Skip to content

Migrate from MCP SDK

Guide for converting existing @modelcontextprotocol/sdk servers to air.

Key differences

MCP SDK directair
Tool definitionserver.tool(name, desc, zodSchema, handler)defineTool(name, { params, handler })
ParametersManual Zod schemas'string', 'number?' shorthand (Zod also works)
Return value{ content: [{ type: 'text', text: '...' }] } manualReturn anything → auto-converted
Error handlingtry/catch in every handlerBuilt-in error boundary middleware
TransportStdioServerTransport / Express setuptransport: { type: 'sse' } one line
Retry/cacheManual implementationuse: [retryPlugin(), cachePlugin()]

Before / After

Tool definition

MCP SDK:

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

const server = new McpServer({ name: 'my-server', version: '0.1.0' });

server.tool('search', 'Search documents',
  { query: z.string(), limit: z.number().optional() },
  async ({ query, limit }) => {
    try {
      const results = await doSearch(query, limit);
      return { content: [{ type: 'text', text: JSON.stringify(results, null, 2) }] };
    } catch (error) {
      return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
    }
  }
);

air:

typescript
import { defineServer, defineTool } from '@airmcp-dev/core';

const server = defineServer({
  name: 'my-server',
  tools: [
    defineTool('search', {
      description: 'Search documents',
      params: { query: 'string', limit: 'number?' },
      handler: async ({ query, limit }) => doSearch(query, limit),
    }),
  ],
});
server.start();

Transport

MCP SDK: Manual StdioServerTransport or Express + SSEServerTransport setup.

air:

typescript
defineServer({ transport: { type: 'sse', port: 3510 } });

Resources

MCP SDK: server.resource(new ResourceTemplate(...), handler) with manual content wrapping.

air:

typescript
defineResource('file:///{path}', {
  name: 'file',
  handler: async (uri) => readFile(matchTemplate('file:///{path}', uri)!.path, 'utf-8'),
});

Step-by-step migration

1. Replace dependencies

bash
npm uninstall @modelcontextprotocol/sdk
npm install @airmcp-dev/core

INFO

air uses @modelcontextprotocol/sdk internally. No need to depend on it directly.

2. Change imports

typescript
// Before
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
// After
import { defineServer, defineTool } from '@airmcp-dev/core';

3. Convert server definition

typescript
// Before
const server = new McpServer({ name: 'my-server', version: '0.1.0' });
server.tool('search', '...', { query: z.string() }, handler);
await server.connect(new StdioServerTransport());

// After
const server = defineServer({
  name: 'my-server',
  tools: [defineTool('search', { params: { query: 'string' }, handler })],
});
server.start();

4. Remove error handling boilerplate

Remove try/catch from each handler. air handles it automatically.

5. Add plugins (optional)

Replace manually implemented retry/cache/auth with plugins:

typescript
use: [retryPlugin({ maxRetries: 3 }), cachePlugin({ ttlMs: 60_000 }), authPlugin({ ... })]

Compatibility

air uses @modelcontextprotocol/sdk ^1.12.0 internally. MCP protocol compatibility is identical. Existing clients (Claude Desktop, Cursor, VS Code) work without changes.

Released under the Apache-2.0 License.