npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mcpweb-org/sdk

v0.1.15

Published

Official TypeScript/JavaScript SDK for the MCPaaS platform - A wrapper around the official MCP Server using @modelcontextprotocol/sdk

Downloads

81

Readme

MCPaaS TypeScript SDK

The official TypeScript SDK for MCPaaS (Model Context Protocol as a Service) - build, deploy, and monitor MCP servers with automatic analytics and observability.

npm version TypeScript License: MIT

🚀 Ready in 2 minutes - Get your MCP server running with built-in analytics, HTTP routing, API integrations, and comprehensive observability

📚 Table of Contents

🚀 Quick Start

Get running in under 2 minutes:

# 1. Install the SDK
npm install @mcpweb-org/sdk

# 2. Create a new TypeScript project
mkdir my-mcpaas-server
cd my-mcpaas-server
npm init -y
npm install @mcpweb-org/sdk typescript @types/node zod
npx tsc --init

# 3. Create your server file
touch server.ts

Then add this code to server.ts:

import { MCPWeb } from '@mcpweb-org/sdk';
import { z } from 'zod';

// ✨ Create server with automatic analytics
const server = new MCPWeb({
  name: 'my-awesome-server',
  version: '1.0.0',
}, 'your-app-id', 'your-api-key');

// 🛠️ Add a tool in 30 seconds
server.registerTool('greet', {
  title: 'Greeting Tool',
  description: 'Say hello to someone',
  inputSchema: {
    name: z.string().describe('Person to greet'),
    style: z.enum(['formal', 'casual']).default('casual')
  }
}, async ({ name, style }) => {
  const greeting = style === 'formal' 
    ? `Good day, ${name}.` 
    : `Hey ${name}! 👋`;
  
  return {
    content: [{
      type: 'text',
      text: greeting
    }]
  };
});

// 🚀 Start your server
await server.start();
console.log('🎉 Server running! Try calling the greet tool.');

Run it:

# 4. Set environment variables
echo "MCPAAS_API_BASE_URL=https://us-central1-mcpaas-dev.cloudfunctions.net/analytics" > .env
echo "MCPAAS_APP_ID=your-app-id" >> .env
echo "MCPAAS_API_KEY=your-api-key" >> .env

# 5. Start your server
npx tsx server.ts
# or compile and run: npx tsc && node server.js

That's it! Your MCP server is running with built-in analytics, error tracking, and performance monitoring.

📦 Installation

# npm
npm install @mcpweb-org/sdk

# yarn  
yarn add @mcpweb-org/sdk

# pnpm
pnpm add @mcpweb-org/sdk

Requirements:

  • Node.js 18+
  • TypeScript 5.0+ (recommended)

🧩 Core Components

🎯 What Should I Use?

| Component | Use Case | When to Choose | |-----------|----------|----------------| | MCPWeb | Core MCP server with HTTPS/HTTP support | ✅ Always start here - complete MCP server | | MCPWebExpress | Drop-in Express replacement with MCP | ✅ Migrating from Express servers | | AnalyticsClient | Advanced analytics tracking | ✅ Custom metrics and observability | | MCPWebLog | Lightweight logging utility | ✅ Production debugging with toggle | | OpenAPI Parser | Auto-register APIs from schemas | ✅ Bulk API integration from specs | | API Helper | Manual API registration utilities | ✅ Custom API transformations |

✨ Complete Feature Overview

🚀 Core MCP Server (MCPWeb)

  • Full MCP Protocol: Complete implementation of MCP specification
  • HTTP/HTTPS Server: Built-in web server with REST endpoints
  • Transport Support: Works with StreamableHTTP, Stdio, and custom transports
  • Session Management: Automatic session lifecycle tracking and cleanup
  • Built-in Endpoints: /health, /docs, /tools, /resources, /prompts

📊 Advanced Analytics System

  • Flat Schema Design: BigQuery-compatible event structure
  • Comprehensive Tracking: Tools, resources, prompts, sessions, performance
  • Real-time Metrics: Memory usage, CPU, response times, error rates
  • Batch Processing: Efficient data transmission with configurable batching
  • Custom Events: Track your own business metrics and KPIs
  • Retry Logic: Robust error handling with exponential backoff

🌐 OpenAPI Integration Engine

  • Bulk Registration: Register entire API suites from OpenAPI 3.0 specifications
  • Automatic Schema Conversion: OpenAPI schemas → Zod validation schemas
  • Parameter Extraction: Path, query, body, and header parameters automatically mapped
  • Type Safety: Full TypeScript type generation from OpenAPI definitions
  • Authentication Support: Bearer, Basic, API Key, OAuth2 from security schemes
  • Template Variables: Dynamic parameter injection with {{param}} syntax
  • Error Handling: Comprehensive validation and error reporting with retry logic
  • Selective Registration: Filter and register only specific endpoints
  • Remote Loading: Load schemas from URLs, files, or inline definitions

🌐 API Integration Engine

  • HTTP Method Support: GET, POST, PUT, DELETE, PATCH, and 20+ others
  • Template System: Dynamic parameter injection with {{param}} syntax
  • Built-in Functions: {{$now}}, {{$uuid}}, {{$timestamp}}, {{$env.VAR}}
  • Authentication: Bearer, Basic, API Key, OAuth2, Custom headers
  • OpenAPI Parsing: Bulk registration from OpenAPI 3.0 specifications
  • Error Handling: Comprehensive validation and error reporting

Express Integration (MCPWebExpress)

  • Drop-in Replacement: Zero-code migration from Express servers
  • MCP Protocol: Automatic /mcp endpoints for client communication
  • Middleware Support: Full Express.js middleware ecosystem compatibility
  • CORS & Security: Built-in cross-origin and security features
  • Session Cleanup: Automatic transport cleanup on disconnect

🔍 Developer Tools

  • MCPWebLog: Lightweight logging with production toggle
  • Type Safety: Full TypeScript support with Zod validation
  • Error Classes: Structured error handling with custom error types
  • Configuration Schemas: Validated configuration with helpful error messages

🎓 Step-by-Step Tutorials

Tutorial 1: Your First MCP Tool (2 minutes)

import { MCPWeb } from '@mcpweb-org/sdk';
import { z } from 'zod';

// Step 1: Create server
const server = new MCPWeb({
  name: 'tutorial-server',
  version: '1.0.0'
}, process.env.MCPAAS_APP_ID!, process.env.MCPAAS_API_KEY!);

// Step 2: Add a simple tool
server.registerTool('flip-coin', {
  title: 'Coin Flipper',
  description: 'Flip a virtual coin',
  inputSchema: {
    // No inputs needed!
  }
}, async () => {
  const result = Math.random() > 0.5 ? 'heads' : 'tails';
  return {
    content: [{
      type: 'text',
      text: `🪙 Coin flip result: ${result.toUpperCase()}!`
    }]
  };
});

// Step 3: Start server
await server.start();

Tutorial 2: Mounting MCP on Express Server (3 minutes)

import { MCPWeb, MCPWebExpress } from '@mcpweb-org/sdk';

// Step 1: Setup MCP server (from Tutorial 1)
const mcpServer = new MCPWeb({
  name: 'web-server',
  version: '1.0.0'
}, process.env.MCPAAS_APP_ID!, process.env.MCPAAS_API_KEY!);

// Add your MCP tools here...

// Step 2: Mount MCP on Express server
const server = new MCPWebExpress({
  mcpWeb: mcpServer,
  options: {
    port: 3000,
    cors: true,
    json: true
  }
});

// Step 3:(Optional) Add additional custom REST APIs
server.get('/api/flip', async (req, res) => {
  // Call your MCP tool from HTTP!
  const result = Math.random() > 0.5 ? 'heads' : 'tails';
  res.json({ result, timestamp: new Date().toISOString() });
});

server.post('/api/greet', async (req, res) => {
  const { name } = req.body;
  res.json({ message: `Hello ${name}!` });
});

// Step 4: Start server
await server.start();
console.log('🌐 Server running on http://localhost:3000');
console.log('🧪 Try: curl http://localhost:3000/api/flip');

Tutorial 3: External API Integration (5 minutes)

// Step 1: Transform GitHub API into MCP tool
server.registerAPI('github-user', {
  title: 'GitHub User Info',
  description: 'Get GitHub user information',
  inputSchema: {
    username: z.string().describe('GitHub username')
  }
}, {
  method: 'GET',
  url: 'https://api.github.com/users/{{username}}',
  headers: {
    'User-Agent': 'MCPaaS-SDK',
    'Accept': 'application/vnd.github.v3+json'
  }
});

// Step 2: Use weather API with API key
server.registerAPI('weather', {
  title: 'Current Weather',
  description: 'Get current weather for a city',
  inputSchema: {
    city: z.string(),
    units: z.enum(['metric', 'imperial']).default('metric')
  }
}, {
  method: 'GET',
  url: 'https://api.openweathermap.org/data/2.5/weather',
  headers: {
    'Authorization': `Bearer ${process.env.OPENWEATHER_API_KEY}`
  },
  queryParams: {
    q: '{{city}}',
    units: '{{units}}'
  }
});

// Done! Your external APIs are now MCP tools 🎉

Tutorial 4: Advanced Analytics Tracking (3 minutes)

import { MCPWeb, AnalyticsClient } from '@mcpweb-org/sdk';

// Step 1: Setup server with analytics
const server = new MCPWeb({
  name: 'analytics-demo',
  version: '1.0.0'
}, process.env.MCPAAS_APP_ID!, process.env.MCPAAS_API_KEY!);

// Step 2: Get analytics collector
const analytics = server.analyticsCollector;

// Step 3: Add tool with custom analytics
server.registerTool('process-data', {
  title: 'Data Processor',
  description: 'Process and analyze data',
  inputSchema: {
    data: z.array(z.number()),
    algorithm: z.enum(['mean', 'median', 'mode'])
  }
}, async ({ data, algorithm }) => {
  const startTime = Date.now();
  
  // Track custom business metrics
  analytics.trackEvent({
    eventType: 'performance_metric',
    performanceCustomMetricsJson: JSON.stringify({
      inputDataSize: data.length,
      algorithmType: algorithm,
      memoryBefore: process.memoryUsage().heapUsed
    })
  });
  
  // Process data
  let result: number;
  switch (algorithm) {
    case 'mean':
      result = data.reduce((a, b) => a + b, 0) / data.length;
      break;
    case 'median':
      const sorted = [...data].sort((a, b) => a - b);
      result = sorted[Math.floor(sorted.length / 2)];
      break;
    case 'mode':
      const counts = data.reduce((acc, val) => {
        acc[val] = (acc[val] || 0) + 1;
        return acc;
      }, {} as Record<number, number>);
      result = Number(Object.keys(counts).reduce((a, b) => counts[Number(a)] > counts[Number(b)] ? a : b));
      break;
  }
  
  // Track completion with performance data
  const duration = Date.now() - startTime;
  analytics.trackEvent({
    eventType: 'performance_metric',
    performanceCustomMetricsJson: JSON.stringify({
      processingTime: duration,
      memoryAfter: process.memoryUsage().heapUsed,
      efficiency: data.length / duration, // items per ms
      accuracy: 1.0 // assuming 100% accuracy for demo
    })
  });
  
  return {
    content: [{
      type: 'text',
      text: `${algorithm.toUpperCase()} of ${data.length} items: ${result}`
    }]
  };
});

// Step 4: Configure analytics behavior
analytics.configure({
  batchSize: 50,           // Events per batch
  flushInterval: 30000,    // Flush every 30 seconds
  maxEventsInMemory: 1000, // Memory limit
  enabled: true
});

await server.start();

Tutorial 5: Bulk API Registration with OpenAPI (2 minutes)

Register entire API suites instantly using OpenAPI specifications:

import { MCPWeb, OpenAPISchema } from '@mcpweb-org/sdk';

// Step 1: Define or load your OpenAPI schema
const githubAPISchema: OpenAPISchema = {
  openapi: "3.0.0",
  info: {
    title: "GitHub API",
    version: "1.0.0",
    description: "GitHub REST API endpoints for user and repository management"
  },
  servers: [{ 
    url: "https://api.github.com",
    description: "GitHub API v3"
  }],
  paths: {
    "/users/{username}": {
      get: {
        operationId: "getUser",
        summary: "Get user information",
        description: "Fetch detailed information about a GitHub user",
        parameters: [{
          name: "username",
          in: "path",
          required: true,
          description: "The GitHub username to fetch",
          schema: { type: "string" }
        }],
        responses: { 
          "200": { 
            description: "User data retrieved successfully",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    login: { type: "string" },
                    id: { type: "number" },
                    name: { type: "string" },
                    company: { type: "string" },
                    public_repos: { type: "number" }
                  }
                }
              }
            }
          },
          "404": { description: "User not found" }
        }
      }
    },
    "/users/{username}/repos": {
      get: {
        operationId: "getUserRepos", 
        summary: "List user repositories",
        description: "List public repositories for the specified user",
        parameters: [
          {
            name: "username",
            in: "path", 
            required: true,
            description: "GitHub username",
            schema: { type: "string" }
          },
          {
            name: "type",
            in: "query",
            required: false,
            description: "Repository type filter",
            schema: { 
              type: "string", 
              enum: ["all", "owner", "member"],
              default: "all"
            }
          },
          {
            name: "sort",
            in: "query",
            required: false,
            description: "Sort repositories by",
            schema: {
              type: "string",
              enum: ["created", "updated", "pushed", "full_name"],
              default: "updated"
            }
          },
          {
            name: "per_page",
            in: "query",
            required: false,
            description: "Number of results per page (max 100)",
            schema: {
              type: "integer",
              minimum: 1,
              maximum: 100,
              default: 30
            }
          }
        ],
        responses: { 
          "200": { 
            description: "Repository list retrieved successfully",
            content: {
              "application/json": {
                schema: {
                  type: "array",
                  items: {
                    type: "object",
                    properties: {
                      name: { type: "string" },
                      full_name: { type: "string" },
                      description: { type: "string" },
                      private: { type: "boolean" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/repos/{owner}/{repo}/issues": {
      get: {
        operationId: "listRepoIssues",
        summary: "List repository issues",
        description: "List issues in a repository",
        parameters: [
          {
            name: "owner",
            in: "path",
            required: true,
            description: "Repository owner",
            schema: { type: "string" }
          },
          {
            name: "repo",
            in: "path",
            required: true,
            description: "Repository name", 
            schema: { type: "string" }
          },
          {
            name: "state",
            in: "query",
            required: false,
            description: "Issue state filter",
            schema: {
              type: "string",
              enum: ["open", "closed", "all"],
              default: "open"
            }
          }
        ],
        responses: {
          "200": { description: "Issues retrieved successfully" }
        }
      },
      post: {
        operationId: "createRepoIssue",
        summary: "Create repository issue",
        description: "Create a new issue in a repository",
        parameters: [
          {
            name: "owner",
            in: "path",
            required: true,
            schema: { type: "string" }
          },
          {
            name: "repo",
            in: "path",
            required: true,
            schema: { type: "string" }
          }
        ],
        requestBody: {
          required: true,
          description: "Issue details",
          content: {
            "application/json": {
              schema: {
                type: "object",
                required: ["title"],
                properties: {
                  title: {
                    type: "string",
                    description: "Issue title",
                    minLength: 1,
                    maxLength: 256
                  },
                  body: {
                    type: "string",
                    description: "Issue description"
                  },
                  assignees: {
                    type: "array",
                    items: { type: "string" },
                    description: "GitHub usernames to assign"
                  },
                  labels: {
                    type: "array",
                    items: { type: "string" },
                    description: "Labels to apply"
                  }
                }
              }
            }
          }
        },
        responses: {
          "201": { description: "Issue created successfully" }
        }
      }
    }
  },
  components: {
    securitySchemes: {
      githubAuth: {
        type: "http",
        scheme: "bearer",
        description: "GitHub personal access token"
      }
    }
  }
};

// Step 2: Register entire API with one call
console.log('📋 Registering GitHub API endpoints...');
server.registerOpenAPI(githubAPISchema);

// Result: All endpoints automatically become MCP tools!
// ✅ getUser - Get user information with username validation
// ✅ getUserRepos - List repositories with filtering and pagination  
// ✅ listRepoIssues - List issues with state filtering
// ✅ createRepoIssue - Create new issues with full validation
// ✅ Full type safety with Zod validation schemas
// ✅ Automatic parameter extraction and templating
// ✅ Built-in retry logic and error handling

console.log('✅ Registered tools:', server.listTools().map(t => t.name));

Advanced OpenAPI Features

// Load OpenAPI schema from URL
const loadOpenAPIFromURL = async (url: string): Promise<OpenAPISchema> => {
  const response = await fetch(url);
  return await response.json();
};

// Load from Swagger/OpenAPI spec URL
const petStoreSchema = await loadOpenAPIFromURL('https://petstore3.swagger.io/api/v3/openapi.json');
server.registerOpenAPI(petStoreSchema);

// Load from local file
import fs from 'fs';
const localSchema: OpenAPISchema = JSON.parse(fs.readFileSync('./api-spec.json', 'utf-8'));
server.registerOpenAPI(localSchema);

// Selective registration with filtering
const parseAndFilterAPIs = (schema: OpenAPISchema, filter: (path: string, method: string) => boolean) => {
  const parsedAPIs = parseOpenAPISchema(schema);
  return parsedAPIs.filter(api => {
    // Extract path and method from the API config
    const path = api.apiConfig.uri.replace(/https?:\/\/[^\/]+/, '');
    const method = api.apiConfig.method.toLowerCase();
    return filter(path, method);
  });
};

// Only register GET endpoints
const getAPIs = parseAndFilterAPIs(githubAPISchema, (path, method) => method === 'get');
getAPIs.forEach(api => {
  server.registerAPI(api.name, api.toolConfig, api.apiConfig);
});

📋 OpenAPI Integration Guide

The MCPaaS SDK provides comprehensive OpenAPI 3.0 integration, enabling you to register entire API suites as MCP tools with a single function call. This powerful feature transforms any OpenAPI specification into fully-functional, type-safe MCP tools with automatic validation and error handling.

🚀 OpenAPI Quick Start

import { MCPWeb, OpenAPISchema } from '@mcpweb-org/sdk';

// Initialize your MCP server
const server = new MCPWeb(config, appId, apiKey);

// Define your OpenAPI schema
const apiSchema: OpenAPISchema = {
  openapi: "3.0.0",
  info: { title: "User Management API", version: "1.0.0" },
  servers: [{ url: "https://api.myservice.com" }],
  paths: {
    "/users/{id}": {
      get: {
        operationId: "getUser",
        parameters: [{ 
          name: "id", 
          in: "path", 
          required: true, 
          schema: { type: "string" } 
        }],
        responses: { "200": { description: "User found" } }
      }
    }
  }
};

// Register entire API with one line
server.registerOpenAPI(apiSchema);

// ✅ Result: getUser tool is now available with full type safety!

🛠️ Supported OpenAPI Features

✅ Complete HTTP Method Support

  • GET, POST, PUT, DELETE, PATCH: All standard HTTP methods
  • HEAD, OPTIONS, TRACE: Extended method support
  • Request/Response Bodies: JSON, form data, multipart uploads
  • Custom Headers: Authorization, content types, API keys

✅ Advanced Parameter Handling

  • Path Parameters: {id} automatically becomes {{id}} template variables
  • Query Parameters: Full URL query string support with validation
  • Request Bodies: Complex JSON schemas with nested validation
  • Header Parameters: Custom headers and authentication schemes

✅ Schema Validation System

  • Primitive Types: string, number, integer, boolean with constraints
  • Complex Objects: Nested objects, arrays, references ($ref)
  • Enumerations: String and numeric enum validation
  • Format Validation: email, url, date, uuid, and custom formats
  • Constraints: min/max length, value ranges, patterns, required fields

✅ Authentication & Security

  • Bearer Token: Authorization: Bearer {token}
  • API Key: Header, query parameter, or cookie-based authentication
  • Basic Auth: Username/password authentication
  • OAuth2: Full OAuth2 flow support with scopes
  • Custom Security: Flexible header-based authentication schemes

🎯 Production-Ready Examples

E-commerce API Integration

const ecommerceSchema: OpenAPISchema = {
  openapi: "3.0.0",
  info: {
    title: "E-commerce API",
    version: "2.1.0",
    description: "Complete e-commerce backend with products, orders, and customers"
  },
  servers: [
    { url: "https://api.shop.com/v2", description: "Production API" },
    { url: "https://staging-api.shop.com/v2", description: "Staging Environment" }
  ],
  paths: {
    "/products": {
      get: {
        operationId: "listProducts",
        summary: "List products with advanced filtering",
        parameters: [
          {
            name: "category",
            in: "query",
            description: "Filter by product category",
            schema: { 
              type: "string", 
              enum: ["electronics", "clothing", "books", "home"] 
            }
          },
          {
            name: "price_min",
            in: "query",
            description: "Minimum price filter",
            schema: { type: "number", minimum: 0, maximum: 100000 }
          },
          {
            name: "price_max",
            in: "query", 
            description: "Maximum price filter",
            schema: { type: "number", minimum: 0, maximum: 100000 }
          },
          {
            name: "in_stock",
            in: "query",
            description: "Filter by stock availability",
            schema: { type: "boolean", default: true }
          },
          {
            name: "sort",
            in: "query",
            description: "Sort products by field",
            schema: {
              type: "string",
              enum: ["name", "price", "created_at", "popularity"],
              default: "popularity"
            }
          },
          {
            name: "limit",
            in: "query",
            description: "Number of products to return",
            schema: { 
              type: "integer", 
              minimum: 1, 
              maximum: 100, 
              default: 20 
            }
          }
        ],
        responses: {
          "200": {
            description: "Products retrieved successfully",
            content: {
              "application/json": {
                schema: {
                  type: "object",
                  properties: {
                    products: {
                      type: "array",
                      items: { $ref: "#/components/schemas/Product" }
                    },
                    total: { type: "integer" },
                    page: { type: "integer" },
                    total_pages: { type: "integer" }
                  }
                }
              }
            }
          }
        }
      },
      post: {
        operationId: "createProduct",
        summary: "Create new product",
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: { $ref: "#/components/schemas/CreateProductRequest" }
            }
          }
        },
        responses: {
          "201": {
            description: "Product created successfully",
            content: {
              "application/json": {
                schema: { $ref: "#/components/schemas/Product" }
              }
            }
          },
          "400": { description: "Validation error" },
          "401": { description: "Authentication required" }
        }
      }
    },
    "/products/{id}": {
      get: {
        operationId: "getProduct",
        summary: "Get product by ID",
        parameters: [{
          name: "id",
          in: "path",
          required: true,
          description: "Product unique identifier",
          schema: { 
            type: "string", 
            pattern: "^[0-9a-f]{24}$",
            example: "507f1f77bcf86cd799439011"
          }
        }],
        responses: {
          "200": {
            description: "Product retrieved successfully",
            content: {
              "application/json": {
                schema: { $ref: "#/components/schemas/Product" }
              }
            }
          },
          "404": { description: "Product not found" }
        }
      },
      put: {
        operationId: "updateProduct",
        summary: "Update product",
        parameters: [{
          name: "id",
          in: "path",
          required: true,
          schema: { type: "string", pattern: "^[0-9a-f]{24}$" }
        }],
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: { $ref: "#/components/schemas/UpdateProductRequest" }
            }
          }
        },
        responses: {
          "200": { description: "Product updated successfully" },
          "404": { description: "Product not found" }
        }
      },
      delete: {
        operationId: "deleteProduct",
        summary: "Delete product",
        parameters: [{
          name: "id",
          in: "path", 
          required: true,
          schema: { type: "string", pattern: "^[0-9a-f]{24}$" }
        }],
        responses: {
          "204": { description: "Product deleted successfully" },
          "404": { description: "Product not found" }
        }
      }
    },
    "/orders": {
      post: {
        operationId: "createOrder",
        summary: "Create new order",
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: {
                type: "object",
                required: ["customer_id", "items"],
                properties: {
                  customer_id: { 
                    type: "string",
                    description: "Customer identifier"
                  },
                  items: {
                    type: "array",
                    minItems: 1,
                    maxItems: 50,
                    items: {
                      type: "object",
                      required: ["product_id", "quantity"],
                      properties: {
                        product_id: { type: "string" },
                        quantity: { 
                          type: "integer", 
                          minimum: 1, 
                          maximum: 100 
                        },
                        price_override: {
                          type: "number",
                          minimum: 0,
                          description: "Override product price for this order"
                        }
                      }
                    }
                  },
                  shipping_address: {
                    type: "object",
                    required: ["street", "city", "country"],
                    properties: {
                      street: { type: "string", minLength: 1, maxLength: 255 },
                      city: { type: "string", minLength: 1, maxLength: 100 },
                      state: { type: "string", maxLength: 100 },
                      postal_code: { type: "string", maxLength: 20 },
                      country: { 
                        type: "string", 
                        minLength: 2, 
                        maxLength: 2,
                        description: "ISO 3166-1 alpha-2 country code"
                      }
                    }
                  },
                  coupon_code: {
                    type: "string",
                    pattern: "^[A-Z0-9]{4,12}$",
                    description: "Promotional coupon code"
                  }
                }
              }
            }
          }
        },
        responses: {
          "201": { description: "Order created successfully" },
          "400": { description: "Invalid order data" }
        }
      }
    }
  },
  components: {
    schemas: {
      Product: {
        type: "object",
        required: ["id", "name", "price", "category"],
        properties: {
          id: { 
            type: "string",
            description: "Unique product identifier"
          },
          name: { 
            type: "string", 
            minLength: 1, 
            maxLength: 255,
            description: "Product name"
          },
          description: { 
            type: "string", 
            maxLength: 2000,
            description: "Product description"
          },
          price: { 
            type: "number", 
            minimum: 0,
            maximum: 999999.99,
            description: "Product price in USD"
          },
          category: { 
            type: "string",
            enum: ["electronics", "clothing", "books", "home"],
            description: "Product category"
          },
          in_stock: { 
            type: "boolean", 
            default: true,
            description: "Whether product is in stock"
          },
          stock_quantity: {
            type: "integer",
            minimum: 0,
            description: "Available stock quantity"
          },
          tags: {
            type: "array",
            items: { 
              type: "string",
              minLength: 1,
              maxLength: 50
            },
            maxItems: 10,
            uniqueItems: true,
            description: "Product tags for search and categorization"
          },
          images: {
            type: "array",
            items: {
              type: "string",
              format: "uri",
              description: "Image URL"
            },
            maxItems: 10,
            description: "Product image URLs"
          },
          created_at: {
            type: "string",
            format: "date-time",
            description: "Product creation timestamp"
          },
          updated_at: {
            type: "string",
            format: "date-time", 
            description: "Last update timestamp"
          }
        }
      },
      CreateProductRequest: {
        type: "object",
        required: ["name", "price", "category"],
        properties: {
          name: { 
            type: "string", 
            minLength: 1, 
            maxLength: 255 
          },
          description: { 
            type: "string", 
            maxLength: 2000 
          },
          price: { 
            type: "number", 
            minimum: 0,
            maximum: 999999.99
          },
          category: { 
            type: "string",
            enum: ["electronics", "clothing", "books", "home"]
          },
          stock_quantity: {
            type: "integer",
            minimum: 0,
            default: 0
          },
          tags: {
            type: "array",
            items: { 
              type: "string",
              minLength: 1,
              maxLength: 50
            },
            maxItems: 10,
            uniqueItems: true
          }
        }
      },
      UpdateProductRequest: {
        type: "object",
        properties: {
          name: { type: "string", minLength: 1, maxLength: 255 },
          description: { type: "string", maxLength: 2000 },
          price: { type: "number", minimum: 0, maximum: 999999.99 },
          category: { 
            type: "string",
            enum: ["electronics", "clothing", "books", "home"]
          },
          in_stock: { type: "boolean" },
          stock_quantity: { type: "integer", minimum: 0 },
          tags: {
            type: "array",
            items: { type: "string", minLength: 1, maxLength: 50 },
            maxItems: 10,
            uniqueItems: true
          }
        }
      }
    },
    securitySchemes: {
      bearerAuth: {
        type: "http",
        scheme: "bearer",
        bearerFormat: "JWT",
        description: "JWT access token from /auth/login endpoint"
      },
      apiKeyAuth: {
        type: "apiKey",
        in: "header",
        name: "X-API-Key",
        description: "API key for service authentication"
      }
    }
  },
  security: [
    { bearerAuth: [] },
    { apiKeyAuth: [] }
  ]
};

// Register the complete e-commerce API
console.log('🛍️ Registering E-commerce API...');
server.registerOpenAPI(ecommerceSchema);

console.log('✅ Registered Tools:');
server.listTools().forEach(tool => {
  console.log(`  🔧 ${tool.name}: ${tool.description}`);
});

// Result: Complete e-commerce API suite available as MCP tools!
// ✅ listProducts - Advanced product filtering and pagination
// ✅ createProduct - Product creation with validation
// ✅ getProduct - Product retrieval by ID
// ✅ updateProduct - Product updates with partial data
// ✅ deleteProduct - Product deletion
// ✅ createOrder - Complex order creation with items and shipping
// ✅ Full type safety with comprehensive validation
// ✅ Automatic authentication handling

📚 Loading Schemas from Different Sources

From Remote APIs

// Load from public API specifications
const loadRemoteOpenAPI = async (url: string): Promise<OpenAPISchema> => {
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`Failed to fetch OpenAPI spec: ${response.statusText}`);
    }
    return await response.json();
  } catch (error) {
    console.error(`Error loading OpenAPI from ${url}:`, error);
    throw error;
  }
};

// Popular API examples
const APIs = {
  petStore: 'https://petstore3.swagger.io/api/v3/openapi.json',
  github: 'https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json',
  stripe: 'https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json',
  slack: 'https://raw.githubusercontent.com/slackapi/slack-api-specs/master/web-api/slack_web_openapi_v2.json'
};

// Load and register Stripe API
try {
  const stripeSchema = await loadRemoteOpenAPI(APIs.stripe);
  server.registerOpenAPI(stripeSchema);
  console.log('✅ Stripe API registered successfully');
} catch (error) {
  console.error('❌ Failed to load Stripe API:', error.message);
}

// Load multiple APIs in parallel
const loadMultipleAPIs = async () => {
  const results = await Promise.allSettled([
    loadRemoteOpenAPI(APIs.petStore),
    loadRemoteOpenAPI(APIs.github)
  ]);
  
  results.forEach((result, index) => {
    const apiName = Object.keys(APIs)[index];
    if (result.status === 'fulfilled') {
      server.registerOpenAPI(result.value);
      console.log(`✅ ${apiName} API registered`);
    } else {
      console.error(`❌ Failed to load ${apiName} API:`, result.reason);
    }
  });
};

await loadMultipleAPIs();

From Local Files

import fs from 'fs/promises';
import path from 'path';

// Load from JSON file
const loadLocalOpenAPI = async (filePath: string): Promise<OpenAPISchema> => {
  try {
    const content = await fs.readFile(filePath, 'utf-8');
    return JSON.parse(content);
  } catch (error) {
    console.error(`Error loading local OpenAPI file ${filePath}:`, error);
    throw error;
  }
};

// Load from YAML file (requires js-yaml package)
import yaml from 'js-yaml';

const loadOpenAPIYAML = async (filePath: string): Promise<OpenAPISchema> => {
  try {
    const content = await fs.readFile(filePath, 'utf-8');
    return yaml.load(content) as OpenAPISchema;
  } catch (error) {
    console.error(`Error loading YAML OpenAPI file ${filePath}:`, error);
    throw error;
  }
};

// Load from different file formats
const apiPaths = {
  json: './specs/my-api.json',
  yaml: './specs/my-api.yaml',
  remote: 'https://api.example.com/openapi.json'
};

// Batch load with error handling
const loadAllAPIs = async () => {
  for (const [format, apiPath] of Object.entries(apiPaths)) {
    try {
      let schema: OpenAPISchema;
      
      if (format === 'json') {
        schema = await loadLocalOpenAPI(apiPath);
      } else if (format === 'yaml') {
        schema = await loadOpenAPIYAML(apiPath);
      } else {
        schema = await loadRemoteOpenAPI(apiPath);
      }
      
      server.registerOpenAPI(schema);
      console.log(`✅ ${format.toUpperCase()} API loaded from ${apiPath}`);
      
    } catch (error) {
      console.error(`❌ Failed to load ${format} API from ${apiPath}:`, error.message);
      // Continue loading other APIs even if one fails
    }
  }
};

await loadAllAPIs();

🔍 Advanced Filtering and Customization

Selective API Registration

import { parseOpenAPISchema } from '@mcpweb-org/sdk';

// Parse schema without registering
const parsedAPIs = parseOpenAPISchema(ecommerceSchema);

// Filter by HTTP method
const readOnlyAPIs = parsedAPIs.filter(api => 
  api.apiConfig.method.toUpperCase() === 'GET'
);

// Filter by path pattern
const productAPIs = parsedAPIs.filter(api => 
  api.apiConfig.uri.includes('/products')
);

// Filter by operation ID pattern
const userManagementAPIs = parsedAPIs.filter(api => 
  api.name.toLowerCase().includes('user') || 
  api.name.toLowerCase().includes('customer')
);

// Advanced filtering with custom logic
const criticalAPIs = parsedAPIs.filter(api => {
  const isMutating = ['POST', 'PUT', 'DELETE', 'PATCH'].includes(
    api.apiConfig.method.toUpperCase()
  );
  const isUserFacing = api.apiConfig.uri.includes('/users') || 
                       api.apiConfig.uri.includes('/orders');
  const requiresAuth = api.toolConfig.inputSchema.properties?.authorization;
  
  return isMutating && isUserFacing && requiresAuth;
});

// Register filtered APIs
console.log('📋 Registering filtered API subsets...');

readOnlyAPIs.forEach(api => {
  server.registerAPI(api.name, api.toolConfig, api.apiConfig);
  console.log(`✅ Read-only: ${api.name}`);
});

productAPIs.forEach(api => {
  server.registerAPI(api.name, api.toolConfig, api.apiConfig);
  console.log(`✅ Product API: ${api.name}`);
});

API Customization and Enhancement

// Enhanced API registration with custom modifications
const enhanceAPIs = (schemas: OpenAPISchema[], customizations: any[]) => {
  schemas.forEach((schema, index) => {
    const parsedAPIs = parseOpenAPISchema(schema);
    const customization = customizations[index] || {};
    
    parsedAPIs.forEach(api => {
      // Add custom headers
      api.apiConfig.headers = {
        ...api.apiConfig.headers,
        'User-Agent': 'MCPaaS-SDK/2.1.0',
        'X-Client-Version': '1.0.0',
        'X-Request-ID': '{{requestId}}',
        ...customization.headers
      };
      
      // Add authentication
      if (process.env.API_TOKEN) {
        api.apiConfig.headers['Authorization'] = `Bearer ${process.env.API_TOKEN}`;
      }
      
      // Add API key from environment
      if (process.env.API_KEY && customization.apiKeyHeader) {
        api.apiConfig.headers[customization.apiKeyHeader] = process.env.API_KEY;
      }
      
      // Customize timeout based on endpoint
      if (api.apiConfig.uri.includes('/reports') || 
          api.apiConfig.uri.includes('/analytics')) {
        api.apiConfig.timeout = 60000; // 60 seconds for slow endpoints
      } else if (api.apiConfig.method.toUpperCase() === 'GET') {
        api.apiConfig.timeout = 15000; // 15 seconds for read operations
      } else {
        api.apiConfig.timeout = 30000; // 30 seconds for write operations
      }
      
      // Add retry configuration
      api.apiConfig.retryConfig = {
        maxRetries: customization.maxRetries || 3,
        retryDelay: customization.retryDelay || 1000,
        retryOn: [408, 429, 500, 502, 503, 504]
      };
      
      // Add custom validation
      if (customization.additionalValidation) {
        // Extend Zod schema with custom validation
        const originalSchema = api.toolConfig.inputSchema;
        api.toolConfig.inputSchema = originalSchema.refine(
          customization.additionalValidation,
          { message: customization.validationMessage || 'Custom validation failed' }
        );
      }
      
      // Add custom error handling
      if (customization.errorTransform) {
        const originalErrorTransform = api.apiConfig.errorTransform;
        api.apiConfig.errorTransform = (error) => {
          const transformed = customization.errorTransform(error);
          return originalErrorTransform ? originalErrorTransform(transformed) : transformed;
        };
      }
      
      // Register the enhanced API
      server.registerAPI(api.name, api.toolConfig, api.apiConfig);
      console.log(`🔧 Enhanced: ${api.name} with custom settings`);
    });
  });
};

// Apply customizations
const customizations = [
  {
    headers: { 'X-Service': 'ecommerce' },
    apiKeyHeader: 'X-Ecommerce-Key',
    maxRetries: 5,
    retryDelay: 2000,
    additionalValidation: (data: any) => {
      return data.price === undefined || data.price >= 0;
    },
    validationMessage: 'Price must be non-negative',
    errorTransform: (error: any) => ({
      ...error,
      context: 'E-commerce API',
      timestamp: new Date().toISOString()
    })
  }
];

enhanceAPIs([ecommerceSchema], customizations);

🐛 Error Handling & Debugging

Comprehensive Error Management

// Enable detailed logging
process.env.DEBUG = 'mcpaas:openapi,mcpaas:validation,mcpaas:http';

const registerWithErrorHandling = async (schema: OpenAPISchema, schemaName: string) => {
  console.log(`🔄 Registering ${schemaName} API...`);
  
  try {
    // Validate schema first
    if (!schema.openapi || !schema.info || !schema.paths) {
      throw new Error('Invalid OpenAPI schema: missing required fields');
    }
    
    // Check for supported OpenAPI version
    if (!schema.openapi.startsWith('3.0') && !schema.openapi.startsWith('3.1')) {
      console.warn(`⚠️ OpenAPI version ${schema.openapi} may not be fully supported`);
    }
    
    // Register the API
    server.registerOpenAPI(schema);
    
    const registeredTools = server.listTools();
    console.log(`✅ ${schemaName} registered successfully!`);
    console.log(`📊 Total tools: ${registeredTools.length}`);
    
    // Log registered endpoints
    registeredTools
      .filter(tool => tool.name.includes(schemaName.toLowerCase()) || 
                     tool.description?.includes(schemaName))
      .forEach(tool => {
        console.log(`  🔧 ${tool.name}: ${tool.description}`);
      });
      
  } catch (error) {
    console.error(`❌ Failed to register ${schemaName}:`, error.message);
    console.error('📋 Error details:', error);
    
    // Attempt individual API registration for debugging
    try {
      console.log(`🔍 Attempting individual API registration for ${schemaName}...`);
      const parsedAPIs = parseOpenAPISchema(schema);
      
      let successCount = 0;
      let failureCount = 0;
      
      for (const api of parsedAPIs) {
        try {
          server.registerAPI(api.name, api.toolConfig, api.apiConfig);
          console.log(`  ✅ ${api.name}`);
          successCount++;
        } catch (apiError) {
          console.error(`  ❌ ${api.name}: ${apiError.message}`);
          failureCount++;
        }
      }
      
      console.log(`📈 Registration Summary for ${schemaName}:`);
      console.log(`  ✅ Successful: ${successCount}`);
      console.log(`  ❌ Failed: ${failureCount}`);
      
    } catch (parseError) {
      console.error(`❌ Could not parse ${schemaName} schema:`, parseError.message);
    }
  }
};

// Register multiple APIs with comprehensive error handling
const apiRegistrations = [
  { schema: ecommerceSchema, name: 'E-commerce' },
  { schema: await loadRemoteOpenAPI(APIs.petStore).catch(() => null), name: 'PetStore' },
  { schema: await loadLocalOpenAPI('./my-api.json').catch(() => null), name: 'Custom' }
];

for (const registration of apiRegistrations) {
  if (registration.schema) {
    await registerWithErrorHandling(registration.schema, registration.name);
  } else {
    console.warn(`⚠️ Skipping ${registration.name} - schema not available`);
  }
}

Validation and Testing

// Validate APIs before registration
const validateOpenAPISchema = (schema: OpenAPISchema): string[] => {
  const issues: string[] = [];
  
  // Check required fields
  if (!schema.openapi) issues.push('Missing openapi version');
  if (!schema.info?.title) issues.push('Missing API title');
  if (!schema.info?.version) issues.push('Missing API version');
  if (!schema.paths || Object.keys(schema.paths).length === 0) {
    issues.push('No API paths defined');
  }
  
  // Check paths
  Object.entries(schema.paths || {}).forEach(([path, pathItem]) => {
    Object.entries(pathItem || {}).forEach(([method, operation]) => {
      if (typeof operation === 'object' && operation !== null) {
        if (!operation.operationId) {
          issues.push(`Missing operationId for ${method.toUpperCase()} ${path}`);
        }
        if (!operation.responses) {
          issues.push(`Missing responses for ${method.toUpperCase()} ${path}`);
        }
      }
    });
  });
  
  return issues;
};

// Test API registration
const testAPIRegistration = async (schema: OpenAPISchema, schemaName: string) => {
  console.log(`🧪 Testing ${schemaName} API registration...`);
  
  // Validate schema
  const issues = validateOpenAPISchema(schema);
  if (issues.length > 0) {
    console.warn(`⚠️ Schema validation issues for ${schemaName}:`);
    issues.forEach(issue => console.warn(`  - ${issue}`));
  }
  
  // Test parsing
  try {
    const parsedAPIs = parseOpenAPISchema(schema);
    console.log(`✅ Successfully parsed ${parsedAPIs.length} APIs`);
    
    // Test each API configuration
    parsedAPIs.forEach((api, index) => {
      console.log(`  🔧 API ${index + 1}: ${api.name}`);
      console.log(`     Method: ${api.apiConfig.method}`);
      console.log(`     URL: ${api.apiConfig.uri}`);
      console.log(`     Parameters: ${Object.keys(api.toolConfig.inputSchema.properties || {}).length}`);
    });
    
    return true;
  } catch (error) {
    console.error(`❌ Failed to parse ${schemaName} schema:`, error.message);
    return false;
  }
};

// Test before registering
const testResult = await testAPIRegistration(ecommerceSchema, 'E-commerce');
if (testResult) {
  await registerWithErrorHandling(ecommerceSchema, 'E-commerce');
}

🎯 Best Practices

1. Schema Design Guidelines

// ✅ DO: Use clear, descriptive operationIds
{
  "operationId": "getUserProfile",           // Clear and specific
  "summary": "Get user profile information", // Descriptive summary
  "description": "Retrieve detailed profile information for a specific user including preferences and settings"
}

// ❌ DON'T: Use generic or missing operationIds
{
  "operationId": "get1",                     // Too generic
  // Missing summary and description
}

// ✅ DO: Provide comprehensive parameter documentation
"parameters": [{
  "name": "userId",
  "in": "path",
  "required": true,
  "description": "Unique identifier for the user account. Must be a valid ObjectId.",
  "schema": { 
    "type": "string",
    "pattern": "^[0-9a-f]{24}$",
    "example": "507f1f77bcf86cd799439011"
  }
}]

// ✅ DO: Define detailed response schemas
"responses": {
  "200": {
    "description": "User profile retrieved successfully",
    "content": {
      "application/json": {
        "schema": {
          "type": "object",
          "required": ["id", "email", "name"],
          "properties": {
            "id": { "type": "string" },
            "email": { "type": "string", "format": "email" },
            "name": { "type": "string", "minLength": 1 },
            "preferences": { "$ref": "#/components/schemas/UserPreferences" }
          }
        }
      }
    }
  },
  "404": {
    "description": "User not found",
    "content": {
      "application/json": {
        "schema": { "$ref": "#/components/schemas/Error" }
      }
    }
  }
}

2. Performance Optimization

// ✅ DO: Implement efficient batch operations
const registerMultipleAPIsEfficiently = async (schemas: OpenAPISchema[]) => {
  // Parse all schemas first
  const allParsedAPIs = schemas.flatMap(schema => {
    try {
      return parseOpenAPISchema(schema);
    } catch (error) {
      console.error(`Failed to parse schema:`, error.message);
      return [];
    }
  });
  
  // Group by base URL for connection pooling
  const apisByBaseUrl = allParsedAPIs.reduce((groups, api) => {
    const baseUrl = api.apiConfig.uri.split('/').slice(0, 3).join('/');
    if (!groups[baseUrl]) groups[baseUrl] = [];
    groups[baseUrl].push(api);
    return groups;
  }, {} as Record<string, typeof allParsedAPIs>);
  
  // Register APIs grouped by base URL
  for (const [baseUrl, apis] of Object.entries(apisByBaseUrl)) {
    console.log(`🔗 Registering ${apis.length} APIs for ${baseUrl}...`);
    
    // Set shared connection settings for APIs from same base URL
    const sharedConfig = {
      timeout: 30000,
      retryConfig: { maxRetries: 3, retryDelay: 1000 },
      headers: { 'User-Agent': 'MCPaaS-SDK/2.1.0' }
    };
    
    apis.forEach(api => {
      api.apiConfig = { ...api.apiConfig, ...sharedConfig };
      server.registerAPI(api.name, api.toolConfig, api.apiConfig);
    });
    
    console.log(`✅ Registered ${apis.length} APIs for ${baseUrl}`);
  }
};

3. Security Best Practices

// ✅ DO: Implement comprehensive security
const secureAPIRegistration = (schema: OpenAPISchema, credentials: any) => {
  const parsedAPIs = parseOpenAPISchema(schema);
  
  parsedAPIs.forEach(api => {
    // Add authentication headers
    api.apiConfig.headers = {
      ...api.apiConfig.headers,
      'Authorization': `Bearer ${credentials.token}`,
      'X-API-Key': credentials.apiKey,
      'X-Client-ID': credentials.clientId
    };
    
    // Add request/response interceptors for security
    api.apiConfig.requestInterceptor = (config) => {
      // Add timestamp and nonce for request signing
      config.headers['X-Timestamp'] = Date.now().toString();
      config.headers['X-Nonce'] = Math.random().toString(36);
      
      // Log sensitive operations
      if (['POST', 'PUT', 'DELETE'].includes(config.method.toUpperCase())) {
        console.log(`🔒 Secure operation: ${config.method} ${config.url}`);
      }
      
      return config;
    };
    
    api.apiConfig.responseInterceptor = (response, error) => {
      // Sanitize sensitive data from error messages
      if (error && error.response?.data?.message) {
        error.response.data.message = error.response.data.message.replace(
          /api[_-]?key|token|secret|password/gi,
          '[REDACTED]'
        );
      }
      
      return error ? Promise.reject(error) : response;
    };
    
    // Rate limiting configuration
    api.apiConfig.rateLimitConfig = {
      maxRequests: 100,
      windowMs: 60000, // 1 minute
      skipSuccessfulRequests: false
    };
    
    server.registerAPI(api.name, api.toolConfig, api.apiConfig);
  });
};

This comprehensive OpenAPI integration system makes the MCPaaS SDK incredibly powerful for API management and integration. You can now register entire API suites with full type safety, validation, and professional-grade error handling!


## Installation

```bash
npm install @mcpaas/sdk
# or
yarn add @mcpaas/sdk

Core Concepts

MCPWeb

The main server class that replaces the official MCP SDK:

import { MCPWeb } from '@mcpaas/sdk';

const server = new MCPWeb(
  {
    name: 'my-server',
    version: '1.0.0'
  },
  'app-id',     // Your MCPaaS app ID
  'api-key'     // Your MCPaaS API key
);

MCPWebExpress

Drop-in replacement for Express servers with full MCP support. MCPWebExpress mounts MCP over Express, giving you all the Express functionality you know with automatic MCP protocol integration:

import { MCPWebExpress } from '@mcpaas/sdk';

const server = new MCPWebExpress({
  mcpWeb: mcpServer,  // Your MCPWeb instance
  options: {
    port: 3000,
    host: 'localhost',
    cors: true,
    json: true
  }
});

// Express.js-style routing
server.get('/api/users', (req, res) => {
  res.json([{ id: 1, name: 'John' }]);
});

server.post('/api/users', (req, res) => {
  res.json({ message: 'User created', data: req.body });
});

// Start the server
await server.start();

MCPWebExpress Features:

  • 🚀 Drop-in Express Replacement: Seamlessly replace your existing Express servers
  • 🛣️ Full Express Compatibility: All Express.js routing and middleware works as expected
  • 🔌 MCP Integration: Automatic MCP protocol endpoints mounted on your Express server
  • 🌐 CORS Support: Built-in cross-origin resource sharing
  • 📝 JSON Parsing: Automatic request body parsing
  • 🏥 Health Checks: Built-in /health and /status endpoints
  • Middleware Support: Complete Express.js middleware ecosystem compatibility

MCPWebLog

Lightweight logging utility with toggle capability:

import { MCPWebLog } from '@mcpaas/sdk';

const logger = new MCPWebLog({ disable: false });

logger.log('Server started');
logger.log('Processing request:', requestData);

MCPWebLog Features:

  • 🔇 Toggle Logging: Enable/disable logging globally
  • 🎯 Simple API: Familiar console.log-style interface
  • 📊 Performance: Minimal overhead when disabled
  • 🔧 Debug Mode: Perfect for development vs production

RegisterAPI Method

Transform any HTTP API into an MCP tool with automatic integration:

// Register external APIs as MCP tools
server.registerAPI('weather-api', {
  title: 'Weather API',
  description: 'Get current weather data',
  inputSchema: {
    city: z.string().describe('City name'),
    units: z.enum(['metric', 'imperial']).optional()
  }
}, {
  method: 'GET',
  url: 'https://api.openweathermap.org/data/2.5/weather',
  headers: {
    'Authorization': `Bearer ${API_KEY}`
  },
  queryParams: {
    q: '{{city}}',        // Template from input
    units: '{{units}}'
  }
});

// Register internal APIs
server.registerAPI('user-service', {
  title: 'User Management',
  description: 'Create new user account',
  inputSchema: {
    name: z.string(),
    email: z.string().email()
  }
}, {
  method: 'POST',
  url: 'http://localhost:8080/api/users',
  headers: {
    'Content-Type': 'application/json'
  },
  body: {
    name: '{{name}}',
    email: '{{email}}',
    created_at: '{{$now}}'  // Built-in template functions
  }
});

RegisterAPI Features:

  • 🌐 Any HTTP API: Support for GET, POST, PUT, DELETE, PATCH
  • 📝 Template System: Dynamic parameter injection with {{param}}
  • 🔧 Built-in Functions: {{$now}}, {{$uuid}}, {{$timestamp}}
  • 🛡️ Type Safety: Full TypeScript validation for inputs and outputs
  • 📊 Auto Analytics: Automatic performance tracking and error monitoring
  • 🔁 Retry Logic: Built-in retry mechanisms for failed requests
  • 🏷️ Header Support: Custom headers, authentication, content types

SDK Usage (Legacy API Client)

For platform management operations:

import { MCPaaSClient } from '@mcpaas/sdk/client';

const client = new MCPaaSClient({
  apiKey: 'your-api-key',
  baseUrl: 'https://api.mcpaas.dev', // Optional, defaults to production
  timeout: 30000 // Optional, defaults to 10 seconds
});

Tool Registration

Register tools with automatic analytics tracking:

server.registerTool('tool-name', toolConfig, async (args) => {
  // Your tool implementation
  // Analytics automatically tracked:
  // - Execution time
  // - Input/output sizes
  // - Success/failure
  // - Memory usage
  return { content: [{ type: 'text', text: 'response' }] };
});

Resource Registration

Register resources with access pattern tracking:

server.registerResource('resource-name', 'resource://uri', resourceConfig, async () => {
  // Analytics tracked:
  // - Access frequency
  // - Response sizes
  // - Cache effectiveness
  return { content: 'resource data' };
});

Prompt Registration

Register prompts with generation analytics:

server.registerPrompt('prompt-name', promptConfig, async (args) => {
  // Analytics tracked:
  // - Generation time
  // - Template complexity
  // - Usage patterns
  return { messages: [...] };
});

Analytics Overview

Analytics are automatically collected for every operation:

// Get analytics collector for custom tracking
const analytics = server.analyticsCollector;

// Track custom metrics
analytics.trackPerformance({
  customMetrics: {
    databaseQueries: 5,
    cacheHitRate: 0.85
  }
});

// Track tool execution manually
const eventId = analytics.trackToolStart('custom-tool');
// ... perform work ...
analytics.trackToolComplete(eventId, 'custom-tool', {
  customMetrics: { accuracy: 0.95 }
});

Examples

Complete MCPWebExpress Server

import { MCPWeb, MCPWebExpress } from '@mcpaas/sdk';
import { z } from 'zod';

// Setup MCPaaS server with tools and resources
const setupMCPServer = () => {
  const mcpWeb = new MCPWeb({
    name: "mcpaas-express-server",
    description: "High-performance server with MCPWebExpress",
    version: "1.0.0",
    capabilities: {
      tools: true,
      resources: true,
      prompts: true,
    },
  }, 'your-app-id', 'your-api-key');

  // Register calculation tool
  mcpWeb.registerTool('calculate', {
    title: 'Calculator',
    description: 'Perform arithmetic calculations',
    inputSchema: {
      operation: z.enum(['add', 'subtract', 'multiply', 'divide']),
      a: z.number(),
      b: z.number(),
    },
  }, async ({ operation, a, b }) => {
    let result: number;
    switch (operation) {
      case 'add': result = a + b; break;
      case 'subtract': result = a - b; break;
      case 'multiply': result = a * b; break;
      case 'divide': 
        if (b === 0) throw new Error('Division by zero');
        result = a / b; 
        break;
    }

    return {
      content: [{
        type: 'text',
        text: `${a} ${operation} ${b} = ${result}`,
      }],
    };
  });

  // Register weather API as MCP tool
  mcpWeb.registerAPI('weather', {
    title: 'Weather API',
    description: 'Get current weather',
    inputSchema: {
      city: z.string().describe('City name'),
      units: z.enum(['metric', 'imperial']).default('metric')
    }
  }, {
    method: 'GET',
    url: 'https://api.openweathermap.org/data/2.5/weather',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    },
    queryParams: {
      q: '{{city}}',
      units: '{{units}}'
    }
  });

  return mcpWeb;
};

// Create MCPWebExpress server
const server = new MCPWebExpress({
  mcpWeb: setupMCPServer(),
  options: {
    port: 3000,
    host: 'localhost',
    cors: true,
    json: true
  }
});

// Add REST API routes
server.get('/api/users', (req, res) => {
  res.json([
    { id: 1, name: 'John Doe', email: '[email protected]' },
    { id: 2, name: 'Jane Smith', email: '[email protected]' }
  ]);
});

server.post('/api/users', (req, res) => {
  const { name, email } = req.body;
  const newUser = { id: Date.now(), name, email };
  res.json({ message: 'User created', user: newUser });
});

// Add middleware for logging
server.use('/api', (req, res, next) => {
  console.log(`${new Date().toISOString()} ${req.method} ${req.path}`);
  next();
});

// Start server
await server.start();
console.log('🚀 MCPWebExpress server running on http://localhost:3000');

MCPWebLog Usage Example

import { MCPWebLog } from '@mcpaas/sdk';

// Create logger (disable in production)
const logger = new MCPWebLog({ 
  disable: process.env.NODE_ENV === 'production' 
});

// Use throughout your application
logger.log('Server starting...');
logger.log('Processing request:', { userId: 123, action: 'login' });
logger.log('Database connected successfully');

// Conditional logging
if (process.env.DEBUG) {
  const debugLogger = new MCPWebLog({ disable: false });
  debugLogger.log('Debug information:', complexObject);
}

RegisterAPI Advanced Examples

// GitHub API integration
server.registerAPI('github-repos', {
  title: 'GitHub Repositories',
  description: 'Get user repositories from GitHub',
  inputSchema: {
    username: z.string(),
    type: z.enum(['all', 'public', 'private']).default('public'),
    sort: z.enum(['created', 'updated', 'pushed', 'full_name']).default('updated')
  }
}, {
  method: 'GET',
  url: 'https://api.github.com/users/{{username}}/repos',
  headers: {
    'Accept': 'application/vnd.github.v3+json',
    'User-Agent': 'MCPaaS-SDK'
  },
  queryParams: {
    type: '{{type}}',
    sort: '{{sort}}',
    per_page: '50'
  }
});

// Internal microservice with authentication
server.registerAPI('user-profile', {
  title: 'User Profile Service',
  description: 'Update user profile information',
  inputSchema: {
    userId: z.string(),
    name: z.string().optional(),
    email: z.string().email().optional(),
    avatar: z.string().url().optional()
  }
}, {
  method: 'PATCH',
  url: 'http://user-service:8080/api/users/{{userId}}',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer {{$env.USER_SERVICE_TOKEN}}',
    'X-Request-ID': '{{$uuid}}'
  },
  body: {
    name: '{{name}}',
    email: '{{email}}',
    avatar: '{{avatar}}',
    updated_at: '{{$now}}',
    updated_by: 'mcpaas-sdk'
  }
});

// Database API with custom error handling
server.registerAPI('database-query', {
  title: 'Database Query',
  description: 'Execute SQL queries safely',
  inputSchema: {
    table: z.string(),
    filters: z.record(z.any()).optional(),
    limit: z.number().max(1000).default(100)
  }
}, {
  method: 'POST',
  url: 'http://db-proxy:3000/query',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': '{{$env.DB_API_KEY}}'
  },
  body: {
    query: 'SELECT * FROM {{table}} {{#if filters}}WHERE {{filters}} {{/if}}LIMIT {{limit}}',
    timestamp: '{{$timestamp}}'
  },
  timeout: 30000,
  retries: 3
});

Basic Calculator Tool

import { MCPWeb } from '@mcpaas/sdk';

const server = new MCPWeb({
  name: 'calculator',
  version: '1.0.0'
}, 'app-id', 'api-key');

server.registerTool('add', {
  title: 'Add Numbers',
  description: 'Add two numbers together',
  inputSchema: {
    a: z.number().describe('First number'),
    b: z.number().describe('Second number')
  }
}, async ({ a, b }) => {
  const result = a + b;
  return {
    content: [{
      type: 'text',
      text: `${a} + ${b} = ${result}`
    }]
  };
});

await server.start();

Database Resource

import { MCPServer } from '@mcpaas/sdk';

const server = new MCPServer({
  name: 'database-server',
  version: '1.0.0'
}, 'app-id', 'api-key');

server.registerResource('users', 'db://users', {
  name: 'users',
  description: 'User database',
  mimeType: 'application/json'
}, async () => {
  const users = await fetchUsersFromDatabase();
  return {
    content: JSON.stringify(users),
    mimeType: 'application/json'
  };
});

server.start();

Custom Analytics

import { MCPServer } from '@mcpaas/sdk';

const server = new MCPServer({
  name: 'ai-service',
  version: '1.0.0'
}, 'app-id', 'api-key');

ser