Sandbox
@profullstack/mcp-server

MCP server framework for modular tools and resources

This repository provides a modular JavaScript server for the Model Context Protocol. It loads modules dynamically, serves standard MCP endpoints, and connects to model providers and module resources through a shared API.

45 stars6 forksJavaScriptUpdated 27d ago
Who it's for

Builders who want a reusable MCP server they can extend with their own modules.

What it delivers

You can stand up an MCP server and add new tools or resources without wiring each one from scratch.

What it does

Dynamic module loading

Loads modules at runtime so you can add or remove capabilities without rewriting the server.

Standard MCP endpoints

Implements routes for server info, models, inference, module lookup, tools, and resources.

Model provider support

Connects to OpenAI, Stability AI, Anthropic, and Hugging Face for text, image, and speech tasks.

Module search and metadata

Searches installed modules by package.json fields and returns metadata in API responses.

Module template and generator

Includes a module template and `pnpm create-module` for starting new modules quickly.

Testing and deployment support

Ships with Mocha/Chai tests, Docker files, and service scripts for local and hosted runs.

How to get it

  1. 1Run
    # Clone the repository
    git clone https://github.com/yourusername/mcp-server.git
    cd mcp-server
    
    # Install dependencies
    pnpm install
  2. 2Run
    # Install dependencies
    pnpm install
    
    # Start the server
    pnpm start
    
    # Start the server in development mode (with auto-reload)
    pnpm dev
  3. 3Copy the sample environment file and edit it with your API keys
    # Copy the sample environment file
    cp sample.env .env
    
    # Edit the file with your favorite editor
    nano .env
  4. 4At minimum, you'll need to add API keys for the model providers you want to use
    # OpenAI API (for GPT-4 and Whisper)
    OPENAI_API_KEY=your_openai_api_key_here
    
    # Stability AI API (for Stable Diffusion)
    STABILITY_API_KEY=your_stability_api_key_here
    
    # Anthropic API (for Claude models)
    ANTHROPIC_API_KEY=your_anthropic_api_key_here
  5. 5The repository includes comprehensive testing using Mocha and Chai
    # Run all tests
    pnpm test
    
    # Run only module tests
    pnpm test:modules
    
    # Run all tests (both core and modules)
    pnpm test:all
  6. 6The repository includes pre-commit hooks using Husky and lint-staged
    # The hooks are automatically installed when you run
    pnpm install

README

MCP Server (Model Context Protocol)

Node

A generic, modular server for implementing the Model Context Protocol (MCP). This server provides a framework for controlling and interacting with various models through a standardized API.

Crypto Payment

Hosted deployment

A hosted deployment is available on Fronteir AI.

Features

  • Modular architecture for easy extension
  • Dynamic module loading
  • Core model management functionality
  • Standardized API for model context
  • Simple configuration system
  • Logging utilities
  • Enhanced module structure with proper separation of concerns
  • Package.json support for modules with dependency management
  • Comprehensive testing infrastructure with Mocha and Chai
  • Powerful module search functionality
  • Module metadata display in API responses
  • Integration with real AI model providers (OpenAI, Stability AI, Anthropic, Hugging Face)
  • Support for text generation, image generation, and speech-to-text models
  • Streaming inference support for compatible models

Getting Started

Prerequisites

  • Node.js 18.x or higher
  • pnpm 10.x or higher

This project uses ES Modules (ESM) exclusively. All imports use the import syntax rather than require().

Installation

# Clone the repository
git clone https://github.com/yourusername/mcp-server.git
cd mcp-server

# Install dependencies
pnpm install

Running the Server

# Install dependencies
pnpm install

# Start the server
pnpm start

# Start the server in development mode (with auto-reload)
pnpm dev

The server will start on http://localhost:3000 by default.

Configuration

Copy the sample environment file and edit it with your API keys:

# Copy the sample environment file
cp sample.env .env

# Edit the file with your favorite editor
nano .env

At minimum, you'll need to add API keys for the model providers you want to use:

# OpenAI API (for GPT-4 and Whisper)
OPENAI_API_KEY=your_openai_api_key_here

# Stability AI API (for Stable Diffusion)
STABILITY_API_KEY=your_stability_api_key_here

# Anthropic API (for Claude models)
ANTHROPIC_API_KEY=your_anthropic_api_key_here

You can get these API keys from:

Security

The server has no global authentication layer, so anything that can reach the port can call any module route. Modules that touch the filesystem or issue outbound requests are constrained as follows.

Module tokens. Routes with side effects accept a token via Authorization: Bearer <token> or X-API-Key: <token>. When the variable is unset the routes stay open and a warning is logged at startup.

VariableGuards
SCANNER_API_TOKEN/scanner/scan, /scanner/reports/:id/export, /tools/scanner
README_BADGES_API_TOKEN/readme-badges/update, /readme-badges/detect, /tools/readme-badges

Path containment. readme-badges resolves readmePath and rootDir against README_BADGES_ROOT (default: the working directory) and refuses anything that escapes it, targets a non-markdown file, or reaches outside via a symlink. scanner confines exports to its reports directory the same way.

Outbound request allowlists. Modules that fetch caller-named URLs reject loopback, link-local (cloud metadata), RFC1918, CGNAT and other non-public addresses, resolve hostnames and check every returned address, and re-validate each redirect hop. Where a module talks to one known service, the host is also allowlisted:

VariableExtends the allowlist for
CONVERT2DOC_ALLOWED_HOSTSconvert2doc baseUrl (default: convert2doc.com)
CRAIGSLIST_ALLOWED_HOSTS/craigslist/details (default: *.craigslist.org)

Cross-origin requests. CSRF_PROTECTION_ENABLED (default true) rejects state-changing requests that carry a foreign Origin header, so a malicious web page cannot drive a browser at a localhost-bound server. Clients that send no Origin — curl, MCP clients, server-to-server calls — are unaffected. List trusted browser origins in CORS_ORIGINS.

Run the server behind an authenticating reverse proxy if it is exposed beyond localhost.

Testing the Server

The repository includes comprehensive testing using Mocha and Chai:

# Run all tests
pnpm test

# Run only module tests
pnpm test:modules

# Run all tests (both core and modules)
pnpm test:all

The testing infrastructure includes:

  1. Core server tests for module loading, routing, and other core functionality
  2. Module-specific tests for each module's functionality
  3. Support for ES modules in tests
  4. Mocking and stubbing utilities with Sinon

Tests are organized in a structured way:

  • Core tests in /test/core/
  • Module tests in each module's test/ directory

This comprehensive testing ensures code quality and makes it easier to detect regressions when making changes.

Pre-commit Hooks

The repository includes pre-commit hooks using Husky and lint-staged:

# The hooks are automatically installed when you run
pnpm install

The pre-commit hooks:

  1. Run ESLint on JavaScript files
  2. Run Prettier on all staged files

This ensures that all code committed to the repository follows coding standards and maintains code quality. The test suite is continuously being improved to provide better coverage and reliability, and will be enabled in the pre-commit hook once it's more stable.

Docker Support

The repository includes Docker support for easy containerization and deployment:

# Build and run with Docker
docker build -t mcp-server .
docker run -p 3000:3000 mcp-server

# Or use Docker Compose
docker-compose up

The Docker configuration:

  • Uses Node.js 20 Alpine as the base image
  • Exposes port 3000
  • Mounts the modules directory as a volume for easy module management
  • Includes health checks

Standard MCP Methods

The MCP server implements a standardized set of methods that all MCP servers should provide:

Server Information

  • GET / - Basic server information
  • GET /status - Detailed server status
  • GET /health - Health check endpoint
  • GET /metrics - Server metrics

Model Management

  • GET /models - List available models
  • GET /model/:modelId - Get model information
  • POST /model/:modelId/activate - Activate a specific model
  • POST /model/deactivate - Deactivate the current model
  • GET /model/active - Get information about the active model

Inference

  • POST /model/infer - Perform inference with the active model
  • POST /model/:modelId/infer - Perform inference with a specific model

Supported Models

The MCP server supports the following model types:

Model TypeProviderCapabilitiesExample IDs
GPT ModelsOpenAIText generationgpt-4, gpt-3.5-turbo
WhisperOpenAISpeech-to-textwhisper, whisper-1
Stable DiffusionStability AIImage generationstable-diffusion-xl-1024-v1-0
Claude ModelsAnthropicText generationclaude-3-opus, claude-3-sonnet
Custom ModelsHugging FaceVarious(any Hugging Face model ID)

Inference Examples

Text generation with GPT-4:

# Activate the model
curl -X POST http://localhost:3000/model/gpt-4/activate \
  -H "Content-Type: application/json" \
  -d '{"config": {"temperature": 0.7}}'

# Perform inference
curl -X POST http://localhost:3000/model/infer \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Explain quantum computing in simple terms",
    "temperature": 0.5,
    "max_tokens": 200
  }'

Image generation with Stable Diffusion:

# Activate the model
curl -X POST http://localhost:3000/model/stable-diffusion/activate \
  -H "Content-Type: application/json" \
  -d '{}'

# Generate an image
curl -X POST http://localhost:3000/model/infer \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A beautiful sunset over mountains",
    "height": 1024,
    "width": 1024,
    "steps": 30
  }'

Streaming text generation:

# Enable streaming
curl -X POST http://localhost:3000/model/infer \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Write a short story about a robot",
    "stream": true
  }'

Module Management

  • GET /modules - List installed modules
  • GET /modules/:moduleId - Get module information
  • GET /modules/search/:query - Search modules by any field in their package.json or metadata

Tools and Resources

  • GET /tools - List available tools
  • GET /resources - List available resources

For detailed information about these methods, see MCP Standard Methods.

Configuration

Configuration is loaded from environment variables and stored in src/core/config.js. The easiest way to configure the server is to edit the .env file in the project root.

Environment Variables

Key environment variables include:

VariableDescriptionDefault
PORTServer port3000
HOSTServer hostlocalhost
NODE_ENVEnvironment (development/production)development
OPENAI_API_KEYOpenAI API key(required for OpenAI models)
STABILITY_API_KEYStability AI API key(required for Stable Diffusion)
ANTHROPIC_API_KEYAnthropic API key(required for Claude models)
HUGGINGFACE_API_KEYHugging Face API key(required for Hugging Face models)

See sample.env for a complete list of configuration options.

Examples

The repository includes several examples to help you get started:

  • Client Example: examples/client.js demonstrates how to interact with the MCP server from a client application.
  • Custom Module Example: examples/custom-module/ shows how to create a custom module that adds a calculator tool to the server.

To run the client example:

node examples/client.js

To use the custom module example, copy it to the modules directory:

cp -r examples/custom-module mcp_modules/calculator

Creating Modules

Modules are the primary way to extend the MCP server. Each module is a self-contained package that can add new functionality to the server.

Module Structure

Modules now follow an enhanced structure with better organization:

mcp_modules/your-module/
├── assets/          # Static assets (images, CSS, etc.)
├── docs/            # Documentation files
├── examples/        # Example usage
├── src/             # Source code
│   ├── controller.js  # HTTP route handlers
│   ├── service.js     # Business logic
│   └── utils.js       # Utility functions
├── test/            # Test files
│   ├── controller.test.js
│   └── service.test.js
├── index.js         # Main module file with register function
├── package.json     # Module metadata, dependencies, and scripts
└── README.md        # Module documentation

Each module should include a package.json file with:

  • Name, version, description
  • Author and license information
  • Dependencies and dev dependencies
  • Scripts (especially for testing)
  • Keywords and other metadata

This structure provides better separation of concerns, makes testing easier, and improves module discoverability.

Module Implementation

The main module file (index.js) must export a register function that will be called when the module is loaded:

/**
 * Register this module with the Hono app
 * @param {import('hono').Hono} app - The Hono app instance
 */
export async function register(app) {
  // Register routes, middleware, etc.
  app.get('/your-module/endpoint', c => {
    return c.json({ message: 'Your module is working!' });
  });
}

// Optional: Export module metadata
export const metadata = {
  name: 'Your Module',
  version: '1.0.0',
  description: 'Description of your module',
  author: 'Your Name',
};

Example Modules

  • A simple example module is provided in mcp_modules/example/ to demonstrate how to create a module.
  • A more complex example with a calculator tool is provided in examples/custom-module/.
  • A health check module is provided in mcp_modules/health-check/ for system monitoring.
  • A template for creating new modules is available in mcp_modules/template/.

Creating New Modules

You can create a new module using the provided script:

# Create a new module
pnpm create-module

# Or with a module name
pnpm create-module my-module

The script will:

  1. Create a new module directory in mcp_modules/
  2. Copy the template files
  3. Replace placeholders with your module information
  4. Provide next steps for implementing your module

Module Search

The MCP server includes a powerful search functionality that allows you to find modules based on any information in their package.json or metadata.

Search Endpoints

  • GET /modules/search/:query - Search for modules containing the specified query string in any field

Search Examples

# Find modules by name or description
curl http://localhost:3000/modules/search/craigslist

# Find modules by dependency
curl http://localhost:3000/modules/search/jsdom

# Find modules by keyword
curl http://localhost:3000/modules/search/mcp

# Find modules by author
curl http://localhost:3000/modules/search/"MCP Server Team"

# Find modules by license
curl http://localhost:3000/modules/search/ISC

JavaScript Example

// Function to search modules by any field
async function searchModules(query) {
  const response = await fetch(`http://localhost:3000/modules/search/${query}`);
  const data = await response.json();

  console.log(`Found ${data.count} modules matching "${query}":`);
  data.results.forEach(module => {
    console.log(`- ${module.name} (${module.directoryName}): ${module.description}`);
  });

  return data.results;
}

The search is comprehensive and will find matches in any field, including nested objects like dependencies, keywords, and other metadata.

Model Providers

The MCP server integrates with several AI model providers:

OpenAI

OpenAI provides GPT models for text generation and Whisper for speech-to-text:

// Text generation example
const response = await fetch('http://localhost:3000/model/infer', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    prompt: 'Write a poem about artificial intelligence',
    temperature: 0.7,
    max_tokens: 200,
  }),
});

// Speech-to-text example (requires multipart form data)
const formData = new FormData();
formData.append('file', audioFile);
formData.append('model', 'whisper-1');
formData.append('language', 'en');

const response = await fetch('http://localhost:3000/model/whisper/infer', {
  method: 'POST',
  body: formData,
});

Stability AI

Stability AI provides Stable Diffusion for image generation:

const response = await fetch('http://localhost:3000/model/infer', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    prompt: 'A photorealistic image of a futuristic city',
    height: 1024,
    width: 1024,
    steps: 30,
    cfg_scale: 7,
  }),
});

// The response includes base64-encoded images
const result = await response.json();
const imageBase64 = result.response[0].base64;

Anthropic

Anthropic provides Claude models for text generation:

const response = await fetch('http://localhost:3000/model/infer', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    prompt: 'Explain how neural networks work',
    temperature: 0.5,
    max_tokens: 300,
  }),
});

Hugging Face

Hugging Face provides access to thousands of open-source models:

const response = await fetch('http://localhost:3000/model/custom-model-name/infer', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    prompt: 'Input for the model',
    parameters: {
      // Model-specific parameters
    },
  }),
});

Documentation

  • MCP Standard Methods: Documentation of the standard methods that all MCP servers should implement.
  • MCP Interface: TypeScript interface definitions for the MCP protocol.
  • Architecture: Overview of the MCP server architecture.

License

ISC

Files in the repo

Repository payload31 top-level entries
  • .github
  • .husky
  • .socket
  • bin
  • docs
  • etc
  • examples
  • mcp_modules
  • mcp_resources
  • scripts
  • src
  • test
  • .dockerignore
  • .env.example
  • .eslintrc.json
  • .gitignore
  • .gitleaks.toml
  • .mocharc.json
  • .npmignore
  • .prettierrc
  • CONTRIBUTING.md
  • docker-compose.yml
  • Dockerfile
  • index.js
  • LICENSE
  • package.json
  • pnpm-lock.yaml
  • README.md
  • sample.env
  • test-image-extraction.js
  • TODO.md

Discussion (0)

Ask about usage, or say what you built with it

Sign in to join the discussion.

No comments yet. Be the first to say what this is good for.

More frameworks & sdks

HKUDS/nanobotFrameworks & SDKs

Ultra-lightweight, open-source, self-hosted personal AI agent framework in Python with WebUI, tools, memory, MCP, multi-agent workflows, automation, and chat apps

48k
microsoft/
SkillOpt
microsoft/SkillOptFrameworks & SDKs

SkillOpt is a text-space optimizer that trains reusable natural-language skills for frozen LLM agents through trajectory-driven edits, validation-gated updates, and deployable best_skill.md artifacts.

17k
omnigent-ai/omnigentFrameworks & SDKs

Omnigent is an open-source AI agent framework and meta-harness: orchestrate Claude Code, Codex, Cursor, Pi, and custom agents — swap harnesses without rewriting, enforce policies and sandboxing, and collaborate in real time from any device.

9.8k
kyegomez/
OpenMythos
kyegomez/OpenMythosFrameworks & SDKs

A theoretical reconstruction of the Claude Mythos architecture, built from first principles using the available research literature.

15k
D4Vinci/ScraplingFrameworks & SDKs

🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!

80k