# Build an MCP server with Deno

An MCP server exposes tools, resources, and prompts to AI clients through a protocol. Deno is a natural fit for a local stdio server: single-file TypeScript, explicit permissions, and no separate compile step.

```bash
deno add npm:@modelcontextprotocol/sdk npm:zod
```

```ts title="mcp_server.ts"
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({ name: "project-info", version: "1.0.0" });

server.registerTool(
  "read_project_note",
  {
    description: "Read one approved note by its short name",
    inputSchema: { name: z.string().regex(/^[a-z0-9-]+$/) },
  },
  async ({ name }) => ({
    content: [{
      type: "text",
      text: await Deno.readTextFile(`./notes/${name}.md`),
    }],
  }),
);

await server.connect(new StdioServerTransport());
```

Grant the client read access only to the notes directory:

```json
{
  "mcpServers": {
    "project-info": {
      "command": "deno",
      "args": ["run", "--allow-read=./notes", "mcp_server.ts"]
    }
  }
}
```

<Callout type="warn" title="stdout belongs to the stdio protocol">
Do not print debug logs to stdout; that corrupts JSON-RPC. Log to stderr and keep secrets out of tool arguments and logs.
</Callout>

Prefer Streamable HTTP for remote servers. The old HTTP+SSE transport exists only for compatibility. A public deployment also needs authentication, Origin and DNS-rebinding defenses, rate limits, and authorization on every tool call.

Official references: [Deno MCP server example](https://docs.deno.com/examples/mcp_server/), [MCP TypeScript SDK server](https://ts.sdk.modelcontextprotocol.io/server), and [Model Context Protocol](https://modelcontextprotocol.io/docs/).
