mctxdocs
Building mcp servers

Tools & Resources

Links to MCP SDK documentation, code examples, debugging tools, and community resources for building MCP servers.

Official MCP Documentation

The Model Context Protocol is maintained as an open specification with comprehensive documentation.

ResourceURLDescription
Official Specificationmodelcontextprotocol.io/specificationComplete protocol reference
Introductionmodelcontextprotocol.ioHigh-level overview and concepts
GitHub Organizationgithub.com/modelcontextprotocolOfficial SDKs and tools

MCP SDK

The official MCP SDK provides TypeScript/JavaScript implementations of the protocol.

Repository: github.com/modelcontextprotocol/typescript-sdk

Installation:

npm install @modelcontextprotocol/sdk

Key packages:

  • @modelcontextprotocol/sdk/server/mcp.js - Server implementation
  • @modelcontextprotocol/sdk/server/streamableHttp.js - HTTP transport
  • @modelcontextprotocol/sdk/types.js - TypeScript types

SDK vs Raw JSON-RPC

For mctx servers, we recommend the raw JSON-RPC approach over the SDK:

Raw JSON-RPC (Recommended):

  • ✅ Simpler - Direct control over requests and responses
  • ✅ Cloudflare Worker native - No adapters needed
  • ✅ Smaller bundle size - No SDK dependencies
  • ✅ Easier debugging - Clear request/response flow

Using the SDK:

  • ❌ More complex - Requires transport layer adaptation
  • ❌ Node.js-oriented - Built for Express/Node.js, not Workers
  • ❌ Larger bundle - Includes unnecessary features for mctx
  • ✅ Type safety - Strong TypeScript types (but you can define these yourself)

Example: Raw JSON-RPC approach (recommended)

interface Env {
  API_KEY?: string;
}

const TOOLS = [
  {
    name: "hello",
    description: "Returns a greeting",
    inputSchema: {
      type: "object",
      properties: {},
      required: [],
    },
  },
];

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    if (request.method !== "POST") {
      return new Response("Method not allowed", { status: 405 });
    }

    const body = await request.json();
    const { method, params, id } = body;

    let result;

    switch (method) {
      case "tools/list":
        result = { tools: TOOLS };
        break;

      case "tools/call":
        if (params.name === "hello") {
          result = {
            content: [{ type: "text", text: "Hello from mctx!" }],
          };
        } else {
          return jsonRpcError(-32601, `Unknown tool: ${params.name}`, id);
        }
        break;

      default:
        return jsonRpcError(-32601, "Method not found", id);
    }

    return new Response(JSON.stringify({ jsonrpc: "2.0", result, id }), {
      headers: {
        "Content-Type": "application/json",
        "MCP-Protocol-Version": "2025-11-25",
      },
    });
  },
};

function jsonRpcError(code: number, message: string, id: unknown) {
  return new Response(
    JSON.stringify({
      jsonrpc: "2.0",
      error: { code, message },
      id: id ?? null,
    }),
    {
      status: 400,
      headers: {
        "Content-Type": "application/json",
        "MCP-Protocol-Version": "2025-11-25",
      },
    },
  );
}

Example Servers

mctx Test Server

The mctx repository includes a minimal hello world MCP server used for platform testing.

Location: github.com/mctx-ai/mctx/tree/main/examples/test-mcp-server

What it demonstrates:

  • Minimal mctx.json configuration
  • Single tool implementation
  • JSON-RPC request handling
  • Cloudflare Worker format

Use this as a starting template for new mctx servers.

Community Examples

Microsoft MCP Servers: github.com/microsoft/mcp

  • Collection of reference implementations
  • Examples: GitHub, Azure DevOps, PostgreSQL, Redis

awesome-mcp-servers: github.com/punkpeye/awesome-mcp-servers

  • Curated list of 200+ MCP servers
  • Real-world examples across many domains
  • Active community with 78k+ GitHub stars

Development Tools

Testing MCP Servers

MCP Inspector: github.com/modelcontextprotocol/inspector

  • Interactive tool for testing MCP servers locally
  • Visualize tool calls, responses, and errors
  • Test before deploying to mctx

Usage:

npx @modelcontextprotocol/inspector

TypeScript Types

Define your own types for type safety without the SDK:

// MCP JSON-RPC types
interface JsonRpcRequest {
  jsonrpc: "2.0";
  method: string;
  params?: unknown;
  id: string | number;
}

interface JsonRpcResponse {
  jsonrpc: "2.0";
  result?: unknown;
  error?: {
    code: number;
    message: string;
    data?: unknown;
  };
  id: string | number | null;
}

// MCP tool definition
interface Tool {
  name: string;
  description: string;
  inputSchema: {
    type: "object";
    properties: Record<string, unknown>;
    required?: string[];
  };
}

// Tool response
interface ToolResponse {
  content: Array<{
    type: "text" | "image" | "resource";
    text?: string;
    data?: string;
    mimeType?: string;
  }>;
  isError?: boolean;
}

Debugging

Real-Time Logs on mctx

mctx provides real-time log streaming in the dashboard:

  1. Go to your server detail page
  2. Click View Logs
  3. Trigger a request from your AI client
  4. Watch console.log output appear instantly

Logging best practices:

// Use structured prefixes
console.log(`[INFO] Tool called: ${toolName}`);
console.log(`[DEBUG] Parameters: ${JSON.stringify(params)}`);
console.log(`[WARN] Rate limit approaching: ${remaining} requests left`);
console.log(`[ERROR] API call failed: ${error.message}`);

Local Testing Before Deploy

Test your server locally before deploying to mctx:

1. Use Cloudflare Workers development server:

npm install -g wrangler
wrangler dev

2. Test with curl:

curl -X POST http://localhost:8787 \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/list",
    "params": {},
    "id": 1
  }'

3. Use MCP Inspector:

npx @modelcontextprotocol/inspector http://localhost:8787

Learning Resources

MCP for Beginners

Microsoft's MCP Curriculum: github.com/microsoft/mcp-for-beginners

  • Structured learning path
  • Code examples in multiple languages (TypeScript, Python, C#, Java)
  • Hands-on exercises

Community Resources

Discord: discord.gg/mcp

  • Official MCP community
  • Get help from other developers
  • Share your servers

Reddit: r/ModelContextProtocol

  • Community discussions
  • Server showcases
  • Q&A

Common Patterns

External API Integration

async function callExternalApi(query: string, env: Env): Promise<string> {
  const response = await fetch("https://api.example.com/search", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${env.API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ query }),
  });

  if (!response.ok) {
    throw new Error(`API error: ${response.status}`);
  }

  return response.json();
}

Input Validation

function validateParams(params: unknown, tool: Tool): boolean {
  if (typeof params !== "object" || params === null) {
    return false;
  }

  const p = params as Record<string, unknown>;

  // Check required fields
  for (const field of tool.inputSchema.required || []) {
    if (!(field in p)) {
      return false;
    }
  }

  return true;
}

Error Handling

try {
  const result = await fetchData(params);
  return {
    content: [{ type: "text", text: JSON.stringify(result) }],
  };
} catch (error) {
  return {
    content: [
      {
        type: "text",
        text: `Error: ${error instanceof Error ? error.message : "Unknown error"}`,
      },
    ],
    isError: true,
  };
}

Platform-Specific Notes

What mctx Provides

When deploying to mctx, the platform handles:

  • Authentication - OAuth validation via JWT
  • Initialization - initialize method response
  • Session management - Session IDs and lifecycle
  • Version routing - Routes requests to the correct version
  • Environment variables - Encrypted secrets injection
  • Real-time logs - Console output streaming

What You Implement

Your server code only needs to handle:

  • Business logic - Tool implementations
  • JSON-RPC methods - tools/list, tools/call, etc.
  • Error handling - Return proper JSON-RPC errors
  • Input validation - Validate tool parameters

Best Practices

  1. Keep it focused - One server, one clear purpose
  2. Validate inputs - Check parameters before using
  3. Handle errors gracefully - Return meaningful error messages
  4. Log important events - Helps with debugging
  5. Use environment variables - Never hardcode secrets
  6. Follow semver - Version bumps communicate breaking changes
  7. Test before deploying - Use local testing and MCP Inspector
  8. Document your tools - Clear descriptions help AI models use them correctly

Next Steps


See something wrong? Report it or suggest an improvement — your feedback helps make these docs better.