70 KiB
FastMCP Implementation Plan for Agentic-Flow
Executive Summary
This document outlines a comprehensive plan to integrate the fastmcp TypeScript framework into agentic-flow, enhancing the Model Context Protocol (MCP) server infrastructure with improved performance, real-time streaming capabilities via HTTP transport, and optional security features.
Current State
- Architecture: 4 MCP servers (claude-flow-sdk in-process, claude-flow, flow-nexus, agentic-payments as subprocesses)
- Tools: 203+ MCP tools across multiple domains
- Implementation: Custom MCP implementation using
@anthropic-ai/claude-agent-sdkand@modelcontextprotocol/sdk - Transport: Primarily stdio for local/subprocess communication
- Deployment: Local, Docker, and cloud environments
Target State
- Framework: fastmcp TypeScript framework for standardized MCP server implementation
- Transport: Dual support for stdio (local) and HTTP streaming (network/cloud)
- Security: Optional authentication, authorization, and rate limiting layers
- Performance: Reduced boilerplate, improved tooling, better debugging
- Maintainability: Standardized patterns across all MCP servers
Benefits
- Developer Experience: Simplified tool definition with Zod schema validation
- Performance: Built-in optimizations, streaming support, progress notifications
- Security: Session-based authentication, tool-level authorization, rate limiting
- Observability: Enhanced logging, typed server events, health-check endpoints
- Flexibility: Support for both stdio and HTTP transports with automatic CORS
- Testing: Built-in CLI tools for development and debugging (
npx fastmcp dev)
1. Research Summary
FastMCP Overview
FastMCP (v3.19.0+) is a TypeScript framework built on top of @modelcontextprotocol/sdk that eliminates boilerplate and provides intuitive APIs for building MCP servers.
Key Features:
- Simple tool, resource, and prompt definition
- Schema validation support (Zod, ArkType, Valibot, Standard Schema)
- Session-based authentication with tool-level access control
- Multiple transport types: stdio, HTTP streaming (SSE deprecated)
- Stateless mode for serverless deployments
- Progress notifications and streaming output
- Typed server events and prompt auto-completion
- CORS enabled by default
- Health-check endpoints
- Built-in development CLI
Package Info:
- npm:
npm install fastmcp - GitHub: https://github.com/punkpeye/fastmcp
- Documentation: https://gofastmcp.com/
- Usage: 382+ projects in npm registry
Transport Mechanisms
1. Stdio Transport (Default)
- Use Case: Local command-line tools, desktop applications (Claude Desktop)
- Communication: Standard input/output streams
- Advantages: Simple, lightweight, perfect for subprocess communication
- Current Match: Aligns with current agentic-flow subprocess servers
2. HTTP Streaming Transport (Recommended for Web)
- Use Case: Network-based deployments, multiple clients, cloud services
- Communication: Streamable HTTP with optional SSE for server-to-client streaming
- Advantages: Bidirectional communication, scalable, web-friendly
- Target Use: Flow-nexus cloud features, remote agent coordination
3. SSE Transport (Deprecated)
- Status: Maintained for backward compatibility only
- Recommendation: Use HTTP streaming for all new projects
- Migration Path: Clients can fall back from HTTP to SSE for old servers
Security Features
Authentication
const server = new FastMCP({
name: "Secure Server",
authenticate: async (req) => {
const apiKey = req.headers.get('x-api-key');
if (!apiKey || apiKey !== process.env.API_KEY) {
throw new Response('Unauthorized', { status: 401 });
}
return { userId: 'user-123', role: 'admin' };
}
});
Tool-Level Authorization
server.addTool({
name: "admin-dashboard",
canAccess: (auth) => auth.role === 'admin',
execute: async () => { /* ... */ }
});
Rate Limiting
- TypeScript version: Middleware pattern support (not built-in like Python version)
- Python version: Built-in token bucket algorithms, per-client identification
- Implementation: Custom middleware or third-party libraries (express-rate-limit)
OAuth Support
- Built-in OAuth discovery endpoints
- Supports MCP Specification 2025-03-26 and 2025-06-18
Comparison: Current vs FastMCP
| Feature | Current Implementation | FastMCP Implementation |
|---|---|---|
| Tool Definition | Manual SDK calls with verbose handlers | Simple addTool() with Zod schemas |
| Schema Validation | Custom validation logic | Built-in Zod/ArkType/Valibot support |
| Authentication | Not implemented | Session-based with tool-level control |
| Transport | Stdio only | Stdio + HTTP streaming |
| Progress Reporting | Not available | Built-in progress notifications |
| Streaming | Not available | Built-in streaming output |
| Development Tools | Manual testing | npx fastmcp dev and npx fastmcp inspect |
| Error Handling | Custom error handling | Standardized error responses |
| Type Safety | Partial | Full TypeScript support |
| CORS | Manual setup | Enabled by default |
| Health Checks | Not available | Built-in health-check endpoint |
| Session Management | Not available | Built-in session support |
| OAuth | Not implemented | Built-in OAuth discovery |
2. Technical Architecture
2.1 Architecture Overview
┌─────────────────────────────────────────────────────────────┐
│ Agentic-Flow Core │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Goal Planner│ │ Orchestrator│ │ Agent SDK │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └─────────────────┴─────────────────┘ │
│ │ │
└───────────────────────────┼──────────────────────────────────┘
│
┌───────▼────────┐
│ MCP Gateway │
│ (FastMCP Hub) │
└───────┬────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
┌────▼─────┐ ┌─────▼──────┐ ┌─────▼──────┐
│ In-Process│ │ Subprocess │ │ HTTP │
│ FastMCP │ │ FastMCP │ │ FastMCP │
│ Servers │ │ Servers │ │ Servers │
└────┬─────┘ └─────┬──────┘ └─────┬──────┘
│ │ │
┌────▼─────┐ ┌─────▼──────┐ ┌─────▼──────┐
│ claude- │ │ claude- │ │ flow-nexus │
│ flow-sdk │ │ flow │ │ (cloud) │
│ │ │ agentic- │ │ │
│ (stdio) │ │ payments │ │ (HTTP) │
└──────────┘ │ (stdio) │ └────────────┘
└────────────┘
Transport Layer:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Stdio Transport │ │ HTTP Streaming │ │ SSE (Legacy) │
│ │ │ │ │ │
│ • stdin/stdout │ │ • Bidirectional │ │ • Server→Client │
│ • Local process │ │ • Network │ │ • Deprecated │
│ • Claude Desktop│ │ • Multi-client │ │ • Backward compat│
│ • Subprocess │ │ • Cloud ready │ │ • Migration only│
└──────────────────┘ └──────────────────┘ └──────────────────┘
Security Layer (Optional):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┌─────────────────────────────────────────────────────────────┐
│ Authentication │ Authorization │ Rate Limiting │
│ ─────────────── │ ───────────── │ ──────────── │
│ • API Key │ • Tool-level │ • Per-client │
│ • Bearer Token │ • Role-based │ • Per-tool │
│ • OAuth 2.0 │ • Custom logic │ • Token bucket │
│ • Session-based │ • canAccess() │ • Middleware │
└─────────────────────────────────────────────────────────────┘
2.2 Server Migration Plan
Phase 1: In-Process Server (claude-flow-sdk)
Current: Uses @anthropic-ai/claude-agent-sdk with custom tool definitions
Target: FastMCP with stdio transport, no authentication needed (in-process)
// Before (current)
import { createSdkMcpServer, tool } from '@anthropic-ai/claude-agent-sdk';
import { z } from 'zod';
export const claudeFlowSdkServer = createSdkMcpServer({
name: 'claude-flow-sdk',
version: '1.0.0',
tools: [
tool('memory_store', '...', { key: z.string(), ... }, async (args) => { ... })
]
});
// After (FastMCP)
import { FastMCP } from 'fastmcp';
import { z } from 'zod';
const server = new FastMCP({
name: 'claude-flow-sdk',
version: '1.0.0'
});
server.addTool({
name: 'memory_store',
description: 'Store a value in persistent memory',
parameters: z.object({
key: z.string().describe('Memory key'),
value: z.string().describe('Value to store'),
namespace: z.string().optional().default('default'),
ttl: z.number().optional()
}),
execute: async ({ key, value, namespace, ttl }) => {
// Implementation
return `Stored ${key} in ${namespace}`;
}
});
server.start({ transportType: 'stdio' });
Phase 2: Subprocess Servers (claude-flow, agentic-payments)
Current: Spawned as subprocesses with stdio communication Target: FastMCP with stdio transport, optional authentication
// claude-flow server with optional auth
import { FastMCP } from 'fastmcp';
import { z } from 'zod';
const server = new FastMCP({
name: 'claude-flow',
version: '2.0.0',
// Optional: Enable authentication for secure environments
authenticate: process.env.SECURE_MODE === 'true'
? async (req) => {
const token = req.headers.get('authorization')?.replace('Bearer ', '');
if (!token || token !== process.env.CLAUDE_FLOW_TOKEN) {
throw new Response('Unauthorized', { status: 401 });
}
return { authenticated: true };
}
: undefined
});
// Tool definitions with progress reporting
server.addTool({
name: 'swarm_init',
description: 'Initialize multi-agent swarm',
parameters: z.object({
topology: z.enum(['mesh', 'hierarchical', 'ring', 'star']),
maxAgents: z.number().default(8),
strategy: z.enum(['balanced', 'specialized', 'adaptive']).default('balanced')
}),
execute: async ({ topology, maxAgents, strategy }, { onProgress }) => {
onProgress?.({ progress: 0.2, message: 'Initializing topology...' });
// Initialize swarm
onProgress?.({ progress: 0.5, message: 'Spawning agents...' });
// Spawn agents
onProgress?.({ progress: 1.0, message: 'Swarm ready' });
return { swarmId: 'swarm-123', agents: maxAgents, topology };
}
});
server.start({ transportType: 'stdio' });
Phase 3: Cloud/Network Server (flow-nexus)
Current: HTTP-based custom implementation Target: FastMCP with HTTP streaming transport, full authentication
// flow-nexus cloud server with full security
import { FastMCP } from 'fastmcp';
import { z } from 'zod';
import { verifyJWT, checkRateLimit } from './security';
const server = new FastMCP({
name: 'flow-nexus',
version: '1.0.0',
authenticate: async (req) => {
// JWT-based authentication
const token = req.headers.get('authorization')?.replace('Bearer ', '');
if (!token) {
throw new Response('Missing token', { status: 401 });
}
const payload = await verifyJWT(token);
if (!payload) {
throw new Response('Invalid token', { status: 401 });
}
// Rate limiting check
const allowed = await checkRateLimit(payload.userId);
if (!allowed) {
throw new Response('Rate limit exceeded', { status: 429 });
}
return {
userId: payload.userId,
tier: payload.tier,
role: payload.role
};
}
});
// Tool with role-based access control
server.addTool({
name: 'sandbox_create',
description: 'Create isolated code execution sandbox',
canAccess: (auth) => ['pro', 'enterprise'].includes(auth.tier),
parameters: z.object({
template: z.enum(['node', 'python', 'react', 'nextjs']),
name: z.string().optional(),
env_vars: z.record(z.string()).optional()
}),
execute: async ({ template, name, env_vars }, { onProgress, auth }) => {
onProgress?.({ progress: 0.1, message: 'Allocating sandbox...' });
// Create sandbox
onProgress?.({ progress: 0.5, message: 'Installing dependencies...' });
// Setup environment
onProgress?.({ progress: 1.0, message: 'Sandbox ready' });
return {
sandboxId: 'sandbox-456',
template,
userId: auth.userId,
url: `https://sandbox-456.flow-nexus.io`
};
}
});
// Start with HTTP streaming transport
server.start({
transportType: 'http',
port: process.env.PORT || 8080,
host: '0.0.0.0'
});
2.3 Security Architecture
Authentication Layer
// security/auth.ts
import jwt from 'jsonwebtoken';
export interface AuthContext {
userId: string;
tier: 'free' | 'pro' | 'enterprise';
role: 'user' | 'admin';
permissions: string[];
}
export async function verifyJWT(token: string): Promise<AuthContext | null> {
try {
const payload = jwt.verify(token, process.env.JWT_SECRET!) as any;
return {
userId: payload.sub,
tier: payload.tier || 'free',
role: payload.role || 'user',
permissions: payload.permissions || []
};
} catch {
return null;
}
}
export async function verifyAPIKey(apiKey: string): Promise<AuthContext | null> {
// Check against database or cache
const user = await db.users.findByAPIKey(apiKey);
if (!user) return null;
return {
userId: user.id,
tier: user.tier,
role: user.role,
permissions: user.permissions
};
}
Rate Limiting
// security/rate-limit.ts
import { RedisClient } from 'redis';
interface RateLimitConfig {
windowMs: number;
maxRequests: number;
keyPrefix: string;
}
export class RateLimiter {
private redis: RedisClient;
constructor(private config: RateLimitConfig) {
this.redis = new RedisClient(process.env.REDIS_URL);
}
async checkLimit(userId: string): Promise<boolean> {
const key = `${this.config.keyPrefix}:${userId}`;
const now = Date.now();
const windowStart = now - this.config.windowMs;
// Remove old entries
await this.redis.zremrangebyscore(key, 0, windowStart);
// Count requests in current window
const count = await this.redis.zcard(key);
if (count >= this.config.maxRequests) {
return false;
}
// Add current request
await this.redis.zadd(key, now, `${now}`);
await this.redis.expire(key, Math.ceil(this.config.windowMs / 1000));
return true;
}
}
// Usage
const limiter = new RateLimiter({
windowMs: 60000, // 1 minute
maxRequests: 100,
keyPrefix: 'rate-limit'
});
export async function checkRateLimit(userId: string): Promise<boolean> {
return await limiter.checkLimit(userId);
}
Tool Authorization
// security/authorization.ts
export interface Permission {
resource: string;
action: 'read' | 'write' | 'execute';
}
export function hasPermission(
auth: AuthContext,
required: Permission
): boolean {
// Admin has all permissions
if (auth.role === 'admin') return true;
// Check tier-based permissions
const tierPermissions = {
free: ['swarm:read', 'memory:read', 'agent:read'],
pro: ['swarm:*', 'memory:*', 'agent:*', 'sandbox:*'],
enterprise: ['*']
};
const permissions = tierPermissions[auth.tier];
const pattern = `${required.resource}:${required.action}`;
return permissions.includes(pattern) ||
permissions.includes(`${required.resource}:*`) ||
permissions.includes('*');
}
// Tool-level authorization helper
export function requirePermission(resource: string, action: string) {
return (auth: AuthContext) => hasPermission(auth, { resource, action });
}
2.4 Transport Selection Strategy
// config/transport.ts
export interface TransportConfig {
type: 'stdio' | 'http';
port?: number;
host?: string;
enableAuth?: boolean;
enableCORS?: boolean;
}
export function selectTransport(): TransportConfig {
// Environment-based transport selection
const env = process.env.NODE_ENV || 'development';
const deploymentMode = process.env.DEPLOYMENT_MODE || 'local';
// Local subprocess: stdio
if (deploymentMode === 'local' || deploymentMode === 'subprocess') {
return {
type: 'stdio',
enableAuth: false
};
}
// Docker container: stdio or HTTP based on port
if (deploymentMode === 'docker') {
return {
type: process.env.MCP_PORT ? 'http' : 'stdio',
port: parseInt(process.env.MCP_PORT || '8080'),
host: '0.0.0.0',
enableAuth: env === 'production',
enableCORS: true
};
}
// Cloud deployment: HTTP with auth
if (deploymentMode === 'cloud') {
return {
type: 'http',
port: parseInt(process.env.PORT || '8080'),
host: '0.0.0.0',
enableAuth: true,
enableCORS: true
};
}
// Default to stdio
return {
type: 'stdio',
enableAuth: false
};
}
3. Migration Strategy
3.1 Migration Phases
Phase 0: Preparation (Week 1)
Goals:
- Install and evaluate fastmcp in development environment
- Create proof-of-concept with single tool
- Benchmark performance vs current implementation
- Document API differences
Tasks:
- Install fastmcp:
npm install fastmcp - Create test server with 1-2 tools
- Compare stdio performance
- Test HTTP streaming transport
- Evaluate authentication options
- Document findings
Deliverables:
- POC server implementation
- Performance comparison report
- API migration guide draft
Phase 1: In-Process Server Migration (Week 2-3)
Target: claude-flow-sdk server (in-process, stdio)
Migration Steps:
- Create new
src/mcp/fastmcp/directory structure - Implement base FastMCP server class
- Migrate tools one category at a time:
- Memory tools (store, retrieve, search)
- Swarm tools (init, spawn, status)
- Coordination tools (orchestrate, metrics)
- Add comprehensive error handling
- Implement logging integration
- Create migration tests
- Run parallel with old implementation
- Gradual rollout with feature flags
Code Structure:
src/mcp/fastmcp/
├── servers/
│ ├── base.ts # Base FastMCP server class
│ ├── claude-flow-sdk.ts # In-process server
│ └── index.ts
├── tools/
│ ├── memory/ # Memory tools
│ │ ├── store.ts
│ │ ├── retrieve.ts
│ │ └── search.ts
│ ├── swarm/ # Swarm tools
│ │ ├── init.ts
│ │ ├── spawn.ts
│ │ └── status.ts
│ └── index.ts
├── security/
│ ├── auth.ts # Authentication
│ ├── rate-limit.ts # Rate limiting
│ └── authorization.ts # Tool-level auth
├── config/
│ ├── transport.ts # Transport selection
│ └── server-config.ts # Server configuration
└── index.ts
Success Criteria:
- All existing tools work with FastMCP
- No performance degradation
- Improved error messages
- Better TypeScript types
- Tests passing
Phase 2: Subprocess Servers Migration (Week 4-5)
Target: claude-flow and agentic-payments servers (subprocess, stdio)
Migration Steps:
- Migrate claude-flow server
- Convert all swarm coordination tools
- Add progress reporting
- Implement streaming for long operations
- Add optional authentication
- Migrate agentic-payments server
- Convert payment tools
- Add transaction streaming
- Implement webhook notifications
- Add authentication
- Update subprocess spawning logic
- Test inter-server communication
- Validate memory coordination
Authentication:
- Development: No authentication
- Production: Optional token-based authentication via environment variable
Success Criteria:
- Subprocess servers work seamlessly
- Progress reporting functional
- Streaming operations work
- Optional auth doesn't break existing workflows
Phase 3: HTTP/Cloud Server (Week 6-7)
Target: flow-nexus server (HTTP streaming, full auth)
Migration Steps:
- Implement HTTP streaming transport
- Add JWT-based authentication
- Implement rate limiting with Redis
- Add role-based tool access control
- Setup CORS configuration
- Add health-check endpoints
- Implement session management
- Deploy to staging environment
- Load testing
- Production deployment
Security Features:
- JWT authentication
- API key support
- OAuth 2.0 integration
- Per-user rate limiting
- Tool-level authorization
- Request logging
- Audit trail
Success Criteria:
- HTTP transport working in cloud
- Authentication prevents unauthorized access
- Rate limiting prevents abuse
- Multi-client support verified
- Health checks operational
- Performance acceptable under load
Phase 4: Testing & Validation (Week 8)
Goals:
- Comprehensive integration testing
- Performance benchmarking
- Security audit
- Documentation update
Testing Matrix:
| Server | Transport | Auth | Tests |
|---|---|---|---|
| claude-flow-sdk | stdio | None | Unit, Integration |
| claude-flow | stdio | Optional | Unit, Integration, E2E |
| agentic-payments | stdio | Optional | Unit, Integration |
| flow-nexus | HTTP | Required | Unit, Integration, E2E, Load |
Performance Benchmarks:
- Tool invocation latency
- Throughput (tools/second)
- Memory usage
- CPU utilization
- Startup time
- Subprocess spawn time
- HTTP request latency
Security Tests:
- Authentication bypass attempts
- Rate limit effectiveness
- Authorization checks
- Token expiration
- CORS validation
- Input sanitization
Phase 5: Documentation & Rollout (Week 9-10)
Goals:
- Complete documentation
- Migration guide for users
- Training materials
- Staged rollout
Documentation:
- Architecture overview
- API reference for each server
- Authentication guide
- Transport selection guide
- Security best practices
- Migration guide from v1.x
- Troubleshooting guide
- Performance tuning guide
Rollout Strategy:
- Beta release (10% users)
- Feedback collection
- Bug fixes
- Expanded rollout (50% users)
- Final validation
- Full rollout (100% users)
- Deprecate old implementation
3.2 Backward Compatibility
Strategy:
- Maintain old implementation alongside FastMCP
- Feature flag:
USE_FASTMCP=true/false - Gradual migration path
- Support both implementations for 2 releases
Feature Flag Implementation:
// src/mcp/index.ts
import { getServerConfig } from './config';
import { createLegacyServer } from './legacy';
import { createFastMCPServer } from './fastmcp';
export function createMCPServer(name: string) {
const config = getServerConfig();
if (config.useFastMCP) {
return createFastMCPServer(name);
} else {
return createLegacyServer(name);
}
}
Migration Timeline:
- v2.0.0: FastMCP available, old implementation default
- v2.1.0: FastMCP default, old implementation available via flag
- v2.2.0: FastMCP only, old implementation removed
3.3 Rollback Plan
Triggers:
- Critical bugs in production
- Performance degradation > 20%
- Authentication vulnerabilities
- Data loss or corruption
Rollback Procedure:
- Set
USE_FASTMCP=falseenvironment variable - Restart affected servers
- Validate old implementation working
- Investigate issue
- Fix and retest
- Re-enable FastMCP
Rollback Testing:
- Practice rollback in staging
- Document time to rollback (target: < 5 minutes)
- Validate no data loss during rollback
4. Implementation Details
4.1 Code Structure
src/mcp/
├── fastmcp/ # New FastMCP implementation
│ ├── servers/
│ │ ├── base.ts # Base server class with common setup
│ │ ├── claude-flow-sdk.ts # In-process server
│ │ ├── claude-flow.ts # Subprocess server
│ │ ├── agentic-payments.ts # Payments subprocess server
│ │ ├── flow-nexus.ts # Cloud HTTP server
│ │ └── index.ts
│ ├── tools/
│ │ ├── memory/
│ │ │ ├── store.ts
│ │ │ ├── retrieve.ts
│ │ │ ├── search.ts
│ │ │ ├── list.ts
│ │ │ └── delete.ts
│ │ ├── swarm/
│ │ │ ├── init.ts
│ │ │ ├── spawn.ts
│ │ │ ├── status.ts
│ │ │ ├── scale.ts
│ │ │ └── destroy.ts
│ │ ├── agent/
│ │ │ ├── list.ts
│ │ │ ├── metrics.ts
│ │ │ └── monitor.ts
│ │ ├── task/
│ │ │ ├── orchestrate.ts
│ │ │ ├── status.ts
│ │ │ └── results.ts
│ │ ├── neural/
│ │ │ ├── train.ts
│ │ │ ├── predict.ts
│ │ │ ├── status.ts
│ │ │ └── patterns.ts
│ │ ├── github/
│ │ │ ├── analyze.ts
│ │ │ ├── pr-manage.ts
│ │ │ └── issue-track.ts
│ │ ├── sandbox/
│ │ │ ├── create.ts
│ │ │ ├── execute.ts
│ │ │ ├── upload.ts
│ │ │ └── logs.ts
│ │ └── index.ts
│ ├── security/
│ │ ├── auth.ts # Authentication handlers
│ │ ├── rate-limit.ts # Rate limiting
│ │ ├── authorization.ts # Tool authorization
│ │ └── index.ts
│ ├── middleware/
│ │ ├── logging.ts # Request/response logging
│ │ ├── metrics.ts # Performance metrics
│ │ ├── error-handler.ts # Error handling
│ │ └── index.ts
│ ├── config/
│ │ ├── transport.ts # Transport configuration
│ │ ├── server-config.ts # Server settings
│ │ ├── security-config.ts # Security settings
│ │ └── index.ts
│ ├── utils/
│ │ ├── progress.ts # Progress reporting helpers
│ │ ├── streaming.ts # Streaming helpers
│ │ ├── validation.ts # Schema validation
│ │ └── index.ts
│ ├── types/
│ │ ├── auth.ts # Auth types
│ │ ├── tools.ts # Tool types
│ │ ├── config.ts # Config types
│ │ └── index.ts
│ └── index.ts
├── legacy/ # Old implementation (deprecated)
│ └── ...
└── index.ts # Main entry point with feature flag
4.2 Base Server Implementation
// src/mcp/fastmcp/servers/base.ts
import { FastMCP } from 'fastmcp';
import { z } from 'zod';
import type { AuthContext, TransportConfig } from '../types';
import { setupLogging } from '../middleware/logging';
import { setupMetrics } from '../middleware/metrics';
import { setupErrorHandler } from '../middleware/error-handler';
export interface BaseServerConfig {
name: string;
version: string;
transport: TransportConfig;
enableAuth?: boolean;
enableMetrics?: boolean;
enableLogging?: boolean;
}
export abstract class BaseMCPServer {
protected server: FastMCP;
protected config: BaseServerConfig;
constructor(config: BaseServerConfig) {
this.config = config;
this.server = new FastMCP({
name: config.name,
version: config.version,
authenticate: config.enableAuth
? this.authenticate.bind(this)
: undefined
});
// Setup middleware
if (config.enableLogging) {
setupLogging(this.server);
}
if (config.enableMetrics) {
setupMetrics(this.server);
}
setupErrorHandler(this.server);
// Register tools
this.registerTools();
}
protected abstract registerTools(): void;
protected async authenticate(req: Request): Promise<AuthContext> {
// Override in subclasses for custom auth
throw new Response('Authentication not implemented', { status: 501 });
}
public async start() {
const { transport } = this.config;
if (transport.type === 'stdio') {
await this.server.start({ transportType: 'stdio' });
} else {
await this.server.start({
transportType: 'http',
port: transport.port,
host: transport.host
});
}
console.log(`${this.config.name} server started on ${transport.type}`);
}
public async stop() {
// Cleanup logic
}
}
4.3 Tool Implementation Example
// src/mcp/fastmcp/tools/memory/store.ts
import { z } from 'zod';
import type { ToolDefinition } from '../../types';
import { execSync } from 'child_process';
export const memoryStoreTool: ToolDefinition = {
name: 'memory_store',
description: 'Store a value in persistent memory with optional namespace and TTL',
parameters: z.object({
key: z.string()
.min(1)
.describe('Memory key'),
value: z.string()
.describe('Value to store'),
namespace: z.string()
.optional()
.default('default')
.describe('Memory namespace'),
ttl: z.number()
.positive()
.optional()
.describe('Time-to-live in seconds')
}),
execute: async ({ key, value, namespace, ttl }, { onProgress, auth }) => {
try {
// Progress reporting
onProgress?.({ progress: 0.2, message: 'Validating input...' });
// Build command
const cmd = [
'npx claude-flow@alpha memory store',
`"${key}"`,
`"${value}"`,
`--namespace "${namespace}"`,
ttl ? `--ttl ${ttl}` : ''
].filter(Boolean).join(' ');
onProgress?.({ progress: 0.5, message: 'Storing value...' });
// Execute
const result = execSync(cmd, {
encoding: 'utf-8',
maxBuffer: 10 * 1024 * 1024
});
onProgress?.({ progress: 1.0, message: 'Stored successfully' });
// Return formatted result
return {
success: true,
key,
namespace,
size: value.length,
ttl,
userId: auth?.userId
};
} catch (error: any) {
throw new Error(`Failed to store memory: ${error.message}`);
}
}
};
4.4 Authentication Implementation
// src/mcp/fastmcp/security/auth.ts
import jwt from 'jsonwebtoken';
import type { AuthContext } from '../types';
export async function authenticateJWT(req: Request): Promise<AuthContext> {
const authHeader = req.headers.get('authorization');
if (!authHeader) {
throw new Response('Missing Authorization header', { status: 401 });
}
const token = authHeader.replace('Bearer ', '');
if (!token) {
throw new Response('Invalid Authorization format', { status: 401 });
}
try {
const payload = jwt.verify(token, process.env.JWT_SECRET!) as any;
return {
userId: payload.sub,
tier: payload.tier || 'free',
role: payload.role || 'user',
permissions: payload.permissions || []
};
} catch (error) {
throw new Response('Invalid or expired token', { status: 401 });
}
}
export async function authenticateAPIKey(req: Request): Promise<AuthContext> {
const apiKey = req.headers.get('x-api-key');
if (!apiKey) {
throw new Response('Missing API key', { status: 401 });
}
// In production, check against database
if (apiKey !== process.env.API_KEY) {
throw new Response('Invalid API key', { status: 401 });
}
// Return static context for demo
return {
userId: 'api-key-user',
tier: 'pro',
role: 'user',
permissions: ['*']
};
}
4.5 Server-Specific Implementations
Claude Flow SDK Server (In-Process)
// src/mcp/fastmcp/servers/claude-flow-sdk.ts
import { BaseMCPServer } from './base';
import { selectTransport } from '../config/transport';
import * as memoryTools from '../tools/memory';
import * as swarmTools from '../tools/swarm';
import * as agentTools from '../tools/agent';
import * as taskTools from '../tools/task';
export class ClaudeFlowSdkServer extends BaseMCPServer {
constructor() {
super({
name: 'claude-flow-sdk',
version: '1.0.0',
transport: selectTransport(),
enableAuth: false, // In-process, no auth needed
enableMetrics: true,
enableLogging: true
});
}
protected registerTools() {
// Memory tools
this.server.addTool(memoryTools.memoryStoreTool);
this.server.addTool(memoryTools.memoryRetrieveTool);
this.server.addTool(memoryTools.memorySearchTool);
this.server.addTool(memoryTools.memoryListTool);
this.server.addTool(memoryTools.memoryDeleteTool);
// Swarm tools
this.server.addTool(swarmTools.swarmInitTool);
this.server.addTool(swarmTools.swarmStatusTool);
this.server.addTool(swarmTools.swarmDestroyTool);
// Agent tools
this.server.addTool(agentTools.agentSpawnTool);
this.server.addTool(agentTools.agentListTool);
this.server.addTool(agentTools.agentMetricsTool);
// Task tools
this.server.addTool(taskTools.taskOrchestrateTool);
this.server.addTool(taskTools.taskStatusTool);
this.server.addTool(taskTools.taskResultsTool);
}
}
Flow Nexus Server (HTTP with Auth)
// src/mcp/fastmcp/servers/flow-nexus.ts
import { BaseMCPServer } from './base';
import { authenticateJWT } from '../security/auth';
import { checkRateLimit } from '../security/rate-limit';
import * as sandboxTools from '../tools/sandbox';
import * as neuralTools from '../tools/neural';
import * as githubTools from '../tools/github';
export class FlowNexusServer extends BaseMCPServer {
constructor() {
super({
name: 'flow-nexus',
version: '1.0.0',
transport: {
type: 'http',
port: parseInt(process.env.PORT || '8080'),
host: '0.0.0.0',
enableAuth: true,
enableCORS: true
},
enableAuth: true,
enableMetrics: true,
enableLogging: true
});
}
protected async authenticate(req: Request) {
const auth = await authenticateJWT(req);
// Check rate limit
const allowed = await checkRateLimit(auth.userId);
if (!allowed) {
throw new Response('Rate limit exceeded', { status: 429 });
}
return auth;
}
protected registerTools() {
// Sandbox tools (Pro+ only)
this.server.addTool({
...sandboxTools.sandboxCreateTool,
canAccess: (auth) => ['pro', 'enterprise'].includes(auth.tier)
});
this.server.addTool({
...sandboxTools.sandboxExecuteTool,
canAccess: (auth) => ['pro', 'enterprise'].includes(auth.tier)
});
// Neural tools (All authenticated users)
this.server.addTool(neuralTools.neuralTrainTool);
this.server.addTool(neuralTools.neuralPredictTool);
this.server.addTool(neuralTools.neuralStatusTool);
// GitHub tools (All authenticated users)
this.server.addTool(githubTools.githubAnalyzeTool);
this.server.addTool(githubTools.githubPRManageTool);
// Admin tools (Admin only)
this.server.addTool({
name: 'admin_metrics',
description: 'View system-wide metrics',
canAccess: (auth) => auth.role === 'admin',
parameters: z.object({}),
execute: async () => {
// Return metrics
}
});
}
}
5. Testing Strategy
5.1 Unit Tests
// tests/unit/tools/memory/store.test.ts
import { describe, it, expect, vi } from 'vitest';
import { memoryStoreTool } from '../../../../src/mcp/fastmcp/tools/memory/store';
describe('Memory Store Tool', () => {
it('should store value successfully', async () => {
const result = await memoryStoreTool.execute(
{ key: 'test', value: 'data', namespace: 'default' },
{ onProgress: vi.fn(), auth: undefined }
);
expect(result.success).toBe(true);
expect(result.key).toBe('test');
});
it('should validate input schema', () => {
expect(() => {
memoryStoreTool.parameters.parse({ key: '', value: 'data' });
}).toThrow();
});
it('should report progress', async () => {
const onProgress = vi.fn();
await memoryStoreTool.execute(
{ key: 'test', value: 'data', namespace: 'default' },
{ onProgress, auth: undefined }
);
expect(onProgress).toHaveBeenCalledWith(
expect.objectContaining({ progress: 0.2 })
);
});
});
5.2 Integration Tests
// tests/integration/servers/claude-flow-sdk.test.ts
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { ClaudeFlowSdkServer } from '../../../src/mcp/fastmcp/servers/claude-flow-sdk';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
describe('Claude Flow SDK Server', () => {
let server: ClaudeFlowSdkServer;
let client: any;
beforeAll(async () => {
server = new ClaudeFlowSdkServer();
await server.start();
// Create client
const transport = new StdioClientTransport({
command: 'node',
args: ['dist/mcp/fastmcp/servers/claude-flow-sdk.js']
});
client = await transport.connect();
});
afterAll(async () => {
await server.stop();
});
it('should list available tools', async () => {
const tools = await client.listTools();
expect(tools).toContain('memory_store');
expect(tools).toContain('swarm_init');
});
it('should execute memory_store tool', async () => {
const result = await client.callTool('memory_store', {
key: 'integration-test',
value: 'test-data',
namespace: 'test'
});
expect(result.success).toBe(true);
});
});
5.3 E2E Tests
// tests/e2e/multi-server.test.ts
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { ClaudeFlowSdkServer } from '../../src/mcp/fastmcp/servers/claude-flow-sdk';
import { FlowNexusServer } from '../../src/mcp/fastmcp/servers/flow-nexus';
describe('Multi-Server Coordination', () => {
let sdkServer: ClaudeFlowSdkServer;
let nexusServer: FlowNexusServer;
beforeAll(async () => {
sdkServer = new ClaudeFlowSdkServer();
nexusServer = new FlowNexusServer();
await Promise.all([sdkServer.start(), nexusServer.start()]);
});
afterAll(async () => {
await Promise.all([sdkServer.stop(), nexusServer.stop()]);
});
it('should coordinate swarm initialization', async () => {
// Initialize swarm via SDK
const swarmResult = await sdkClient.callTool('swarm_init', {
topology: 'mesh',
maxAgents: 5
});
// Create sandbox via Nexus
const sandboxResult = await nexusClient.callTool('sandbox_create', {
template: 'node',
name: 'test-sandbox'
});
// Verify coordination
const status = await sdkClient.callTool('swarm_status');
expect(status.agents).toHaveLength(5);
});
});
5.4 Performance Tests
// tests/performance/throughput.test.ts
import { describe, it, expect } from 'vitest';
import { performance } from 'perf_hooks';
describe('Performance Benchmarks', () => {
it('should handle 1000 tool calls within 5 seconds', async () => {
const start = performance.now();
const promises = Array.from({ length: 1000 }, () =>
client.callTool('memory_store', {
key: `perf-${Math.random()}`,
value: 'test-data',
namespace: 'perf'
})
);
await Promise.all(promises);
const duration = performance.now() - start;
expect(duration).toBeLessThan(5000);
console.log(`Throughput: ${(1000 / duration * 1000).toFixed(2)} tools/sec`);
});
it('should maintain low latency under load', async () => {
const latencies: number[] = [];
for (let i = 0; i < 100; i++) {
const start = performance.now();
await client.callTool('swarm_status');
latencies.push(performance.now() - start);
}
const avg = latencies.reduce((a, b) => a + b) / latencies.length;
const p95 = latencies.sort()[Math.floor(latencies.length * 0.95)];
expect(avg).toBeLessThan(50); // 50ms average
expect(p95).toBeLessThan(100); // 100ms p95
console.log(`Avg latency: ${avg.toFixed(2)}ms, P95: ${p95.toFixed(2)}ms`);
});
});
5.5 Security Tests
// tests/security/auth.test.ts
import { describe, it, expect } from 'vitest';
import { FlowNexusServer } from '../../src/mcp/fastmcp/servers/flow-nexus';
describe('Authentication Security', () => {
it('should reject requests without token', async () => {
const response = await fetch('http://localhost:8080/tools/list');
expect(response.status).toBe(401);
});
it('should reject invalid tokens', async () => {
const response = await fetch('http://localhost:8080/tools/list', {
headers: { 'Authorization': 'Bearer invalid-token' }
});
expect(response.status).toBe(401);
});
it('should accept valid tokens', async () => {
const token = generateValidToken();
const response = await fetch('http://localhost:8080/tools/list', {
headers: { 'Authorization': `Bearer ${token}` }
});
expect(response.status).toBe(200);
});
it('should enforce rate limits', async () => {
const token = generateValidToken();
// Make 100 requests (rate limit)
for (let i = 0; i < 100; i++) {
await fetch('http://localhost:8080/tools/list', {
headers: { 'Authorization': `Bearer ${token}` }
});
}
// 101st request should be rate limited
const response = await fetch('http://localhost:8080/tools/list', {
headers: { 'Authorization': `Bearer ${token}` }
});
expect(response.status).toBe(429);
});
});
6. Development & Deployment
6.1 Development Setup
# Install dependencies
npm install fastmcp zod jsonwebtoken redis
# Install dev dependencies
npm install -D @types/jsonwebtoken vitest
# Run in development
npm run dev
# Test FastMCP server
npx fastmcp dev src/mcp/fastmcp/servers/claude-flow-sdk.ts
# Inspect server
npx fastmcp inspect src/mcp/fastmcp/servers/claude-flow-sdk.ts
6.2 Environment Configuration
# .env.development
NODE_ENV=development
DEPLOYMENT_MODE=local
USE_FASTMCP=true
ENABLE_AUTH=false
ENABLE_METRICS=true
LOG_LEVEL=debug
# .env.production
NODE_ENV=production
DEPLOYMENT_MODE=cloud
USE_FASTMCP=true
ENABLE_AUTH=true
ENABLE_METRICS=true
LOG_LEVEL=info
JWT_SECRET=your-secret-key
API_KEY=your-api-key
REDIS_URL=redis://localhost:6379
PORT=8080
6.3 Docker Configuration
# Dockerfile
FROM node:18-alpine
WORKDIR /app
# Install dependencies
COPY package*.json ./
RUN npm ci --only=production
# Copy source
COPY dist ./dist
COPY .env.production ./.env
# Expose ports
EXPOSE 8080
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node -e "require('http').get('http://localhost:8080/health', (r) => r.statusCode === 200 ? process.exit(0) : process.exit(1))"
# Start server
CMD ["node", "dist/mcp/fastmcp/servers/flow-nexus.js"]
# docker-compose.yml
version: '3.8'
services:
# In-process server (not containerized, runs with main app)
# Claude Flow subprocess server
claude-flow:
build: .
command: node dist/mcp/fastmcp/servers/claude-flow.js
environment:
- NODE_ENV=production
- DEPLOYMENT_MODE=docker
- ENABLE_AUTH=false
volumes:
- ./data:/app/data
# Flow Nexus HTTP server
flow-nexus:
build: .
command: node dist/mcp/fastmcp/servers/flow-nexus.js
ports:
- "8080:8080"
environment:
- NODE_ENV=production
- DEPLOYMENT_MODE=cloud
- ENABLE_AUTH=true
- JWT_SECRET=${JWT_SECRET}
- REDIS_URL=redis://redis:6379
- PORT=8080
depends_on:
- redis
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 3s
retries: 3
# Redis for rate limiting
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis-data:/data
volumes:
redis-data:
6.4 Kubernetes Deployment
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: flow-nexus
spec:
replicas: 3
selector:
matchLabels:
app: flow-nexus
template:
metadata:
labels:
app: flow-nexus
spec:
containers:
- name: flow-nexus
image: flow-nexus:latest
ports:
- containerPort: 8080
env:
- name: NODE_ENV
value: "production"
- name: DEPLOYMENT_MODE
value: "cloud"
- name: ENABLE_AUTH
value: "true"
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: flow-nexus-secrets
key: jwt-secret
- name: REDIS_URL
value: "redis://redis-service:6379"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: flow-nexus-service
spec:
type: LoadBalancer
selector:
app: flow-nexus
ports:
- protocol: TCP
port: 80
targetPort: 8080
6.5 CI/CD Pipeline
# .github/workflows/deploy.yml
name: Deploy FastMCP Servers
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm ci
- run: npm run build
- run: npm test
- run: npm run test:integration
- run: npm run test:security
benchmark:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm ci
- run: npm run build
- run: npm run benchmark
- name: Compare performance
run: |
node scripts/compare-benchmarks.js
deploy-staging:
runs-on: ubuntu-latest
needs: [test, benchmark]
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Deploy to staging
run: |
kubectl apply -f k8s/staging/
- name: Run smoke tests
run: npm run test:e2e:staging
deploy-production:
runs-on: ubuntu-latest
needs: deploy-staging
if: github.ref == 'refs/heads/main'
environment: production
steps:
- uses: actions/checkout@v3
- name: Deploy to production
run: |
kubectl apply -f k8s/production/
- name: Run smoke tests
run: npm run test:e2e:production
- name: Monitor rollout
run: kubectl rollout status deployment/flow-nexus
7. Code Examples
7.1 Basic Stdio Server
// examples/stdio-server.ts
import { FastMCP } from 'fastmcp';
import { z } from 'zod';
// Create server
const server = new FastMCP({
name: 'example-stdio-server',
version: '1.0.0'
});
// Add tool with Zod schema
server.addTool({
name: 'calculate',
description: 'Perform basic arithmetic operations',
parameters: z.object({
operation: z.enum(['add', 'subtract', 'multiply', 'divide']),
a: z.number(),
b: z.number()
}),
execute: async ({ operation, a, b }) => {
switch (operation) {
case 'add':
return a + b;
case 'subtract':
return a - b;
case 'multiply':
return a * b;
case 'divide':
if (b === 0) throw new Error('Division by zero');
return a / b;
}
}
});
// Start with stdio transport
server.start({ transportType: 'stdio' });
7.2 HTTP Server with Authentication
// examples/http-server-auth.ts
import { FastMCP } from 'fastmcp';
import { z } from 'zod';
import jwt from 'jsonwebtoken';
// Create server with authentication
const server = new FastMCP({
name: 'secure-http-server',
version: '1.0.0',
authenticate: async (req) => {
const token = req.headers.get('authorization')?.replace('Bearer ', '');
if (!token) {
throw new Response('Missing token', { status: 401 });
}
try {
const payload = jwt.verify(token, process.env.JWT_SECRET!) as any;
return {
userId: payload.sub,
role: payload.role
};
} catch {
throw new Response('Invalid token', { status: 401 });
}
}
});
// Add public tool (no auth required)
server.addTool({
name: 'health',
description: 'Health check endpoint',
parameters: z.object({}),
execute: async () => ({
status: 'healthy',
timestamp: new Date().toISOString()
})
});
// Add authenticated tool with role check
server.addTool({
name: 'admin_action',
description: 'Admin-only action',
canAccess: (auth) => auth.role === 'admin',
parameters: z.object({
action: z.string()
}),
execute: async ({ action }, { auth }) => {
console.log(`Admin ${auth.userId} performed: ${action}`);
return { success: true };
}
});
// Start with HTTP transport
server.start({
transportType: 'http',
port: 8080,
host: '0.0.0.0'
});
7.3 Server with Progress Reporting
// examples/progress-server.ts
import { FastMCP } from 'fastmcp';
import { z } from 'zod';
const server = new FastMCP({
name: 'progress-server',
version: '1.0.0'
});
server.addTool({
name: 'process_data',
description: 'Process large dataset with progress updates',
parameters: z.object({
dataSize: z.number().min(1).max(1000000)
}),
execute: async ({ dataSize }, { onProgress }) => {
const chunks = Math.ceil(dataSize / 1000);
for (let i = 0; i < chunks; i++) {
// Simulate processing
await new Promise(resolve => setTimeout(resolve, 100));
// Report progress
const progress = (i + 1) / chunks;
onProgress?.({
progress,
message: `Processing chunk ${i + 1}/${chunks}`
});
}
return {
processed: dataSize,
chunks,
duration: chunks * 100
};
}
});
server.start({ transportType: 'stdio' });
7.4 Server with Streaming Output
// examples/streaming-server.ts
import { FastMCP } from 'fastmcp';
import { z } from 'zod';
const server = new FastMCP({
name: 'streaming-server',
version: '1.0.0'
});
server.addTool({
name: 'generate_report',
description: 'Generate report with streaming output',
parameters: z.object({
sections: z.array(z.string())
}),
execute: async function* ({ sections }) {
yield '# Report\n\n';
for (const section of sections) {
yield `## ${section}\n\n`;
// Simulate section generation
await new Promise(resolve => setTimeout(resolve, 500));
yield `Content for ${section}...\n\n`;
}
yield '---\nReport complete\n';
}
});
server.start({ transportType: 'http', port: 8080 });
7.5 Multi-Transport Server
// examples/multi-transport.ts
import { FastMCP } from 'fastmcp';
import { z } from 'zod';
function createServer() {
const server = new FastMCP({
name: 'multi-transport-server',
version: '1.0.0'
});
// Add tools...
server.addTool({
name: 'echo',
description: 'Echo a message',
parameters: z.object({ message: z.string() }),
execute: async ({ message }) => message
});
return server;
}
// Determine transport from environment
const transportType = process.env.TRANSPORT_TYPE || 'stdio';
if (transportType === 'stdio') {
const server = createServer();
server.start({ transportType: 'stdio' });
console.error('Started with stdio transport');
} else {
const server = createServer();
server.start({
transportType: 'http',
port: parseInt(process.env.PORT || '8080'),
host: process.env.HOST || '0.0.0.0'
});
console.error(`Started with HTTP transport on ${process.env.PORT || 8080}`);
}
8. Performance Optimization
8.1 Connection Pooling
// src/mcp/fastmcp/utils/connection-pool.ts
export class ConnectionPool {
private connections: Map<string, any> = new Map();
private maxSize: number;
constructor(maxSize = 10) {
this.maxSize = maxSize;
}
async getConnection(key: string, factory: () => Promise<any>) {
if (this.connections.has(key)) {
return this.connections.get(key);
}
if (this.connections.size >= this.maxSize) {
// Evict oldest connection
const firstKey = this.connections.keys().next().value;
const conn = this.connections.get(firstKey);
await conn?.close?.();
this.connections.delete(firstKey);
}
const conn = await factory();
this.connections.set(key, conn);
return conn;
}
async closeAll() {
for (const [key, conn] of this.connections) {
await conn?.close?.();
}
this.connections.clear();
}
}
8.2 Caching Layer
// src/mcp/fastmcp/middleware/cache.ts
import { createHash } from 'crypto';
interface CacheEntry {
value: any;
timestamp: number;
ttl: number;
}
export class ToolCache {
private cache = new Map<string, CacheEntry>();
private getCacheKey(toolName: string, args: any): string {
const hash = createHash('sha256');
hash.update(JSON.stringify({ toolName, args }));
return hash.digest('hex');
}
get(toolName: string, args: any): any | null {
const key = this.getCacheKey(toolName, args);
const entry = this.cache.get(key);
if (!entry) return null;
const now = Date.now();
if (now - entry.timestamp > entry.ttl) {
this.cache.delete(key);
return null;
}
return entry.value;
}
set(toolName: string, args: any, value: any, ttl = 60000) {
const key = this.getCacheKey(toolName, args);
this.cache.set(key, {
value,
timestamp: Date.now(),
ttl
});
}
clear() {
this.cache.clear();
}
}
// Wrap tool execution with caching
export function withCache(cache: ToolCache, ttl?: number) {
return (tool: any) => ({
...tool,
execute: async (args: any, context: any) => {
// Check cache
const cached = cache.get(tool.name, args);
if (cached) {
return cached;
}
// Execute tool
const result = await tool.execute(args, context);
// Store in cache
cache.set(tool.name, args, result, ttl);
return result;
}
});
}
8.3 Request Batching
// src/mcp/fastmcp/utils/batch.ts
export class RequestBatcher {
private pending: Map<string, Promise<any>> = new Map();
private batchDelay: number;
constructor(batchDelay = 10) {
this.batchDelay = batchDelay;
}
async batch<T>(key: string, executor: () => Promise<T>): Promise<T> {
// Check if request with same key is pending
if (this.pending.has(key)) {
return this.pending.get(key);
}
// Create new batch
const promise = new Promise<T>((resolve, reject) => {
setTimeout(async () => {
try {
const result = await executor();
this.pending.delete(key);
resolve(result);
} catch (error) {
this.pending.delete(key);
reject(error);
}
}, this.batchDelay);
});
this.pending.set(key, promise);
return promise;
}
}
9. Monitoring & Observability
9.1 Metrics Collection
// src/mcp/fastmcp/middleware/metrics.ts
import { Counter, Histogram, Registry } from 'prom-client';
export class MetricsCollector {
private registry: Registry;
private toolCallCounter: Counter;
private toolDurationHistogram: Histogram;
private errorCounter: Counter;
constructor() {
this.registry = new Registry();
this.toolCallCounter = new Counter({
name: 'mcp_tool_calls_total',
help: 'Total number of tool calls',
labelNames: ['tool', 'status'],
registers: [this.registry]
});
this.toolDurationHistogram = new Histogram({
name: 'mcp_tool_duration_seconds',
help: 'Tool execution duration',
labelNames: ['tool'],
buckets: [0.001, 0.01, 0.1, 0.5, 1, 5, 10],
registers: [this.registry]
});
this.errorCounter = new Counter({
name: 'mcp_errors_total',
help: 'Total errors',
labelNames: ['tool', 'error_type'],
registers: [this.registry]
});
}
recordToolCall(tool: string, duration: number, success: boolean) {
this.toolCallCounter.inc({ tool, status: success ? 'success' : 'error' });
this.toolDurationHistogram.observe({ tool }, duration);
}
recordError(tool: string, errorType: string) {
this.errorCounter.inc({ tool, error_type: errorType });
}
async getMetrics(): Promise<string> {
return this.registry.metrics();
}
}
// Add metrics endpoint
export function setupMetrics(server: FastMCP) {
const collector = new MetricsCollector();
server.addTool({
name: 'metrics',
description: 'Get Prometheus metrics',
parameters: z.object({}),
execute: async () => {
return await collector.getMetrics();
}
});
return collector;
}
9.2 Distributed Tracing
// src/mcp/fastmcp/middleware/tracing.ts
import { trace, context, SpanStatusCode } from '@opentelemetry/api';
import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
import { JaegerExporter } from '@opentelemetry/exporter-jaeger';
const tracer = trace.getTracer('fastmcp-server');
export function withTracing(tool: any) {
return {
...tool,
execute: async (args: any, ctx: any) => {
const span = tracer.startSpan(`tool.${tool.name}`);
try {
span.setAttributes({
'tool.name': tool.name,
'tool.args': JSON.stringify(args),
'user.id': ctx.auth?.userId
});
const result = await tool.execute(args, ctx);
span.setStatus({ code: SpanStatusCode.OK });
return result;
} catch (error: any) {
span.setStatus({
code: SpanStatusCode.ERROR,
message: error.message
});
span.recordException(error);
throw error;
} finally {
span.end();
}
}
};
}
10. Migration Checklist
10.1 Pre-Migration
- Install fastmcp package
- Review current MCP tool inventory (203+ tools)
- Identify authentication requirements per server
- Plan transport strategy (stdio vs HTTP)
- Setup development environment
- Create feature flag system
- Backup current implementation
- Document current API contracts
10.2 Phase 1: In-Process Server
- Create fastmcp directory structure
- Implement base server class
- Migrate memory tools (5 tools)
- Migrate swarm tools (3 tools)
- Migrate agent tools (3 tools)
- Migrate task tools (3 tools)
- Add error handling
- Add logging integration
- Write unit tests
- Write integration tests
- Performance benchmark
- Code review
- Deploy to development
- Gradual rollout with feature flag
- Monitor for issues
- Full rollout
10.3 Phase 2: Subprocess Servers
- Migrate claude-flow server
- Convert all tools to FastMCP
- Add progress reporting
- Add streaming support
- Optional authentication
- Tests
- Migrate agentic-payments server
- Convert payment tools
- Add transaction streaming
- Authentication
- Tests
- Update subprocess spawning
- Integration tests
- Deploy to development
- Testing period (1 week)
- Production deployment
10.4 Phase 3: HTTP Server
- Implement HTTP streaming transport
- JWT authentication
- API key authentication
- OAuth integration
- Rate limiting with Redis
- Tool authorization
- CORS configuration
- Health-check endpoints
- Session management
- Load testing
- Security audit
- Staging deployment
- Production deployment
10.5 Phase 4: Testing & Validation
- Unit tests (100+ tests)
- Integration tests (30+ tests)
- E2E tests (10+ tests)
- Performance benchmarks
- Security tests
- Load tests
- Chaos testing
- Documentation review
- Migration guide
- Troubleshooting guide
10.6 Phase 5: Documentation & Rollout
- Architecture documentation
- API reference
- Authentication guide
- Security best practices
- Migration guide
- Troubleshooting guide
- Performance tuning guide
- Beta release (10%)
- Expanded rollout (50%)
- Full rollout (100%)
- Deprecate old implementation
11. Risk Assessment & Mitigation
11.1 Technical Risks
| Risk | Probability | Impact | Mitigation |
|---|---|---|---|
| Performance degradation | Low | High | Benchmark before migration, feature flag rollback |
| Authentication vulnerabilities | Medium | Critical | Security audit, penetration testing |
| Tool compatibility issues | Medium | High | Parallel testing, gradual rollout |
| Transport reliability | Low | High | Connection pooling, retry logic, fallback |
| Memory leaks | Low | Medium | Load testing, monitoring, profiling |
| Breaking API changes | Medium | High | Backward compatibility layer, versioning |
11.2 Operational Risks
| Risk | Probability | Impact | Mitigation |
|---|---|---|---|
| Deployment failure | Low | High | Rollback plan, staging testing |
| Downtime during migration | Medium | High | Blue-green deployment, feature flags |
| Training needs | High | Low | Documentation, examples, workshops |
| Support burden | Medium | Medium | Comprehensive docs, troubleshooting guide |
| Third-party dependency | Low | Medium | Pin versions, vendor evaluation |
11.3 Mitigation Strategies
Performance Degradation:
- Benchmark current implementation
- Set performance SLAs (latency, throughput)
- Implement automatic rollback if SLAs breached
- Load testing before production
- Gradual rollout with monitoring
Authentication Security:
- Security audit by external firm
- Penetration testing
- Rate limiting to prevent brute force
- JWT expiration and rotation
- Audit logging for security events
- Regular security reviews
Tool Compatibility:
- Parallel testing (old vs new)
- Schema validation
- Comprehensive test suite
- Gradual migration (tool by tool)
- Fallback to old implementation
Deployment Risks:
- Blue-green deployment
- Feature flags for instant rollback
- Automated rollback triggers
- Staging environment testing
- Canary deployments
12. Success Metrics
12.1 Performance Metrics
Target Improvements:
- Tool invocation latency: < 50ms (p95)
- Throughput: > 1000 tools/sec
- Startup time: < 2 seconds
- Memory usage: < 500MB baseline
- CPU usage: < 50% under load
Current Baseline:
- Measure current performance
- Establish benchmarks
- Set improvement targets
- Monitor regression
12.2 Developer Experience Metrics
- Lines of code reduction: Target 30-40%
- Tool definition time: Target 50% reduction
- Bug density: Target 50% reduction
- Time to add new tool: Target 60% reduction
- Developer satisfaction score: Target 8+/10
12.3 Reliability Metrics
- Uptime: > 99.9%
- Error rate: < 0.1%
- Mean time to recovery: < 5 minutes
- Authentication success rate: > 99%
- Rate limit false positives: < 1%
12.4 Security Metrics
- Authentication failures: < 1% legitimate requests
- Rate limit effectiveness: 100% abuse prevention
- Security incidents: 0
- Audit log completeness: 100%
- Vulnerability response time: < 24 hours
13. Timeline & Resources
13.1 Timeline
Total Duration: 10 weeks
| Phase | Duration | Start | End |
|---|---|---|---|
| Phase 0: Preparation | 1 week | Week 1 | Week 1 |
| Phase 1: In-Process Server | 2 weeks | Week 2 | Week 3 |
| Phase 2: Subprocess Servers | 2 weeks | Week 4 | Week 5 |
| Phase 3: HTTP Server | 2 weeks | Week 6 | Week 7 |
| Phase 4: Testing | 1 week | Week 8 | Week 8 |
| Phase 5: Documentation & Rollout | 2 weeks | Week 9 | Week 10 |
13.2 Resource Requirements
Team:
- 1 Senior Backend Engineer (full-time)
- 1 DevOps Engineer (50%)
- 1 Security Engineer (25%)
- 1 QA Engineer (50%)
- 1 Technical Writer (25%)
Infrastructure:
- Development environment
- Staging environment (identical to production)
- Load testing infrastructure
- Redis for rate limiting
- Monitoring stack (Prometheus, Grafana)
- Tracing infrastructure (Jaeger)
Tools & Services:
- fastmcp npm package
- JWT library (jsonwebtoken)
- Redis client
- Testing framework (vitest)
- Load testing (k6)
- Security scanning tools
13.3 Budget Estimate
- Personnel: $40,000 (10 weeks * combined effort)
- Infrastructure: $2,000 (staging, testing)
- Tools & Services: $500
- Security audit: $5,000
- Contingency (20%): $9,500
- Total: ~$57,000
14. Conclusion
14.1 Summary
This implementation plan provides a comprehensive roadmap for migrating agentic-flow's MCP infrastructure to the fastmcp TypeScript framework. The migration will be executed in five phases over 10 weeks, with each phase building on the previous one.
Key Benefits:
- Simplified Development: Reduced boilerplate, intuitive APIs
- Enhanced Security: Built-in authentication, authorization, rate limiting
- Better Performance: Optimized transport, connection pooling, caching
- Improved Observability: Metrics, tracing, health checks
- Cloud-Ready: HTTP streaming transport for scalable deployments
- Future-Proof: Standardized framework, active community
14.2 Next Steps
- Week 1: Get approval and allocate resources
- Week 1: Setup development environment and POC
- Week 2-3: Begin Phase 1 (in-process server migration)
- Ongoing: Weekly status reviews and risk assessment
- Week 8: Comprehensive testing and validation
- Week 9-10: Documentation and staged rollout
14.3 Long-Term Vision
Post-migration, agentic-flow will have:
- Modern, maintainable MCP server infrastructure
- Flexible transport options (stdio, HTTP)
- Production-ready security features
- Scalable architecture for cloud deployment
- Improved developer experience
- Foundation for future enhancements
14.4 Recommendations
- Start with POC: Validate assumptions before full commitment
- Gradual Rollout: Use feature flags for safe deployment
- Monitor Closely: Set up comprehensive monitoring from day 1
- Document Everything: Maintain migration journal and lessons learned
- Engage Community: Contribute improvements back to fastmcp
- Plan for Scale: Design for 10x growth from the start
15. Appendix
15.1 References
- FastMCP TypeScript: https://github.com/punkpeye/fastmcp
- FastMCP Documentation: https://gofastmcp.com/
- MCP Specification: https://modelcontextprotocol.io/
- MCP TypeScript SDK: https://github.com/modelcontextprotocol/typescript-sdk
- Zod Documentation: https://zod.dev/
15.2 Glossary
- MCP: Model Context Protocol - standardized protocol for AI tool integration
- FastMCP: TypeScript framework for building MCP servers
- Stdio: Standard input/output transport for local communication
- SSE: Server-Sent Events (deprecated in favor of HTTP streaming)
- HTTP Streaming: Bidirectional HTTP transport with optional SSE
- Tool: Executable function exposed via MCP
- Resource: Data source exposed via MCP
- Prompt: Reusable template for LLM interactions
- Transport: Communication mechanism between client and server
- Authentication: Verifying user identity
- Authorization: Controlling access to tools
- Rate Limiting: Preventing abuse through request throttling
15.3 Contact Information
- Project Lead: [Name]
- Tech Lead: [Name]
- Security Lead: [Name]
- DevOps Lead: [Name]
15.4 Change Log
| Version | Date | Changes | Author |
|---|---|---|---|
| 1.0 | 2025-10-03 | Initial plan | Claude |
Document Status: Draft for Review Last Updated: 2025-10-03 Next Review: After Phase 0 completion