Quickstart
In 5 minutes, you will have a working MCP server running locally.
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-serverThis creates a my-server/ directory with:
index.js— a working server with onegreettoolpackage.json— build, dev, and deployment config pre-wired.gitignoreandREADME.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 devYou 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:3000In 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.