AI & Agents

How to Build MCP Servers with Deno

Building MCP servers with Deno provides a secure way to expose tools for AI agents. The Model Context Protocol (MCP) allows streamable tool calls over HTTP or SSE. Deno's permission system handles untrusted agents safely. This tutorial shows how to set up a server, implement core endpoints, add security, integrate Fresh, and deploy.

Fastio Editorial Team 6 min read
Deno MCP server running locally

What is an MCP Server?

An MCP server implements the Model Context Protocol, a streaming protocol for AI agent tools. It handles requests like tool discovery, execution, and state management.

Fastio runs a production MCP server at mcp.fast.io with multiple tools for file storage and collaboration. Building your own lets you expose custom tools securely.

Key features include:

  • Streamable HTTP at /mcp
  • SSE fallback at /sse
  • Session state for auth tokens
  • Dynamic resource listing for files

Deno fits perfectly. It runs TypeScript natively and bundles to a single executable binary. Permissions like --deny-net protect against malicious agents.

Helpful references: Fastio Workspaces, Fastio Collaboration, and Fastio AI.

AI agent connecting to MCP server

Why Deno for MCP Servers?

Deno emphasizes security for untrusted code, ideal for agent tools.

Advantages:

  • Built-in TypeScript support, no config needed
  • Permission flags (--allow-net, --deny-all) for fine-grained control
  • Bundles to single binary with deno compile
  • Fast runtime with V8 isolates
  • Native HTTP server APIs

Compared to Node.js, Deno avoids npm vulnerabilities and package.json hell.

Deno security permissions diagram
Fastio features

Ready for Agentic Workspaces?

Build custom MCP tools or use Fastio's hosted MCP server with 251 tools, 50GB free storage, no credit card. Perfect for Deno developers. Built for building mcp servers deno workflows.

Prerequisites

Install Deno 2.0+:

curl -fsSL https://deno.land/install.sh | sh

Verify:

deno --version

Create project:

mkdir mcp-server-deno
cd mcp-server-deno
deno init

Set Up Fresh Framework

Fresh provides file-based routing and islands for agent UIs.

Add Fresh:

deno add @fresh/core @preact/signals-react fresh

main.ts:

import manifest from "./fresh.gen.ts";

import { start } from "@fresh/server";
import { type Plugin } from "$fresh/server.ts";

const plugins: Plugin[] = [];

await start(manifest, { plugins });

routes/api/mcp.ts for MCP endpoint.

Implement MCP Endpoints

Create /api/mcp POST handler for streamable calls.

Example handler:

import { HandlerContext } from "$fresh/server.ts";

export const handler = {
  async POST(req: Request, ctx: HandlerContext) {
    const sessionId = ctx.state.sessionId || crypto.randomUUID();
    // Parse MCP request
    const body = await req.json();
    const { tool, action, params } = body;

// Route to tool action
    let result;
    if (tool === "storage") {
      result = await handleStorage(action, params, sessionId);
    } // etc

// Stream response
    const stream = new ReadableStream({
      start(controller) {
        controller.enqueue(JSON.stringify({ result }));
        controller.close();
      }
    });

return new Response(stream, {
      headers: { "Content-Type": "application/json-stream" }
    });
  }
};

Add session state with Deno KV for persistence.

Agent Permissions and Security

Deno permissions protect against untrusted agents.

Run with:

deno run --allow-net --allow-env --deny-all main.ts

Explicitly allow only needed perms.

In code, validate agent requests:

if (!isTrustedAgent(req.headers.get("User-Agent"))) {
  return new Response("Unauthorized", { status: 401 });
}

Use Deno's secure defaults: no file access unless allowed.

For production, add rate limiting and auth tokens per agent.

Security audit log for MCP calls

Deploy to Deno Deploy

Bundle and deploy.

deno.json:

{
  "compilerOptions": {
    "lib": ["deno.unstable"]
  },
  "tasks": {
    "deploy": "deno task start"
  },
  "deploy": "./main.ts"
}

Deploy:

deployctl deploy --project=my-mcp

Flags: --allow-net for HTTP, Deno Deploy handles scaling.

Testing Your MCP Server

Test with curl:

curl -X POST http://localhost:8000/api/mcp \\
  -H "Content-Type: application/json" \\
  -d '{"tool":"storage","action":"list"}'

works alongside agents using MCP clients.

Define clear tool contracts and fallback behavior so agents fail safely when dependencies are unavailable. This improves reliability in production workflows.

Frequently Asked Questions

What are Deno MCP permissions?

Deno uses runtime flags like --allow-net, --deny-read to restrict access. For MCP, deny all then allow specific for agent tools. This prevents untrusted agents from accessing files or network.

How does Fresh framework works alongside MCP?

Fresh handles routing to /mcp endpoints. Use islands for agent dashboards. Combine with Preact for reactive UIs serving MCP data.

Can I bundle MCP server to a binary?

Yes, `deno compile --allow-net main.ts` creates a single executable. Distribute easily without Deno install.

What Deno Deploy flags for production?

Use deployctl with --allow-net, --allow-env=DENO_KV. Deno Deploy provides global edge runtime.

How to handle sessions in MCP?

Use Deno KV for persistent sessions. Store auth tokens by sessionId from headers.

Related Resources

Fastio features

Ready for Agentic Workspaces?

Build custom MCP tools or use Fastio's hosted MCP server with 251 tools, 50GB free storage, no credit card. Perfect for Deno developers. Built for building mcp servers deno workflows.