branch:
README.md
2053 bytesRaw
# Stateful MCP Server

A stateful MCP server using `McpAgent` backed by a Durable Object. State persists across requests — the built-in UI lets you call tools and read resources to see it in action.

## What it demonstrates

- **`McpAgent`** — the Agents SDK class for building MCP servers with persistent state
- **Tools** — registering an `add` tool that modifies the counter
- **Resources** — exposing the counter value as an MCP resource
- **State management** — `setState` and `onStateChanged` for durable state
- **Streamable HTTP transport** — the default transport for `McpAgent`

## Running

```sh
npm install
npm run dev
```

Open the browser to see the built-in tool tester. You can also connect with the [MCP Inspector](https://github.com/modelcontextprotocol/inspector) — set the transport to **Streamable HTTP** and URL to `http://localhost:5173/mcp`.

## How it works

The `McpAgent` class extends `Agent` with MCP protocol support. Define your tools and resources in the `init()` method:

```typescript
export class MyMCP extends McpAgent<Env, State, {}> {
  server = new McpServer({ name: "Demo", version: "1.0.0" });
  initialState: State = { counter: 1 };

  async init() {
    this.server.resource("counter", "mcp://resource/counter", (uri) => ({
      contents: [{ text: String(this.state.counter), uri: uri.href }]
    }));

    this.server.registerTool(
      "add",
      { description: "Add to the counter", inputSchema: { a: z.number() } },
      async ({ a }) => {
        this.setState({ ...this.state, counter: this.state.counter + a });
        return {
          content: [{ type: "text", text: `Total: ${this.state.counter}` }]
        };
      }
    );
  }
}

export default MyMCP.serve("/mcp", { binding: "MyMCP" });
```

## Related examples

- [`mcp-worker`](../mcp-worker/) — simplest stateless MCP server using `createMcpHandler`
- [`mcp-worker-authenticated`](../mcp-worker-authenticated/) — adding OAuth to an MCP server
- [`mcp-client`](../mcp-client/) — connecting to MCP servers as a client