Server SDK Reference
This document provides a comprehensive reference for the MCP Server SDK, which allows you to build and deploy Model Context Protocol servers.
Overview
The MCP Server SDK is a JavaScript/TypeScript library that helps you create MCP-compliant servers. It provides everything you need to handle client requests, manage conversation contexts, process AI model responses, and implement tools and resources.
Installation
npm / yarn
# Using npm
npm install @trmx/server
# Using yarn
yarn add @trmx/server
Basic Usage
Creating a Simple MCP Server
// Import the SDK
import { MCPServer } from '@trmx/server';
// Create a server instance
const server = new MCPServer({
port: 3000,
});
// Start the server
server.start()
.then(() => {
console.log('MCP server running on port 3000');
})
.catch(error => {
console.error('Failed to start server:', error);
});
With Express Integration
import express from 'express';
import { MCPServer } from '@trmx/server';
// Create Express app
const app = express();
// Add custom middleware
app.use(express.static('public'));
app.use((req, res, next) => {
console.log(`Request: ${req.method} ${req.path}`);
next();
});
// Create MCP server with custom Express app
const server = new MCPServer({
app,
port: 3000,
});
// Start the server
server.start().then(() => {
console.log('MCP server running on port 3000');
});
Server Configuration
The MCPServer
constructor accepts a configuration object with these options:
const server = new MCPServer({
// Core settings
port: 3000, // Server port (default: 3000)
host: '0.0.0.0', // Server host (default: '0.0.0.0')
app: expressApp, // Optional Express app instance
// AI model configuration
model: {
provider: 'openai', // AI provider (default: 'openai')
apiKey: process.env.OPENAI_API_KEY, // Provider API key
modelName: 'gpt-4', // Model name (default: 'gpt-4')
options: { // Provider-specific options
temperature: 0.7,
maxTokens: 1000,
},
},
// Features
tools: [...tools], // Array of tool definitions
resources: [...resources], // Array of resource definitions
prompts: [...prompts], // Array of prompt templates
// Context settings
contextStore: customContextStore, // Custom context store implementation
contextSettings: {
strategy: 'smart-truncation', // Context management strategy
maxTokens: 4000, // Maximum tokens for context
summarizeThreshold: 20, // When to summarize older messages
},
// Middleware and custom handlers
middleware: [...middleware], // Array of middleware functions
cors: corsOptions, // CORS options
errorHandler: customErrorHandler, // Custom error handler
// Authentication
auth: {
enabled: true, // Enable authentication
apiKey: process.env.API_KEY, // API key for authentication
customAuth: customAuthFunction, // Custom auth handler
},
// Security
httpsOptions: { // HTTPS configuration
key: fs.readFileSync('path/to/key.pem'),
cert: fs.readFileSync('path/to/cert.pem'),
},
// Advanced options
logger: customLogger, // Custom logger implementation
bodyParserOptions: {}, // Options for body-parser
metrics: {
enabled: true,
provider: 'prometheus',
},
});
Tools
Defining Tools
Tools are functions that models can call to perform actions or retrieve information:
// src/tools/calculator.js
export const calculatorTool = {
name: 'calculator', // Tool name
description: 'Performs basic arithmetic operations', // Tool description
// Parameters schema (JSON Schema format)
parameters: {
type: 'object',
properties: {
operation: {
type: 'string',
enum: ['add', 'subtract', 'multiply', 'divide'],
description: 'The operation to perform',
},
a: {
type: 'number',
description: 'First operand',
},
b: {
type: 'number',
description: 'Second operand',
},
},
required: ['operation', 'a', 'b'],
},
// Tool implementation
execute: async ({ operation, a, b }) => {
switch (operation) {
case 'add': return { result: a + b };
case 'subtract': return { result: a - b };
case 'multiply': return { result: a * b };
case 'divide':
if (b === 0) throw new Error('Division by zero');
return { result: a / b };
default:
throw new Error(`Unknown operation: ${operation}`);
}
},
};
Registering Tools
// src/tools/index.js
import { calculatorTool } from './calculator';
import { weatherTool } from './weather';
export const tools = [
calculatorTool,
weatherTool,
];
// In your server setup
import { tools } from './tools';
const server = new MCPServer({
port: 3000,
tools,
});
Advanced Tool Configuration
const advancedTool = {
name: 'advanced_tool',
description: 'An advanced tool with additional configuration',
// Standard parameters schema
parameters: {
// ...parameter definitions
},
// Access control
permissions: ['admin', 'power-user'], // Required permissions
rateLimit: {
maxRequests: 10,
windowMs: 60000, // 1 minute
},
// Execution options
timeout: 5000, // 5 seconds timeout
retry: {
maxRetries: 3,
initialDelay: 100,
},
// Tool implementation
execute: async (params, context) => {
// Access user information from context
const { userId, permissions } = context;
// Implement tool logic
// ...
return { result: 'Tool execution result' };
},
};
Resources
Defining Resources
Resources provide models with access to external data sources:
// src/resources/knowledge-base.js
export const knowledgeBaseResource = {
name: 'knowledge_base', // Resource name
description: 'Access to company knowledge base articles', // Resource description
// Resource implementation
fetch: async (query, context) => {
// Search knowledge base for relevant information
const results = await knowledgeBaseService.search(query);
// Return matching articles
return results.map(article => ({
id: article.id,
title: article.title,
content: article.content,
url: article.url,
lastUpdated: article.updatedAt,
}));
},
};
Registering Resources
// src/resources/index.js
import { knowledgeBaseResource } from './knowledge-base';
import { productCatalogResource } from './product-catalog';
export const resources = [
knowledgeBaseResource,
productCatalogResource,
];
// In your server setup
import { resources } from './resources';
const server = new MCPServer({
port: 3000,
resources,
});
Advanced Resource Configuration
const advancedResource = {
name: 'advanced_resource',
description: 'An advanced resource with additional configuration',
// Access control
permissions: ['user'], // Required permissions
rateLimit: {
maxRequests: 20,
windowMs: 60000, // 1 minute
},
// Cache configuration
cache: {
enabled: true,
ttl: 3600, // 1 hour
maxSize: 100, // Maximum items to cache
},
// Fetch implementation
fetch: async (query, context) => {
// Access user information from context
const { userId, permissions } = context;
// Implement resource logic
// ...
return [/* resource results */];
},
};
Prompt Templates
Defining Prompt Templates
Prompt templates help you create reusable, parameterized prompts:
// src/prompts/greeting.js
export const greetingPrompt = {
name: 'greeting', // Template name
description: 'A friendly greeting template', // Template description
// Template content
template: `
You are a helpful assistant for {{company_name}}.
Always greet the user by their name, {{user_name}}, if available.
Be friendly but professional in your responses.
If the user asks about {{company_name}}'s products or services, provide helpful information.
`,
// Parameters schema
parameters: {
company_name: {
type: 'string',
description: 'The company name',
},
user_name: {
type: 'string',
description: 'The user\'s name',
required: false,
},
},
};
Registering Prompt Templates
// src/prompts/index.js
import { greetingPrompt } from './greeting';
import { supportPrompt } from './support';
export const prompts = [
greetingPrompt,
supportPrompt,
];
// In your server setup
import { prompts } from './prompts';
const server = new MCPServer({
port: 3000,
prompts,
});
Context Management
Default Context Store
By default, MCP Server uses an in-memory context store, which is good for development but not for production:
// Default in-memory context store
const server = new MCPServer({
port: 3000,
// Uses default in-memory store
});
Custom Context Stores
For production, you should use a persistent context store:
// MongoDB context store
import { MongoContextStore } from '@trmx/context-mongodb';
const contextStore = new MongoContextStore({
uri: process.env.MONGODB_URI,
database: 'mcp',
collection: 'contexts',
});
const server = new MCPServer({
port: 3000,
contextStore,
});
// Redis context store
import { RedisContextStore } from '@trmx/context-redis';
const contextStore = new RedisContextStore({
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT,
password: process.env.REDIS_PASSWORD,
});
const server = new MCPServer({
port: 3000,
contextStore,
});
Custom Context Management
You can implement your own context management logic:
import { ContextManager } from '@trmx/server';
class CustomContextManager extends ContextManager {
async prepareContext(contextId, newMessage) {
// Get existing context
const context = await this.store.getContext(contextId);
// Apply custom logic for context preparation
if (context.messages.length > 20) {
// Create a summary of older messages
const oldMessages = context.messages.slice(0, 10);
const summary = await this.createSummary(oldMessages);
// Replace older messages with summary
context.messages = [
{ role: 'system', content: `Conversation summary: ${summary}` },
...context.messages.slice(10)
];
}
// Add the new message
context.messages.push(newMessage);
// Save updated context
await this.store.updateContext(contextId, context);
return context;
}
async createSummary(messages) {
// Custom logic to create a summary of messages
// This might call an AI model to generate a summary
return "Summary of previous conversation...";
}
}
// Use custom context manager in server setup
const server = new MCPServer({
contextManager: new CustomContextManager({
store: contextStore,
}),
});
Authentication
API Key Authentication
The simplest authentication method is API key-based:
const server = new MCPServer({
port: 3000,
auth: {
enabled: true,
apiKey: process.env.API_KEY, // Single API key
// Or multiple keys
apiKeys: [process.env.API_KEY_1, process.env.API_KEY_2],
},
});
Custom Authentication
You can implement custom authentication:
const server = new MCPServer({
port: 3000,
auth: {
enabled: true,
customAuth: async (req, res, next) => {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Unauthorized' });
}
const token = authHeader.split(' ')[1];
try {
// Verify token with your auth service
const user = await authService.verifyToken(token);
// Add user info to request for later use
req.user = user;
next();
} catch (error) {
return res.status(401).json({ error: 'Invalid token' });
}
},
},
});
OAuth Integration
For OAuth authentication, you'll typically set up middleware:
import passport from 'passport';
import { Strategy as OAuth2Strategy } from 'passport-oauth2';
import session from 'express-session';
// Create Express app
const app = express();
// Configure session
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
}));
// Initialize Passport
app.use(passport.initialize());
app.use(passport.session());
// Configure OAuth2 strategy
passport.use(new OAuth2Strategy({
authorizationURL: 'https://auth-provider.com/oauth2/authorize',
tokenURL: 'https://auth-provider.com/oauth2/token',
clientID: process.env.OAUTH_CLIENT_ID,
clientSecret: process.env.OAUTH_CLIENT_SECRET,
callbackURL: 'https://your-mcp-server.com/auth/callback',
}, (accessToken, refreshToken, profile, done) => {
// Verify user and call done(null, user)
}));
// Serialize user to session
passport.serializeUser((user, done) => {
done(null, user.id);
});
// Deserialize user from session
passport.deserializeUser(async (id, done) => {
try {
const user = await userService.findById(id);
done(null, user);
} catch (error) {
done(error);
}
});
// Set up auth routes
app.get('/auth/login', passport.authenticate('oauth2'));
app.get('/auth/callback', passport.authenticate('oauth2', {
successRedirect: '/auth/success',
failureRedirect: '/auth/failure',
}));
// Create MCP server with the app
const server = new MCPServer({
app,
port: 3000,
auth: {
enabled: true,
customAuth: (req, res, next) => {
if (req.isAuthenticated()) {
return next();
}
res.status(401).json({ error: 'Unauthorized' });
},
},
});
Error Handling
Default Error Handler
The SDK provides a default error handler that formats errors according to the MCP protocol:
// Default error handling
const server = new MCPServer({
port: 3000,
// Uses default error handler
});
Custom Error Handler
You can implement custom error handling:
const server = new MCPServer({
port: 3000,
errorHandler: (err, req, res, next) => {
// Log the error
console.error('Error:', err);
// Format error response
const statusCode = err.statusCode || 500;
const errorMessage = err.message || 'Internal Server Error';
// Format MCP protocol error response
res.status(statusCode).json({
error: {
code: err.code || (statusCode === 401 ? 'UNAUTHORIZED' : 'INTERNAL_ERROR'),
message: errorMessage,
data: err.data || undefined,
},
id: req.body.id,
});
// Report error to monitoring service
errorReportingService.report(err);
},
});
Middleware
Adding Middleware
You can add custom middleware functions:
// Rate limiting middleware
import rateLimit from 'express-rate-limit';
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
});
// Logging middleware
const loggingMiddleware = (req, res, next) => {
console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
next();
};
// Add middleware to server
const server = new MCPServer({
port: 3000,
middleware: [
apiLimiter,
loggingMiddleware,
],
});
CORS Configuration
Configure CORS for cross-origin requests:
const server = new MCPServer({
port: 3000,
cors: {
origin: ['https://your-app.com', 'https://admin.your-app.com'],
methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
},
});
Streaming Support
Enabling Streaming
Enable streaming for real-time AI responses:
const server = new MCPServer({
port: 3000,
streaming: {
enabled: true, // Enable streaming support
chunkSize: 10, // Characters per chunk (for testing)
},
});
Metrics and Monitoring
Enabling Metrics
Configure metrics collection for monitoring:
const server = new MCPServer({
port: 3000,
metrics: {
enabled: true,
provider: 'prometheus', // Metrics provider
endpoint: '/metrics', // Metrics endpoint
},
});
Health Check Endpoint
Add a health check endpoint:
const server = new MCPServer({
port: 3000,
healthCheck: {
enabled: true,
endpoint: '/health',
checks: [
// Custom health checks
async () => {
// Check database connection
const dbStatus = await checkDatabaseConnection();
return {
name: 'database',
status: dbStatus ? 'up' : 'down',
};
},
],
},
});
TypeScript Support
The SDK provides full TypeScript support:
import { MCPServer, Tool, Resource, ContextStore } from '@trmx/server';
// Define tool with TypeScript
interface CalculatorParams {
operation: 'add' | 'subtract' | 'multiply' | 'divide';
a: number;
b: number;
}
interface CalculatorResult {
result: number;
}
const calculatorTool: Tool<CalculatorParams, CalculatorResult> = {
name: 'calculator',
description: 'Performs basic arithmetic operations',
parameters: {
type: 'object',
properties: {
operation: {
type: 'string',
enum: ['add', 'subtract', 'multiply', 'divide'],
description: 'The operation to perform',
},
a: {
type: 'number',
description: 'First operand',
},
b: {
type: 'number',
description: 'Second operand',
},
},
required: ['operation', 'a', 'b'],
},
execute: async ({ operation, a, b }) => {
switch (operation) {
case 'add': return { result: a + b };
case 'subtract': return { result: a - b };
case 'multiply': return { result: a * b };
case 'divide':
if (b === 0) throw new Error('Division by zero');
return { result: a / b };
default:
throw new Error(`Unknown operation: ${operation as string}`);
}
},
};
// Create server with TypeScript
const server = new MCPServer({
port: 3000,
tools: [calculatorTool],
});
Deployment
Production Best Practices
When deploying to production, follow these best practices:
- Use a persistent context store (MongoDB, Redis, etc.)
- Enable authentication
- Configure HTTPS
- Set up proper error handling and logging
- Implement rate limiting
- Monitor server health and performance
Example production configuration:
import { MCPServer } from '@trmx/server';
import { MongoContextStore } from '@trmx/context-mongodb';
import fs from 'fs';
// Create context store
const contextStore = new MongoContextStore({
uri: process.env.MONGODB_URI,
database: 'mcp',
collection: 'contexts',
});
// Create server with production settings
const server = new MCPServer({
port: process.env.PORT || 3000,
// Use context store
contextStore,
// Enable authentication
auth: {
enabled: true,
apiKey: process.env.API_KEY,
},
// Configure HTTPS
httpsOptions: {
key: fs.readFileSync('path/to/key.pem'),
cert: fs.readFileSync('path/to/cert.pem'),
},
// CORS configuration
cors: {
origin: process.env.ALLOWED_ORIGINS?.split(',') || '*',
methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization'],
},
// Rate limiting
middleware: [
rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
}),
],
// Metrics and monitoring
metrics: {
enabled: true,
provider: 'prometheus',
},
// Health check
healthCheck: {
enabled: true,
},
});
// Start server
server.start().catch(error => {
console.error('Failed to start server:', error);
process.exit(1);
});