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

@orchestree/mcp-sdk

v1.0.0

Published

MCP (Model Context Protocol) server SDK for Orchestree

Readme

@orchestree/mcp-sdk

A production-grade SDK for building servers that implement the Model Context Protocol (MCP). Enable AI models to safely interact with your tools, data sources, and business logic.

Overview

The MCP SDK provides everything you need to expose tools, resources, and prompts to AI models via the Model Context Protocol. Whether you're building a simple tool server or a complex enterprise application, this SDK handles the protocol details so you can focus on your business logic.

Features

  • Tool Registration: Define tools that AI models can call with proper validation
  • Resource Management: Expose files, databases, and APIs as standardized resources
  • Prompt Templates: Create reusable prompts with customizable arguments
  • Multiple Transports: Support for stdio, HTTP, and Server-Sent Events (SSE)
  • MCP Protocol Compliance: Full implementation of MCP v2024-11-05 specification
  • Event System: Built-in events for monitoring and debugging
  • Type Safety: Complete TypeScript definitions included
  • Error Handling: Proper error propagation and validation

Installation

npm install @orchestree/mcp-sdk

Quick Start

Basic Tool Server

const { McpServer } = require('@orchestree/mcp-sdk');

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

// Register a simple tool
server.registerTool('get_weather', {
  description: 'Get current weather for a location',
  parameters: {
    properties: {
      location: { type: 'string' },
      units: { type: 'string', enum: ['celsius', 'fahrenheit'] }
    },
    required: ['location']
  },
  handler: async (args) => {
    const { location, units = 'celsius' } = args;
    // Your weather logic here
    return {
      location,
      temperature: 22,
      units,
      conditions: 'Partly cloudy'
    };
  }
});

// Start the server
server.start({ transport: 'stdio' });

Resource Provider

server.registerResource('file://config.json', {
  description: 'Application configuration',
  mimeType: 'application/json',
  handler: async () => {
    return {
      apiUrl: 'https://api.example.com',
      timeout: 5000,
      retries: 3
    };
  }
});

Prompt Templates

server.registerPrompt('code_review', {
  description: 'Generates a code review prompt',
  arguments: [
    {
      name: 'language',
      description: 'Programming language',
      required: true
    },
    {
      name: 'focus',
      description: 'Review focus area (security, performance, style)',
      required: false
    }
  ],
  handler: async (args) => {
    const { language, focus = 'style' } = args;
    return `Review this ${language} code for ${focus} issues:\n\n{code}`;
  }
});

API Reference

McpServer

Constructor

new McpServer(config)

Parameters:

  • config.name (string, required): Server name
  • config.version (string): Server version (default: "1.0.0")
  • config.modules (string[]): List of module names

registerTool(name, definition)

Register a callable tool.

Parameters:

  • name (string): Tool name
  • definition (object):
    • description (string, required): What the tool does
    • parameters (object): JSON Schema for input validation
      • properties (object): Parameter definitions
      • required (string[]): Required parameter names
    • handler (function, required): Async or sync handler function
    • metadata (object): Optional metadata

Returns: The server instance (for chaining)

Example:

server.registerTool('add_numbers', {
  description: 'Add two numbers together',
  parameters: {
    properties: {
      a: { type: 'number' },
      b: { type: 'number' }
    },
    required: ['a', 'b']
  },
  handler: async (args) => args.a + args.b
});

registerResource(uri, definition)

Register a readable resource.

Parameters:

  • uri (string): Resource URI (e.g., "file://config.json")
  • definition (object):
    • description (string, required): Resource description
    • name (string): Display name
    • mimeType (string): MIME type (default: "text/plain")
    • handler (function, required): Async or sync handler that returns content
    • metadata (object): Optional metadata

Returns: The server instance (for chaining)

Example:

server.registerResource('database://users', {
  description: 'User database connection',
  mimeType: 'application/json',
  handler: async () => {
    const users = await db.getUsers();
    return users;
  }
});

registerPrompt(name, definition)

Register a prompt template.

Parameters:

  • name (string): Prompt name
  • definition (object):
    • description (string, required): Prompt description
    • arguments (array): Prompt arguments
      • name (string): Argument name
      • description (string): Argument description
      • required (boolean): Whether required
    • handler (function, required): Handler that generates prompt
    • metadata (object): Optional metadata

Returns: The server instance (for chaining)

listTools()

Get all registered tools.

Returns: Array of tool definitions

listResources()

Get all registered resources.

Returns: Array of resource definitions

listPrompts()

Get all registered prompts.

Returns: Array of prompt definitions

callTool(name, args)

Execute a registered tool.

Parameters:

  • name (string): Tool name
  • args (object): Tool arguments

Returns: Promise resolving to tool result

readResource(uri)

Read a registered resource.

Parameters:

  • uri (string): Resource URI

Returns: Promise resolving to resource content

getPrompt(name, args)

Get a prompt with resolved arguments.

Parameters:

  • name (string): Prompt name
  • args (object): Prompt arguments

Returns: Promise resolving to prompt content

start(config)

Start the MCP server.

Parameters:

  • config (object):
    • transport ('stdio' | 'sse' | 'http'): Transport type (default: 'stdio')
    • host (string): Host to bind to (default: 'localhost')
    • port (number): Port to bind to (default: 3000)

Returns: Promise that resolves when server starts

Example:

// Start with stdio transport
await server.start({ transport: 'stdio' });

// Start with HTTP
await server.start({ transport: 'http', host: 'localhost', port: 3000 });

// Start with Server-Sent Events
await server.start({ transport: 'sse', host: '0.0.0.0', port: 8080 });

stop()

Stop the running server.

Returns: Promise that resolves when server stops

isRunning()

Check if the server is running.

Returns: boolean

Events

The McpServer extends EventEmitter and emits the following events:

  • server:started - Server has started
  • server:stopped - Server has stopped
  • server:error - Server error occurred
  • tool:registered - Tool was registered
  • tool:executed - Tool was executed
  • tool:error - Tool execution failed
  • resource:registered - Resource was registered
  • resource:read - Resource was read
  • resource:error - Resource read failed
  • prompt:registered - Prompt was registered
  • prompt:generated - Prompt was generated
  • prompt:error - Prompt generation failed

Example:

server.on('tool:executed', (data) => {
  console.log(`Tool "${data.name}" returned:`, data.result);
});

server.on('tool:error', (data) => {
  console.error(`Tool "${data.name}" failed:`, data.error);
});

Utils

Utility functions for building MCP servers:

Utils.textResponse(text)

Create a text response for tools.

handler: async (args) => {
  return Utils.textResponse('Success!');
}

Utils.imageResponse(base64Data, mimeType)

Create an image response for tools.

handler: async (args) => {
  const imageData = await generateImage(args.prompt);
  return Utils.imageResponse(imageData, 'image/png');
}

Utils.validateParameters(args, schema)

Validate tool parameters against a schema.

const validation = Utils.validateParameters(
  { a: 5, b: 'invalid' },
  {
    properties: {
      a: { type: 'number' },
      b: { type: 'number' }
    },
    required: ['a', 'b']
  }
);

if (!validation.valid) {
  console.error('Validation errors:', validation.errors);
}

Complete Example

const { McpServer, Utils } = require('@orchestree/mcp-sdk');

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

// Tool: Calculator
server.registerTool('calculate', {
  description: 'Perform basic arithmetic operations',
  parameters: {
    properties: {
      operation: { type: 'string', enum: ['add', 'subtract', 'multiply', 'divide'] },
      a: { type: 'number' },
      b: { type: 'number' }
    },
    required: ['operation', 'a', 'b']
  },
  handler: async (args) => {
    const { operation, a, b } = args;
    let result;

    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;
      default:
        throw new Error(`Unknown operation: ${operation}`);
    }

    return Utils.textResponse(`${a} ${operation} ${b} = ${result}`);
  }
});

// Resource: Math documentation
server.registerResource('docs://math-operations', {
  description: 'Documentation for available math operations',
  mimeType: 'text/markdown',
  handler: async () => {
    return `# Math Operations\n\n- **add**: Add two numbers\n- **subtract**: Subtract two numbers\n- **multiply**: Multiply two numbers\n- **divide**: Divide two numbers`;
  }
});

// Prompt: Generate math problem
server.registerPrompt('generate_problem', {
  description: 'Generate a math problem for practice',
  arguments: [
    {
      name: 'difficulty',
      description: 'Difficulty level (easy, medium, hard)',
      required: true
    }
  ],
  handler: async (args) => {
    const { difficulty } = args;
    return `Generate a ${difficulty} math problem for the user to solve.`;
  }
});

// Event handling
server.on('tool:executed', (data) => {
  console.log(`[Tool] ${data.name} executed`);
});

server.on('tool:error', (data) => {
  console.error(`[Tool Error] ${data.name}: ${data.error.message}`);
});

// Start the server
server.start({ transport: 'stdio' }).catch(console.error);

// Graceful shutdown
process.on('SIGTERM', () => {
  server.stop().then(() => {
    console.log('Server stopped');
    process.exit(0);
  });
});

Transport Protocols

Stdio (Default)

JSON-RPC messages over standard input/output. Best for local integration.

await server.start({ transport: 'stdio' });

HTTP

RESTful HTTP endpoint for MCP messages.

await server.start({
  transport: 'http',
  host: 'localhost',
  port: 3000
});

POST JSON-RPC messages to http://localhost:3000/

Server-Sent Events (SSE)

Bidirectional communication using HTTP and SSE. Best for web integration.

await server.start({
  transport: 'sse',
  host: 'localhost',
  port: 3000
});

Connect to http://localhost:3000/sse for events.

Error Handling

The SDK provides comprehensive error handling:

server.on('tool:error', (data) => {
  const { name, args, error } = data;
  console.error(`Tool ${name} failed with:`, error.message);
  // Log, alert, or recover
});

server.on('resource:error', (data) => {
  const { uri, error } = data;
  console.error(`Resource ${uri} failed with:`, error.message);
});

server.on('server:error', (error) => {
  console.error('Server error:', error.message);
  // Restart, fallback, or shutdown
});

Best Practices

  1. Validate Input: Use the parameters schema to describe expected inputs
  2. Handle Errors: Always use try-catch in handlers or return error responses
  3. Be Descriptive: Write clear descriptions for tools, resources, and prompts
  4. Monitor Events: Listen to server events for debugging and monitoring
  5. Use TypeScript: Leverage the included type definitions
  6. Test Thoroughly: Test your server with various inputs and error conditions
  7. Document APIs: Keep documentation of your tools and resources updated
  8. Handle Cleanup: Implement proper shutdown procedures

MCP Protocol Compliance

This SDK implements the Model Context Protocol v2024-11-05 specification, including:

  • ✓ Tool definition and execution
  • ✓ Resource provisioning
  • ✓ Prompt templates
  • ✓ Server initialization
  • ✓ JSON-RPC 2.0 messaging
  • ✓ Multiple transport protocols

Troubleshooting

Server won't start

Ensure the port is available and you have permission to bind to it:

lsof -i :3000  # Check port usage

Handler timeout

Set appropriate timeouts for long-running operations:

handler: async (args) => {
  const result = await Promise.race([
    longOperation(args),
    new Promise((_, reject) =>
      setTimeout(() => reject(new Error('Timeout')), 5000)
    )
  ]);
  return result;
}

Type mismatches

Use TypeScript with the included type definitions:

import { McpServer, ToolRegistration } from '@orchestree/mcp-sdk';

const toolDef: ToolRegistration = {
  description: 'My tool',
  handler: async (args) => 'result'
};

License

MIT - See LICENSE file

Support

For issues, questions, or contributions:

  • GitHub: https://github.com/orchestree/orchestree
  • Docs: https://orchestree.ai/developer/mcp-sdk
  • Community: https://discord.gg/orchestree