mctxdocs
Build Your MCP Server

Quickstart

In 5 minutes, you will have a working MCP server running locally.

Need help? Connect help.mctx.ai for instant answers.

In 5 minutes, you will have a working MCP server running locally.

Prerequisites: Node >= 22, npm. Nothing else.


Step 1 — Scaffold your project

Run this in your terminal:

npm create mctx-app my-server
cd my-server

This creates a my-server/ directory with:

  • index.js — a working server with one greet tool
  • package.json — build, dev, and deployment config pre-wired
  • .gitignore and README.md

The generated index.js looks like this:

import { createServer, T } from "@mctx-ai/mcp";

const app = createServer({
  instructions:
    "This server provides a simple greeting tool. Use the greet tool to say hello to someone by name.",
});

function greet({ name }) {
  return `Hello, ${name}! Welcome to mctx.`;
}
greet.description = "Greet someone by name";
greet.input = {
  name: T.string({ required: true, description: "Name to greet" }),
};
app.tool("greet", greet);

export default app;

That is your complete MCP server. createServer() handles protocol negotiation, input validation, error handling, and security. You write only business logic.


Step 2 — Run the dev server

npm install
npm run dev

You will see output like:

Listening on http://localhost:3000

Claude Desktop config:
  "mcpServers": {
    "my-server": {
      "command": "npx",
      "args": ["mctx-dev", "/path/to/my-server/index.js"]
    }
  }

The dev server hot-reloads on every save — edit index.js, see the change immediately without restarting.


Step 3 — Call your first tool

With the dev server running, open a second terminal and call the greet tool using the MCP Inspector:

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

In the Inspector UI: connect to http://localhost:3000, open the Tools tab, select greet, set name to any value, and click Run Tool. You will see the response: Hello, [name]! Welcome to mctx.

Or call it with curl directly:

curl -s -X POST http://localhost:3000 \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "greet",
      "arguments": { "name": "world" }
    }
  }' | jq '.result.content[0].text'

Expected output: "Hello, world! Welcome to mctx."


Step 4 — Write your own tool

Replace the greet function in index.js with a tool that fetches data from a URL and returns the page title:

import { createServer, T } from "@mctx-ai/mcp";

const app = createServer({
  instructions: "Use the fetch-title tool to retrieve the HTML title of any URL.",
});

async function fetchTitle({ url }) {
  const res = await fetch(url);
  const html = await res.text();
  const match = html.match(/<title[^>]*>([^<]*)<\/title>/i);
  return match ? match[1].trim() : "No title found";
}
fetchTitle.description = "Fetches the HTML title of a URL";
fetchTitle.input = {
  url: T.string({ required: true, description: "URL to fetch the title from" }),
};
app.tool("fetch-title", fetchTitle);

export default app;

Save the file. The dev server reloads automatically. Call it:

curl -s -X POST http://localhost:3000 \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "fetch-title",
      "arguments": { "url": "https://example.com" }
    }
  }' | jq '.result.content[0].text'

Expected output: "Example Domain"

You now have a running MCP server that performs real work.


Next steps

  • Build — full API reference: tools, resources, prompts, T type system, progress tracking, and sampling
  • User identity — access the authenticated caller's ID via ctx.userId
  • Deploy to mctx — connect your GitHub repo and put this server on your-server.mctx.ai

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