Skip to main content
Model Context Protocol (MCP) is an open standard that enables AI applications to connect with external tools, data sources, and services. Mastra provides full MCP support for both client and server implementations.

What is MCP?

MCP standardizes how AI applications communicate with:
  • Tools - Functions that agents can call
  • Resources - Data and content that can be read
  • Prompts - Reusable prompt templates
  • Sampling - AI model interaction patterns
With MCP, you can:
  • Share tools across different AI applications
  • Connect agents to external services
  • Use MCP servers in IDEs like Cursor, Windsurf, and Claude Desktop
  • Build modular AI systems with pluggable capabilities

MCP Architecture

MCP Server

Create an MCP server to expose your tools to other applications:
import { MCPServer } from '@mastra/mcp';
import { createTool } from '@mastra/core/tools';
import { z } from 'zod';

const weatherTool = createTool({
  id: 'getWeather',
  description: 'Get current weather for a location',
  inputSchema: z.object({
    location: z.string(),
  }),
  execute: async (input) => {
    return {
      temperature: 72,
      conditions: 'Sunny',
      location: input.location,
    };
  },
});

const server = new MCPServer({
  name: 'Weather Server',
  version: '1.0.0',
  tools: {
    weatherTool,
  },
});

// Start with stdio transport (for subprocess communication)
await server.startStdio();

MCP Server with HTTP/SSE

Expose your MCP server over HTTP for web applications:
import http from 'node:http';
import { MCPServer } from '@mastra/mcp';

const server = new MCPServer({
  name: 'My MCP Server',
  version: '1.0.0',
  tools: { /* ... */ },
});

const httpServer = http.createServer(async (req, res) => {
  await server.startSSE({
    url: new URL(req.url || '', `http://localhost:3000`),
    ssePath: '/sse',
    messagePath: '/message',
    req,
    res,
  });
});

httpServer.listen(3000, () => {
  console.log('MCP server running on http://localhost:3000/sse');
});

MCP Server with Resources

Expose data and content via MCP resources:
const server = new MCPServer({
  name: 'Data Server',
  version: '1.0.0',
  tools: { /* ... */ },
  resources: {
    listResources: async () => {
      return [
        {
          uri: 'data://users',
          name: 'User Database',
          description: 'List of all users',
          mimeType: 'application/json',
        },
        {
          uri: 'data://products',
          name: 'Product Catalog',
          description: 'Product information',
          mimeType: 'application/json',
        },
      ];
    },
    getResourceContent: async ({ uri }) => {
      if (uri === 'data://users') {
        return {
          text: JSON.stringify(await database.getUsers()),
        };
      }
      if (uri === 'data://products') {
        return {
          text: JSON.stringify(await database.getProducts()),
        };
      }
      throw new Error(`Resource not found: ${uri}`);
    },
  },
});

MCP Server with Prompts

Share reusable prompt templates:
const server = new MCPServer({
  name: 'Prompt Server',
  version: '1.0.0',
  tools: { /* ... */ },
  prompts: {
    listPrompts: async () => {
      return [
        {
          name: 'code-review',
          description: 'Review code for best practices',
          arguments: [
            { name: 'code', description: 'Code to review', required: true },
            { name: 'language', description: 'Programming language', required: true },
          ],
        },
      ];
    },
    getPromptMessages: async ({ name, args }) => {
      if (name === 'code-review') {
        return [
          {
            role: 'user',
            content: {
              type: 'text',
              text: `Review this ${args.language} code:\n\n${args.code}`,
            },
          },
        ];
      }
      throw new Error(`Prompt not found: ${name}`);
    },
  },
});

MCP Client

Connect to MCP servers from your agents:
import { MCPClient } from '@mastra/mcp';
import { Agent } from '@mastra/core/agent';

// Connect to MCP server
const client = new MCPClient({
  name: 'my-client',
  version: '1.0.0',
  server: {
    command: 'node',
    args: ['./mcp-server.js'],
  },
});

await client.connect();

// Get tools from server
const tools = await client.tools();

// Use tools with agent
const agent = new Agent({
  id: 'mcp-agent',
  instructions: 'Use MCP tools to help users',
  model: 'openai/gpt-4',
  tools,
});

const response = await agent.generate('What is the weather?');

MCP Client with HTTP

Connect to HTTP-based MCP servers:
const client = new MCPClient({
  name: 'http-client',
  version: '1.0.0',
  server: {
    url: new URL('http://localhost:3000/sse'),
  },
});

await client.connect();
const tools = await client.tools();

Using Multiple MCP Servers

Connect to multiple MCP servers simultaneously:
import { Mastra } from '@mastra/core';

const mastra = new Mastra({
  mcp: {
    servers: {
      weather: {
        url: new URL('http://weather-service.com/mcp'),
      },
      filesystem: {
        command: 'npx',
        args: ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'],
      },
      database: {
        url: new URL('http://db-service.com/mcp'),
      },
    },
  },
});

const agent = new Agent({
  id: 'multi-mcp-agent',
  instructions: 'Use all available MCP tools',
  model: 'openai/gpt-4',
});

// Agent automatically gets tools from all MCP servers
const response = await agent.generate(
  'Check the weather and save it to a file'
);

MCP Transport Types

MCP supports multiple transport mechanisms:

Standard I/O (stdio)

For subprocess communication:
server: {
  command: 'node',
  args: ['./server.js'],
}

HTTP + Server-Sent Events (SSE)

For web applications:
server: {
  url: new URL('http://localhost:3000/sse'),
}

Streamable HTTP

For modern HTTP applications with better session management:
await server.startHTTP({
  url: new URL(req.url || '', 'http://localhost:3000'),
  httpPath: '/mcp',
  req,
  res,
});

MCP Tool Annotations

Add metadata to tools for better UI presentation:
const tool = createTool({
  id: 'read-file',
  description: 'Read a file from disk',
  mcp: {
    annotations: {
      title: 'Read File',
      readOnlyHint: true,        // Tool doesn't modify environment
      destructiveHint: false,     // Tool is non-destructive
      idempotentHint: true,       // Safe to call multiple times
      openWorldHint: false,       // Closed domain (no external APIs)
    },
  },
  execute: async (input) => {
    return await fs.readFile(input.path, 'utf-8');
  },
});

Benefits of MCP

Write tools once and use them across different AI applications, IDEs, and agents
Break complex systems into smaller, focused MCP servers that can be composed
Control tool access with authentication and session management
Distribute tools across services and scale independently

Next Steps

MCP Servers

Learn how to create and deploy MCP servers

Creating Tools

Build custom tools for your MCP servers

Build docs developers (and LLMs) love