Skip to main content
Claude Desktop discovers MCP servers through a local config file and communicates with them over stdin/stdout. Anvil’s --stdio flag switches the MCP server from Streamable HTTP to the newline-delimited JSON-RPC transport that Claude Desktop (and other local clients) expect.

Transport modes

Anvil supports two MCP transport modes. Choose the one that fits your client:
The default mode starts an HTTP server that accepts POST requests at /mcp. Use this for remote agents, AI frameworks (Vercel AI SDK, LangChain, etc.), or any client that speaks HTTP.
anvil mcp
# [anvil] mcp (Streamable HTTP) on http://localhost:3100/mcp
# [anvil] 2 tool(s): get_users_by_id, wordCount
Point your agent or framework at http://localhost:3100/mcp (or the host/port you configure with --port and --endpoint).

Configure Claude Desktop

To add your Anvil project as an MCP server in Claude Desktop, edit the claude_desktop_config.json file and add an entry under mcpServers:
{
  "mcpServers": {
    "anvil": {
      "command": "npx",
      "args": ["anvil", "mcp", "--stdio"],
      "cwd": "/path/to/your/project"
    }
  }
}
Replace /path/to/your/project with the absolute path to the directory that contains your server/ folder. Claude Desktop will spawn npx anvil mcp --stdio in that directory whenever it needs to call one of your tools.
Where to find claude_desktop_config.json:
  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
Create the file if it doesn’t exist yet. After saving, restart Claude Desktop for the changes to take effect.

Step-by-step setup

1

Annotate at least one route or add a standalone tool

Make sure you have at least one MCP-exposed route (meta.mcp.expose = true) or a file in server/tools/. Without any tools, the server starts but Claude Desktop has nothing to call.
// server/routes/users/[id]/get.ts
export const meta = { mcp: { expose: true, description: 'Fetch a user by ID' } };
export const paramsSchema = z.object({ id: z.string() });
export default (ctx) => findUser(ctx.params.id);
2

Verify with a local test

Confirm the server starts cleanly before touching the Claude Desktop config:
npx anvil mcp --stdio
You should see a line on stderr listing your tools. If there are any schema errors, fix them before proceeding.
3

Edit claude_desktop_config.json

Open the config file for your OS (see the note above) and add the anvil server entry:
{
  "mcpServers": {
    "anvil": {
      "command": "npx",
      "args": ["anvil", "mcp", "--stdio"],
      "cwd": "/absolute/path/to/your/project"
    }
  }
}
4

Restart Claude Desktop

Quit and reopen Claude Desktop. Open a new conversation — your Anvil tools should now appear in the tool list. Ask Claude to call one of them to confirm the connection.

Using a local binary instead of npx

If you have anvil installed globally or in your project’s .bin/, reference it directly to avoid the npx startup overhead:
{
  "mcpServers": {
    "anvil": {
      "command": "/absolute/path/to/your/project/node_modules/.bin/anvil",
      "args": ["mcp", "--stdio"],
      "cwd": "/absolute/path/to/your/project"
    }
  }
}

Connecting other MCP-compatible clients

The Streamable HTTP mode (anvil mcp without --stdio) works with any client or framework that implements the MCP spec over HTTP:
Client / FrameworkConnect to
Vercel AI SDKhttp://localhost:3100/mcp
LangChain / LangGraphhttp://localhost:3100/mcp
Custom JSON-RPC clientPOST http://localhost:3100/mcp
Any MCP-compatible agenthttp://localhost:3100/mcp
Change the default port or endpoint path with --port and --endpoint:
anvil mcp --port 4000 --endpoint /tools
# [anvil] mcp (Streamable HTTP) on http://localhost:4000/tools
Run anvil lint before connecting Claude Desktop to make sure every exposed route’s schema converts cleanly. Lint catches issues at build time rather than surfacing them as confusing runtime errors inside Claude.