Connecting agents

Point Claude Code, Cursor, or any MCP client at your project.

Agents & MCP4 min read

This page gets an agent connected to your Graft project and explains what it is allowed to do once connected. There are two ways to connect, and both reach the same tools:

  • On your machine (stdio). The agent starts graft mcp as a local process. This is the usual setup for Claude Code and Cursor. Start here.
  • Over HTTP. The agent connects to your deployed app at POST /api/mcp, for example a hosted agent working on your live site.

Connect an agent on your machine

  1. Register Graft with your agent

    Most clients read an mcpServers map. Add Graft to it:

    .mcp.json (Claude Code) or .cursor/mcp.json (Cursor)
    {
      "mcpServers": {
        "graft": {
          "command": "npx",
          "args": ["graft", "mcp"]
        }
      }
    }

    Put the file in your project's root folder. Graft looks for graft.config.ts and .env starting from the folder it runs in, so the client must start it in your project.

    The project needs the CLI installed (npm i -D @usegraft/cli; Getting started does this). Without it, npx graft fetches an unrelated npm package named graft and the agent fails to connect.

  2. Check that it works

    Ask the agent to call list_collections. It needs no arguments and no permissions. On the static engine it needs no database either, so if it fails, the problem is the connection. On Postgres, graft mcp needs DATABASE_URL before it starts, so a failure can also be a missing variable or a database that is down.

    From there, describe_schema tells the agent everything it needs to write content, and explain_error turns any failure into a next step.

To work on a preview branch, add --branch to the arguments: ["graft", "mcp", "--branch", "preview"].

If you wrap graft mcp in a script, never print anything from the script. The client reads standard output as the protocol, and stray text breaks it.

What a local agent may do

The agent is a process you started on your own machine, so Graft trusts it to write content: it can call write_content, delete_content, and put_asset with no permission setup. Each still needs its backend: delete_content files an approval, which needs the Postgres engine, and put_asset needs asset storage (the S3_* variables in Assets).

It cannot approve its own destructive actions. A delete waits for you to run graft approve in another terminal, unless you start the server with --elicit-approvals:

graft mcp --elicit-approvals

Then the agent's client asks you to confirm right there, and approving finishes the call. See Audit & approvals.

To let the agent run functions that require scopes, add them to GRAFT_DEV_SCOPES in .env. If GRAFT_DEV_TOKEN is set, the server uses it as the agent's identity for those calls, and the token itself never appears in the agent's conversation.

Connect an agent over HTTP

A deployed app serves MCP at POST /api/mcp. graft serve mounts it for you:

graft serve --port 3903

To mount it inside your own app, use createGraftMcpHandler. Your framework guide shows the route.

The endpoint is stateless: each request is handled on its own, so it runs on serverless platforms too. It only answers POST. A GET returns 405, which MCP clients understand as "this server does not push messages".

Give the agent an identity

Over HTTP, the agent sends a token when it connects, just like a user of your app. Graft checks it the same way, then uses it for every function the agent runs. Auth covers setting up the providers Graft trusts.

An agent that holds a user's token can act as that user for a single call by passing it as the authorization argument to run_function.

Agents that run shell commands

An agent that works in a terminal can use the graft CLI instead of an MCP connection. graft content, graft schema and graft fn run the same tools, --json prints exactly what each tool returns, and --remote sends them to a hosted site with a token saved by graft login. See Script the CLI.

Anonymous agents

Whether an agent without a token is allowed depends on where the server listens:

The server listens onAgents without a token are
Your machine only (loopback)Allowed, so local development needs no setup
Anything elseRefused, unless you set GRAFT_MCP_ALLOW_ANONYMOUS=1

Only set that variable if your own proxy checks identity in front of Graft. The server warns at startup while it is set.

Permissions an agent needs

ToThe agent needs
Read content, the schema, functions, and the registryNothing beyond reaching the endpoint
Write or delete content, or upload filesThe content:write scope
Approve or deny actionsThe approvals:decide scope, on an authenticated connection
Run a functionWhatever that function's access rule requires

Give each token the fewest scopes that work. Writing content is a separate scope from reading, so you can hand every user of your app a read token without letting them edit content.

A separate, public endpoint for your docs

A project can also publish its documentation to agents at /mcp, with no token. It is a different server with no access to content writes, functions, or approvals. See Public docs MCP.

Next steps