# LangChain (/docs/langchain)

import { Callout } from "fumadocs-ui/components/callout";

`langchain-bowmark` gives a LangChain agent the same two calls every Bowmark caller makes:
read the function library for a task, then run a short script against it on the live sites.
Source: [bowmark-ai/langchain-bowmark](https://github.com/bowmark-ai/langchain-bowmark).

## Install

```bash
pip install langchain-bowmark
export BOWMARK_API_KEY="bmk_..."
```

Make the key at [dashboard/keys](https://bowmark.ai/dashboard/keys). The first $10 a month
is free with no card ([Pricing](/docs/pricing)).

## The tools

| Tool                  | What it does                                                                                                                                         |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `bowmark_get_library` | Returns the typed functions for a task or a site, with their types and examples. Read-only, free, touches no site. Same as `GET /v1/library`.        |
| `bowmark_run`         | Runs an async JavaScript script against those functions on the live sites and returns `{ ok, status, result, logs, error }`. Same as `POST /v1/run`. |

`BowmarkToolkit().get_tools()` returns both, sharing one key. Both support `invoke` and
`ainvoke`.

## With an agent

```python
from langchain.agents import create_agent
from langchain_bowmark import BowmarkToolkit

agent = create_agent(
    "openai:gpt-5.6-luna",
    tools=BowmarkToolkit().get_tools(),
    system_prompt=(
        "You can act on live websites through Bowmark. Call bowmark_get_library with what "
        "the user wants to do, write a short script against the functions it returns, and "
        "execute it with bowmark_run. Answer from the run's result."
    ),
)

result = agent.invoke(
    {"messages": [{"role": "user", "content": "What is the top story on Hacker News right now?"}]}
)
print(result["messages"][-1].content)
```

The agent calls `bowmark_get_library` first, writes a script against what comes back, and
answers from `bowmark_run`'s `result`. What a script may contain is
[Scripting](/docs/scripting).

<Callout type="info" title="Already speaking MCP?">
  An agent that uses `langchain-mcp-adapters` can point at `https://api.bowmark.ai/mcp`
  instead and get the same tools under their MCP names, `get_library` and `run`. See
  [Installation](/docs/installation).
</Callout>

## Without an agent

```python
from langchain_bowmark import BowmarkGetLibrary, BowmarkRun

print(BowmarkGetLibrary().invoke({"query": "read a web page"}))
print(BowmarkRun().invoke({"script": 'return (await bowmark.read.page("https://example.com")).title;'}))
```

A failed run is not an exception. `bowmark_run` hands the envelope back with `ok: false` and
an `error` that says what to change, so the model can fix its script and try again.
