Logo
Agentailor
Published on

Getting Started with FastMCP in TypeScript

DocuMentor AI logo

Short on time?

Get the key takeaways in under 10 seconds with DocuMentor AI, my Chrome extension. No account required.

Try it here →
Authors
  • avatar
    Name
    Ali Ibrahim
    Twitter
Getting Started with FastMCP

Introduction

If you've been following the MCP ecosystem, you've probably heard of FastMCP for Python. Created by the team at Prefect, it quickly became the go-to framework for building MCP servers — offering a clean, decorator-based API that makes server development feel almost effortless.

Python developers have had it good. But what about TypeScript?

The official MCP SDK is powerful, but it requires more boilerplate. You need to understand transports, wire up Express, manage sessions, and structure your code around callbacks. It's not hard, but it's not as fast as it could be.

Enter FastMCP for TypeScript.

Inspired by Python's FastMCP (though maintained by a different author — punkpeye), this framework brings the same developer experience to Node.js. Simple tool definitions. Built-in transport handling. TypeScript-first with standard schema validation (zod, ArkType, or Valibot). It's designed to get you from zero to a working MCP server in minutes.

In this guide, you'll build a Calculator MCP Server using FastMCP and the create-mcp-server CLI.

What you'll learn:

  • What FastMCP offers over the official SDK
  • How to scaffold a FastMCP project with create-mcp-server
  • How to define tools, resources, and prompts
  • How to test your server with MCP Inspector

Prerequisites:

  • Node.js 20 or later
  • Basic TypeScript familiarity

What is FastMCP?

FastMCP is a TypeScript framework that simplifies MCP server development. Instead of manually configuring transports and wiring up handlers, you work with a high-level API that handles the complexity for you.

Key features:

FeatureDescription
Simplified definitionsAdd tools, resources, and prompts with minimal code
Built-in transportsSupports stdio, HTTP streaming, and stateless HTTP out of the box
Session managementAutomatic session handling for stateful servers
TypeScript-firstFull type safety with standard schema validation
Progress & streamingBuilt-in support for progress notifications and streaming output

The framework is maintained by punkpeye and available at github.com/punkpeye/fastmcp.

Note: FastMCP for TypeScript is a separate project from Python's FastMCP (maintained by Prefect). They share the same philosophy but are independently developed.

FastMCP vs Official SDK

When should you use FastMCP versus the official MCP SDK? Here's a quick comparison:

AspectFastMCPOfficial SDK
Best forRapid development, new projectsMaximum control, custom architectures
BoilerplateMinimalMore setup required
Transport setupBuilt-in, automaticManual configuration
Learning curveGentleSteeper
FlexibilitySensible defaultsFull customization

Code Comparison

Here's the same tool implemented in both frameworks:

Official SDK:

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { z } from 'zod'

const server = new McpServer(
  { name: 'Calculator', version: '1.0.0' },
  { capabilities: { logging: {} } }
)

server.registerTool(
  'add',
  {
    description: 'Add two numbers',
    inputSchema: {
      a: z.number().describe('First number'),
      b: z.number().describe('Second number'),
    },
  },
  async ({ a, b }) => ({
    content: [{ type: 'text', text: String(a + b) }],
  })
)

// Then wire up Express, transports, sessions...

FastMCP:

import { FastMCP } from 'fastmcp'
import { z } from 'zod'

const server = new FastMCP({
  name: 'Calculator',
  version: '1.0.0',
})

server.addTool({
  name: 'add',
  description: 'Add two numbers',
  parameters: z.object({
    a: z.number().describe('First number'),
    b: z.number().describe('Second number'),
  }),
  execute: async ({ a, b }) => String(a + b),
})

server.start({ transportType: 'httpStream', httpStream: { port: 3000 } })

The FastMCP version is more concise and handles transport configuration in a single line.

Scaffolding with create-mcp-server

The fastest way to get started is with the create-mcp-server CLI. Version ^0.3.x adds FastMCP as a framework option.

Run the CLI:

npx @agentailor/create-mcp-server

When prompted, enter:

  1. Project name: calculator-mcp-server
  2. Package manager: npm (or your preference)
  3. Framework: FastMCP
  4. Template type: Stateful
  5. Enable OAuth authentication?: No
  6. Initialize git repository?: Your choice

The CLI generates this structure:

calculator-mcp-server/
├── src/
│   └── index.ts      # FastMCP server with example tools
│   └── server.ts     # MCP server (tools, prompts, resources)
├── package.json
├── Dockerfile        # Production-ready Docker build
├── tsconfig.json
├── .env.example
├── .gitignore
└── README.md

Navigate to the project and install dependencies:

cd calculator-mcp-server
npm install

Building a Calculator Tool

Let's replace the scaffolded example with a calculator that can add, subtract, multiply, and divide.

Add or Replace the tool definition placeholders in src/server.ts with:

// Addition
server.addTool({
  name: 'add',
  description: 'Add two numbers together',
  parameters: z.object({
    a: z.number().describe('First number'),
    b: z.number().describe('Second number'),
  }),
  execute: async ({ a, b }) => {
    const result = a + b
    return `${a} + ${b} = ${result}`
  },
})

// Subtraction
server.addTool({
  name: 'subtract',
  description: 'Subtract the second number from the first',
  parameters: z.object({
    a: z.number().describe('Number to subtract from'),
    b: z.number().describe('Number to subtract'),
  }),
  execute: async ({ a, b }) => {
    const result = a - b
    return `${a} - ${b} = ${result}`
  },
})

// Multiplication
server.addTool({
  name: 'multiply',
  description: 'Multiply two numbers together',
  parameters: z.object({
    a: z.number().describe('First number'),
    b: z.number().describe('Second number'),
  }),
  execute: async ({ a, b }) => {
    const result = a * b
    return `${a} × ${b} = ${result}`
  },
})

// Division
server.addTool({
  name: 'divide',
  description: 'Divide the first number by the second',
  parameters: z.object({
    a: z.number().describe('Dividend (number to be divided)'),
    b: z.number().describe('Divisor (number to divide by)'),
  }),
  execute: async ({ a, b }) => {
    if (b === 0) {
      return 'Error: Cannot divide by zero'
    }
    const result = a / b
    return `${a} ÷ ${b} = ${result}`
  },
})

Code Breakdown

Server initialization: We create a FastMCP instance with a name and version. These are used for MCP capability negotiation.

Tool definitions: Each tool uses server.addTool() with:

  • name: Unique identifier for the tool
  • description: Helps AI understand when to use the tool
  • parameters: Zod schema defining the expected inputs
  • execute: Async function that returns a string result
// in src/server.ts, create the FastMCP server
const server = new FastMCP({
  name: 'calculator-mcp-server',
  version: '1.0.0',
})

// in src/index.ts, start
const PORT = Number(process.env.PORT) || 3000

server.start({
  transportType: 'httpStream',
  httpStream: {
    port: PORT,
    stateless: true,
  },
})

Transport configuration: The server.start() method handles all transport setup. We're using httpStream for Streamable HTTP, but you could also use stdio for local development.

Adding Resources and Prompts

FastMCP also supports resources and prompts. Here's a quick example of each:

Adding a Resource

Resources expose data that AI can read. Let's add a calculation history:

// In-memory calculation history
const history: string[] = []

// Modify your tools to track history
server.addTool({
  name: 'add',
  description: 'Add two numbers together',
  parameters: z.object({
    a: z.number().describe('First number'),
    b: z.number().describe('Second number'),
  }),
  execute: async ({ a, b }) => {
    const result = a + b
    const entry = `${a} + ${b} = ${result}`
    history.push(entry)
    return entry
  },
})

// Add a resource to expose history
server.addResource({
  uri: 'calculator://history',
  name: 'Calculation History',
  description: 'Recent calculations performed by the calculator',
  mimeType: 'text/plain',
  async load() {
    if (history.length === 0) {
      return { text: 'No calculations yet.' }
    }
    return { text: history.join('\n') }
  },
})

Adding a Prompt

Prompts are templates that help AI use your tools effectively:

server.addPrompt({
  name: 'calculate',
  description: 'Perform a calculation',
  arguments: [
    {
      name: 'expression',
      description: 'The mathematical expression to evaluate (e.g., "5 + 3")',
      required: true,
    },
  ],
  load: async ({ expression }) => {
    return `Please evaluate this expression using the calculator tools: ${expression}`
  },
})

Testing with MCP Inspector

Start your server:

npm run dev

You should see:

Calculator MCP Server running on http://localhost:3000

In a new terminal, run the inspector:

npm run inspect

Once the inspector opens:

  1. Change the transport from STDIO to Streamable HTTP
  2. Enter http://localhost:3000/mcp as the URL
  3. Click Connect

Testing Tools

  1. Go to ToolsList Tools
  2. You'll see all four calculator tools: add, subtract, multiply, divide
  3. Click on add
  4. Enter values for a and b
  5. Click Run Tool

The result will display the calculation:

5 + 3 = 8

Try testing the division tool with b = 0 to see the error handling.

Connecting to VS Code or Cursor

To use your server with an AI assistant:

  1. Server URL: http://localhost:3000/mcp
  2. VS Code setup: See the official VS Code MCP documentation
  3. Cursor setup: See the official Cursor MCP documentation

What's Next?

You've built a working MCP server with FastMCP. Here are some ways to extend it:

Add authentication: Secure your server with OAuth using our OAuth for MCP Servers guide.

Publish to the registry: Share your server with the community using our publishing guide.

Build an MCP client: Connect your own AI agent to MCP servers with our MCP client guide.

Conclusion

FastMCP brings the ergonomic developer experience of Python's FastMCP to the TypeScript ecosystem. With minimal boilerplate and sensible defaults, you can go from idea to working MCP server in minutes.

The create-mcp-server CLI makes it even easier — scaffolding a complete project with a single command.

Whether you're building internal tools, prototyping new capabilities, or creating production services, FastMCP gives you a fast path to get there.

Enjoying content like this? Sign up for Agent Briefings, where I share insights and news on building and scaling MCP Servers and AI agents.

Resources

Agent Briefings

Level up your agent-building skills with weekly deep dives on MCP, prompting, tools, and production patterns.