Claude
Skills
Sign in
Back

fastmcp

Included with Lifetime
$97 forever

FastMCP TypeScript framework patterns for MCP servers. Auto-loads when building MCP servers, creating tools/resources/prompts, implementing authentication, configuring transports, or working with FastMCP in TypeScript.

AI Agents

What this skill does


# FastMCP Development Skill

FastMCP is a TypeScript framework for building Model Context Protocol (MCP) servers. This skill provides patterns for tools, resources, prompts, authentication, and transport configuration.

## Installation

```bash
npm install fastmcp
```

## Basic Server Setup

```typescript
import { FastMCP } from "fastmcp";
import { z } from "zod";

const server = new FastMCP({
  name: "My Server",
  version: "1.0.0",
});

server.start({ transportType: "stdio" });
```

## Tools

### Basic Tool with Zod Schema

```typescript
server.addTool({
  name: "add",
  description: "Add two numbers",
  parameters: z.object({
    a: z.number(),
    b: z.number(),
  }),
  execute: async (args) => {
    return String(args.a + args.b);
  },
});
```

### Tool Without Parameters

```typescript
server.addTool({
  name: "sayHello",
  description: "Say hello",
  execute: async () => {
    return "Hello, world!";
  },
});
```

### Tool with Logging

```typescript
server.addTool({
  name: "download",
  parameters: z.object({ url: z.string() }),
  execute: async (args, { log }) => {
    log.info("Downloading file...", { url: args.url });
    // ... process ...
    log.info("Downloaded file");
    return "done";
  },
});
```

### Tool with Progress Reporting

```typescript
server.addTool({
  name: "download",
  execute: async (args, { reportProgress }) => {
    await reportProgress({ progress: 0, total: 100 });
    // ... process ...
    await reportProgress({ progress: 100, total: 100 });
    return "done";
  },
});
```

### Tool with Streaming Output

```typescript
server.addTool({
  name: "generateText",
  parameters: z.object({ prompt: z.string() }),
  annotations: {
    streamingHint: true,
    readOnlyHint: true,
  },
  execute: async (args, { streamContent }) => {
    await streamContent({ type: "text", text: "Starting...\n" });
    const words = "The quick brown fox".split(" ");
    for (const word of words) {
      await streamContent({ type: "text", text: word + " " });
      await new Promise(resolve => setTimeout(resolve, 300));
    }
    return;
  },
});
```

### Tool with Multiple Content Types

```typescript
server.addTool({
  name: "download",
  description: "Download a file",
  parameters: z.object({ url: z.string() }),
  execute: async (args) => {
    return {
      content: [
        { type: "text", text: "First message" },
        { type: "text", text: "Second message" },
      ],
    };
  },
});
```

### Tool with Image Content

```typescript
import { imageContent } from "fastmcp";

server.addTool({
  name: "getImage",
  execute: async (args) => {
    return imageContent({
      url: "https://example.com/image.png",
    });
    // Or: path: "/path/to/image.png"
    // Or: buffer: Buffer.from(...)
  },
});
```

### Tool with Audio Content

```typescript
import { audioContent } from "fastmcp";

server.addTool({
  name: "getAudio",
  execute: async (args) => {
    return audioContent({
      url: "https://example.com/audio.mp3",
    });
  },
});
```

### Tool with Error Handling

```typescript
import { UserError } from "fastmcp";

server.addTool({
  name: "download",
  execute: async (args) => {
    if (args.url.startsWith("https://example.com")) {
      throw new UserError("This URL is not allowed");
    }
    return "done";
  },
});
```

### Tool with Annotations

```typescript
server.addTool({
  name: "fetch-content",
  description: "Fetch content from a URL",
  parameters: z.object({ url: z.string() }),
  annotations: {
    title: "Web Content Fetcher",
    readOnlyHint: true,
    openWorldHint: true,
  },
  execute: async (args) => {
    return await fetchWebpageContent(args.url);
  },
});
```

### Tool with Authorization

```typescript
server.addTool({
  name: "admin-tool",
  description: "An admin-only tool",
  canAccess: (auth) => auth?.role === "admin",
  execute: async () => "Welcome, admin!",
});
```

## Alternative Schema Libraries

### ArkType

```typescript
import { type } from "arktype";

server.addTool({
  name: "fetch-arktype",
  parameters: type({ url: "string" }),
  execute: async (args) => {
    return await fetchWebpageContent(args.url);
  },
});
```

### Valibot

```typescript
import * as v from "valibot";

server.addTool({
  name: "fetch-valibot",
  parameters: v.object({ url: v.string() }),
  execute: async (args) => {
    return await fetchWebpageContent(args.url);
  },
});
```

## Resources

### Basic Resource

```typescript
server.addResource({
  uri: "file:///logs/app.log",
  name: "Application Logs",
  mimeType: "text/plain",
  async load() {
    return {
      text: await readLogFile(),
    };
  },
});
```

### Resource with Binary Content

```typescript
server.addResource({
  uri: "file:///logs/app.log",
  async load() {
    return {
      blob: 'base64-encoded-data'
    };
  },
});
```

### Resource Template

```typescript
server.addResourceTemplate({
  uriTemplate: "file:///logs/{name}.log",
  name: "Application Logs",
  mimeType: "text/plain",
  arguments: [
    {
      name: "name",
      description: "Name of the log",
      required: true,
    },
  ],
  async load({ name }) {
    return {
      text: `Log content for ${name}`,
    };
  },
});
```

### Resource Template with Auto-Completion

```typescript
server.addResourceTemplate({
  uriTemplate: "file:///logs/{name}.log",
  arguments: [
    {
      name: "name",
      description: "Name of the log",
      required: true,
      complete: async (value) => {
        if (value === "Example") {
          return { values: ["Example Log"] };
        }
        return { values: [] };
      },
    },
  ],
  async load({ name }) {
    return {
      text: `Log content for ${name}`,
    };
  },
});
```

### Embedded Resources in Tools

```typescript
server.addTool({
  name: "get_user_data",
  parameters: z.object({ userId: z.string() }),
  execute: async (args) => {
    return {
      content: [
        {
          type: "resource",
          resource: await server.embedded(`user://profile/${args.userId}`),
        },
      ],
    };
  },
});
```

## Prompts

### Basic Prompt

```typescript
server.addPrompt({
  name: "git-commit",
  description: "Generate a Git commit message",
  arguments: [
    {
      name: "changes",
      description: "Git diff or description of changes",
      required: true,
    },
  ],
  load: async (args) => {
    return "Generate a concise commit message:\n\n" + args.changes;
  },
});
```

### Prompt with Auto-Completion

```typescript
server.addPrompt({
  name: "countryPoem",
  description: "Writes a poem about a country",
  load: async ({ name }) => {
    return "Write a poem about " + name + "!";
  },
  arguments: [
    {
      name: "name",
      description: "Name of the country",
      required: true,
      complete: async (value) => {
        if (value === "Germ") {
          return { values: ["Germany"] };
        }
        return { values: [] };
      },
    },
  ],
});
```

### Prompt with Enum Arguments

```typescript
server.addPrompt({
  name: "countryPoem",
  description: "Writes a poem about a country",
  load: async ({ name }) => {
    return "Write a poem about " + name + "!";
  },
  arguments: [
    {
      name: "name",
      description: "Name of the country",
      required: true,
      enum: ["Germany", "France", "Italy"],
    },
  ],
});
```

## Authentication

### Basic API Key Authentication

```typescript
const server = new FastMCP({
  name: "My Server",
  version: "1.0.0",
  authenticate: (request) => {
    const apiKey = request.headers["x-api-key"];

    if (apiKey !== "expected-key") {
      throw new Response(null, {
        status: 401,
        statusText: "Unauthorized",
      });
    }

    return { id: 1 };
  },
});

server.addTool({
  name: "sayHello",
  execute: async (args, { session }) => {
    return "Hello, " + session.id + "!";
  },
});
```

### Role-Based Authentication

```typescript
const server = new FastMCP<{ role: "admin" | "user" }>({
  authenticate: async (request) => {
    const role = 

Related in AI Agents