# OpenClaw

> Point OpenClaw at Graft with an mcp.servers entry and a token in its .env, and answer approvals on the small page each link opens, since OpenClaw shows no buttons.

Source: https://docs.getgraft.ai/graft/harnesses/openclaw

OpenClaw connects to Graft over streamable HTTP with a static bearer header, reads Graft's tool annotations, and picks up tool-list changes at the start of its next turn. It has no MCP elicitation, so every approval reaches you as a link into the console.

## Configuration

OpenClaw's outbound MCP servers live under `mcp.servers` in the Gateway's config, `~/.openclaw/openclaw.json` by default, with the transport named outright. Put the agent's token in the Gateway host's `~/.openclaw/.env` so the config file holds no secret:

```dotenv
# ~/.openclaw/.env
GRAFT_TOKEN=grft_…
```

Then add Graft under `mcp.servers`, keeping the environment reference literal:

```json
{
  "mcp": {
    "servers": {
      "graft": {
        "url": "https://app.getgraft.ai/mcp",
        "transport": "streamable-http",
        "headers": { "Authorization": "Bearer ${GRAFT_TOKEN}" }
      }
    }
  }
}
```

Or from the CLI: `openclaw mcp add graft --url https://app.getgraft.ai/mcp --transport streamable-http`, then set the header in the file. For self-hosted Graft the URL is your deployment's origin plus `/mcp`. Restart the Gateway that owns your conversations so it loads the token (a token exported in an unrelated terminal never reaches a running Gateway); `openclaw mcp reload` refreshes a running runtime after a config-only change, and on versions that have it `openclaw mcp doctor graft --probe` checks the connection. Graft's tools are available once they appear in a new agent turn — saving the config alone is not proof.

> **Note**
>
> OpenClaw's own schema, not the generic `mcpServers` block other clients take: `mcp.servers`, and `transport` said outright. The console's agent page shows this block under **OpenClaw**.

## Approvals

OpenClaw does not advertise elicitation, so Graft never asks in place. When a call needs your answer, the call returns `awaiting_approval` with a URL, the agent relays it, and you answer on the small page it opens — the one ask under Graft's mark, which closes itself once you have answered; the same action stays under **Pending actions** in the console as the record. The call waits a short while for you first; if you answer within it, the call proceeds without the agent having to try again. Otherwise the agent calls again once you say it is done, and the answer is there.

The same holds for a new connection and a re-entered credential: a link, the console, then the agent calls again. See [Answering in the console](https://docs.getgraft.ai/graft/approvals/answering-in-the-console.md).

## Tool names and the 64-character limit

OpenClaw exposes a server's tools to its model as `<server>__<tool>`, so Graft's `httpbin__get-uuid` becomes `graft__httpbin__get-uuid`. OpenClaw truncates that combined name at 64 characters, while Graft allows 128 for its own. A vendor slug and a tool name that together run long will be cut in OpenClaw's list, and a note from a meta-tool that names the tool will name the untruncated form. Keep vendor slugs and tool names short, and if a name has been cut, `run_tool { vendor, name, input }` still runs it by its real halves.

## Tool-list changes

OpenClaw registers Graft's `tools/list_changed` notification and re-lists at the start of the next turn rather than at once. A tool published mid-turn is therefore called with `run_tool` in that turn and appears first-class from the next one.

## Try it

```text
Get me a fresh UUID from httpbin.org.
```

```text
Create a Linear issue titled "Follow up with Acme" in the Sales team.
```

```text
You said a link was waiting for me. Where do I answer it?
```
