AI & Agents

How to Create an MCP Server with Node.js and TypeScript

The Node.js SDK for MCP enables JavaScript and TypeScript developers to build tools and resources that works alongside Claude and other LLMs. This guide walks you through setting up a project, creating your first tool, and testing your server. This guide covers mcp server nodejs with practical examples.

Fast.io Editorial Team 7 min read
MCP servers connect AI models to your local data and APIs.

What is an MCP Server?: mcp server nodejs

A Model Context Protocol (MCP) server connects Large Language Models (LLMs) like Claude to external systems. Without MCP, integrating AI into your workflow means copying and pasting data into a chat window. An MCP server removes that step, letting the AI query databases, read files, or run code directly within a controlled environment. This solves the "context window" problem. Instead of stuffing everything into a prompt, the AI discovers and pulls in specific information when it needs it. The MCP specification defines three server capabilities:

  • Resources: Passive data sources that the AI can read. Think of them as specialized files or database rows that provide background for a task. * Tools: Executable functions. They let the AI perform actions like sending an email, making an API call, or running a calculation. * Prompts: Pre-defined templates that shape how the AI interacts with the user or the data. The official TypeScript SDK gives Node.js developers full type safety over the JSON-RPC messages exchanged between client and server. If you need to wire up custom AI tools to existing enterprise systems or npm packages, it's a strong starting point.

Helpful references: Fast.io Workspaces, Fast.io Collaboration, and Fast.io AI.

Visualization of data flowing between AI models and external tools

Step 1: Project Setup

You'll need Node.js v18 or higher installed. We'll use TypeScript because the MCP protocol relies on structured data, and TypeScript catches schema mismatches at compile time instead of at runtime. First, create a new directory for your project and initialize it with a package.json file:

mkdir my-mcp-server
cd my-mcp-server
npm init -y

Next, install the dependencies. @modelcontextprotocol/sdk handles the protocol, and zod handles runtime schema validation for your tool inputs:

npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsx

zod matters here because TypeScript types disappear at runtime. LLMs can occasionally send malformed JSON or hallucinated arguments, and zod catches that before your function runs. It verifies that the arguments the AI provides (a and b in our calculator) are actually numbers. If they're not, your server returns a clear error to the model instead of crashing. Create a tsconfig.json in your project root. The MCP SDK requires ESM, so the module settings matter here:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true
  },
  "include": ["src/**/*"]
}

Step 2: Building Your First Tool

Let's create a server that exposes a tool. We'll build a basic calculator the AI can call. Create src/index.ts:

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";

// Initialize the server
const server = new Server(
  {
    name: "example-calculator",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

// Define available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "calculate_sum",
        description: "Add two numbers together",
        inputSchema: {
          type: "object",
          properties: {
            a: { type: "number" },
            b: { type: "number" },
          },
          required: ["a", "b"],
        },
      },
    ],
  };
});

// Handle tool execution
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "calculate_sum") {
    const { a, b } = request.params.arguments as { a: number; b: number };
    return {
      content: [
        {
          type: "text",
          text: String(a + b),
        },
      ],
    };
  }
  throw new Error("Tool not found");
});

// Start the server using stdio transport
const transport = new StdioServerTransport();
await server.connect(transport);

Here's what each piece does:

  • ListToolsRequestSchema: This handler tells the AI what tools are available. The inputSchema is the most important part because it's the documentation the AI reads to figure out how to call the tool. Better descriptions and schemas mean fewer bad calls. * CallToolRequestSchema: This is the execution engine. When the AI decides to call a tool, this handler receives the request, parses the arguments, and runs your logic. * Stdio Transport: We use standard input/output for the connection. This is the simplest setup: no network configuration needed. The client spawns your process and talks to it through command line pipes.
Fast.io features

Need storage for your AI agents?

Fast.io gives you usage-based cloud storage built for mcp server nodejs. Get streaming previews, AI-powered search, and unlimited guest sharing. Start with a free account, no credit card required.

Step 3: Testing with Claude Desktop

To test your server, configure Claude Desktop to run the script. Open your Claude config file (~/Library/Application Support/Claude/claude_desktop_config.json on macOS) and add the server:

{
  "mcpServers": {
    "my-calculator": {
      "command": "npx",
      "args": ["-y", "tsx", "/absolute/path/to/my-mcp-server/src/index.ts"]
    }
  }
}

Restart Claude Desktop. You should now see a 🔌 icon indicating the server is connected. Try asking Claude: "Can you use the calculator tool to add 50 and 100?" It should invoke your code and return "150". Consider how this fits into your broader workflow and what matters most for your team. The right choice depends on your specific requirements: file types, team size, security needs, and how you collaborate with external partners. Testing with a free account is the fast way to know if a tool works for you.

Why Build vs. Buy?

Building your own MCP server makes sense for custom internal logic or proprietary APIs. For standard file operations and cloud storage, though, maintaining your own server is extra work you probably don't need.

Fast.io offers a managed MCP server with 251 pre-built tools for file management, search, and storage. * No setup: No boilerplate or stdio wiring needed. * Persistent Storage: Agents get 50GB of free cloud storage that persists between sessions. * Intelligence Mode: Built-in RAG indexes your files for semantic search automatically. * Works everywhere: Compatible with Claude, OpenClaw, and any MCP-compliant client. Instead of writing a file system MCP server from scratch, you can connect the Fast.io server and focus on the business logic that's unique to your app.

Fast.io MCP server interface showing active tools and logs

Advanced: Serving over HTTP

stdio works well for local desktop apps, but cloud-hosted agents need a different transport. The Node.js SDK also supports Server-Sent Events (SSE) over HTTP. To switch, replace StdioServerTransport with SSEServerTransport and wrap it in an Express or Fastify server. Remote agents can then connect to your tools over the web. The way SSE works: the server pushes messages to the client over a persistent HTTP connection, and the client sends requests back via standard HTTP POST. You get real-time updates without the complexity of full WebSockets, and it's firewall-friendly enough to deploy on serverless platforms. Fast.io's managed MCP server uses this same architecture for streamable connections to your file storage from anywhere.

Frequently Asked Questions

What is the best language for building MCP servers?

TypeScript is a strong choice for MCP servers because its type safety maps directly to the JSON-RPC protocol schemas, catching errors before runtime. Python is another popular option, especially for data science tools.

Can I run an MCP server on a hosting provider?

Yes, you can deploy MCP servers to any platform that supports Node.js or Docker, such as Railway, Render, or AWS. You will need to use the SSE (Server-Sent Events) transport layer instead of stdio for remote connections.

Is Fast.io's MCP server compatible with custom servers?

Yes. MCP is designed to be modular, so you can run Fast.io's server for file storage and RAG alongside your custom Node.js server for business logic. Clients connect to both at the same time.

Related Resources

Fast.io features

Need storage for your AI agents?

Fast.io gives you usage-based cloud storage built for mcp server nodejs. Get streaming previews, AI-powered search, and unlimited guest sharing. Start with a free account, no credit card required.