> ## Documentation Index
> Fetch the complete documentation index at: https://anvil.thatdevguy.in/llms.txt
> Use this file to discover all available pages before exploring further.

# anvil mcp: Serve Your Routes as an MCP Tool Server

> Serve MCP-annotated routes and server/tools/ as an MCP tool server over Streamable HTTP or stdio for AI agents and clients like Claude Desktop.

Run `anvil mcp` to serve your MCP-exposed routes and any standalone tool files in `server/tools/` as a Model Context Protocol (MCP) tool server. AI agents, orchestrators, and local clients such as Claude Desktop can then discover and call your tools without any additional glue code.

Anvil supports two transport modes: Streamable HTTP (the default) for networked agents and hosted deployments, and `--stdio` for local clients that communicate over standard input/output.

## Usage

```bash theme={null}
anvil mcp [options]
```

## Flags

<ParamField query="-r, --routes <dir>" type="string" default="server/routes">
  Directory Anvil scans for route files. Only routes that carry `meta.mcp.expose = true` are registered as MCP tools.
</ParamField>

<ParamField query="-t, --tools <dir>" type="string" default="server/tools">
  Directory of standalone tool files to include alongside route-derived tools. If this directory does not exist, it is silently skipped — no error is thrown.
</ParamField>

<ParamField query="--stdio" type="boolean">
  Serve the MCP server over stdio instead of HTTP. Use this mode when connecting a local client such as Claude Desktop directly to the process. In stdio mode, the protocol channel is `stdout`; all Anvil diagnostics are written to `stderr` so they do not corrupt the protocol stream.
</ParamField>

<ParamField query="-p, --port <port>" type="number" default="3100">
  HTTP port for Streamable HTTP mode. Ignored when `--stdio` is set.
</ParamField>

<ParamField query="-e, --endpoint <path>" type="string" default="/mcp">
  URL path at which the Streamable HTTP endpoint is mounted. Ignored when `--stdio` is set.
</ParamField>

## HTTP mode (default)

Start the MCP server on its default port:

```bash theme={null}
anvil mcp
```

```text theme={null}
[anvil] mcp (Streamable HTTP) on http://localhost:3100/mcp
[anvil] 3 tool(s): get_user, create_order, search_products
```

Connect any MCP-compatible HTTP client to `http://localhost:3100/mcp`.

### Custom port and endpoint

```bash theme={null}
anvil mcp --port 4200 --endpoint /tools/mcp
```

```text theme={null}
[anvil] mcp (Streamable HTTP) on http://localhost:4200/tools/mcp
[anvil] 2 tool(s): summarize, classify
```

## stdio mode

Start the MCP server over stdio for use with Claude Desktop or another local client:

```bash theme={null}
anvil mcp --stdio
```

```text theme={null}
[anvil] mcp stdio: 3 tool(s) — get_user, create_order, search_products
```

The process then communicates exclusively over stdin/stdout using the MCP wire protocol. Add it to your Claude Desktop config like this:

```json theme={null}
{
  "mcpServers": {
    "my-anvil-app": {
      "command": "npx",
      "args": ["anvil", "mcp", "--stdio"],
      "cwd": "/path/to/your/project"
    }
  }
}
```

## Exposing a route as an MCP tool

To include a route as an MCP tool, add a `meta` export to the route file with `mcp.expose` set to `true`:

```typescript theme={null}
// server/routes/api/summarize/POST.ts
export const meta = {
  mcp: {
    expose: true,
    description: "Summarize a block of text to a given maximum length.",
  },
};

export const bodySchema = z.object({
  text: z.string(),
  maxWords: z.number().int().optional(),
});

export default async function handler(req) { /* ... */ }
```

<Note>
  If `server/tools/` does not exist, `anvil mcp` silently skips it. You do not need to create the directory or pass `--tools` with a different path unless you have standalone tool files to include.
</Note>

<Warning>
  In stdio mode, **do not write to stdout** from inside your route handlers or tools. Any non-protocol bytes on stdout will corrupt the MCP stream. Use `process.stderr.write(...)` or a logging library configured to write to stderr.
</Warning>

<Tip>
  Run `anvil lint` before `anvil mcp` in CI. Lint catches `schema-lossy` errors — schemas that cannot round-trip to JSON Schema — which would cause tools to be unregistered or malformed at runtime.
</Tip>
