Skip to main content
Glama
huafua

mcp-simulator

by huafua

MCP Simulator (Node.js MCP Server)

mcp simulator is a lightweight MCP server (Model Context Protocol Server) built on Node.js. This project adopts a zero-external-dependency design (using only the native http module), and provides dynamic tool registration and HTTP remote procedure call (RPC) capabilities through the modular McpServer and McpRegistry.


šŸš€ Core Features

  • Zero external dependencies: Relies entirely on Node.js's native http module; no frameworks such as express are needed.

  • Brand-new MCP core architecture:

    • McpRegistry: responsible for maintaining the tool list and execution logic (supports both synchronous and asynchronous async methods).

    • McpServer: provides an HTTP POST-based execution entry point and unified JSON response wrapping.

  • Clean API registration design: Provides a chainable register() interface; you only need to supply two parameters, the "tool definition" and the "execution callback", to register easily.

  • Built-in tools and reflection mechanism:

    • Built-in tool/list dynamically queries all registered tools.

    • Provides complete demonstrations including synchronous calculation, text processing, and asynchronous (async) simulated API requests (fetch-posts).


Related MCP server: Swagger/Postman MCP Server

šŸ“ File Structure

mcp-simulator/
ā”œā”€ā”€ mcp.core.js             # ä¼ŗęœå™Øę øåæƒå¼•ę“Žļ¼ˆå®šē¾© McpServer 與 McpRegistry é”žåˆ„ļ¼‰
ā”œā”€ā”€ index.js                # å°ˆę”ˆäø»å…„å£ļ¼ˆč¼‰å…„ę øåæƒå¼•ę“Žäø¦čØ»å†Šå…·é«”å·„å…·ļ¼‰
ā”œā”€ā”€ index.http              # HTTP API ęø¬č©¦č…³ęœ¬ļ¼ˆę­é… VS Code REST Client 使用)
ā”œā”€ā”€ package.json            # å°ˆę”ˆé…ē½®ę–‡ä»¶
└── README.md               # ęœ¬å°ˆę”ˆčŖŖę˜Žę–‡ä»¶

āš™ļø Quick Start

Starting the Server

Run the following command in the project root directory:

node index.js

The server listens on port 8889 by default (or reads the PORT environment variable). After startup, the console will display:

Server running at 8889

šŸ”Œ API Protocol Specification

All API calls go through a single entry point.

  • Request method: POST

  • Server address: http://localhost:8889

  • Request header: Content-Type: application/json

  • Request body format (Payload):

    {
        "name": "č¦čŖæē”Øēš„å·„å…·åēØ±",
        "args": {
            "åƒę•øéµ": "åƒę•øå€¼"
        }
    }

Unified Response Structure (Response)

After all requests are processed successfully, the server returns a uniformly wrapped JSON structure:

{
    "code": 200,
    "message": "success",
    "data": {
        /* å·„å…·å›žå‚³ēš„åŽŸå§‹ēµęžœ */
    }
}

Server Error Status Overview

HTTP Status Code

Scenario Description

Response Content (JSON)

200

Header error (application/json not specified)

{"code": 406, "message": "Content-type must be 'application/json'"}

200

JSON format error (cannot be parsed)

{"code": 500, "message": "Request body is not valid format"}

200

Tool name not provided (missing name field)

{"code": 406, "message": "Name must be provided"}

200

Calling an unregistered tool

{"code": 200, "message": "success", "data": null}


šŸ› ļø Built-in Method Call Examples

The following are actual call data using localhost:8889 as an example:

1. Get the List of Available Tools (tool/list)

Lists all tool definitions registered in the server.

  • Request Payload: {"name": "tool/list", "args": {}}

  • Response Example:

    {
        "code": 200,
        "message": "success",
        "data": [
            { "name": "info", "description": "..." },
            {
                "name": "hello",
                "description": "just say hello to someone",
                "args": { "username": "string" }
            },
            {
                "name": "calculate",
                "description": "calculate sum of two numbers",
                "args": { "a": "number", "b": "number" }
            },
            {
                "name": "fetch-posts",
                "description": "fetch posts from https://jsonplaceholder.typicode.com/posts"
            }
        ]
    }

2. Calculate the Sum of Two Numbers (calculate)

  • Request Payload: {"name": "calculate", "args": {"a": 20, "b": 30}}

  • Response Example:

    {
        "code": 200,
        "message": "success",
        "data": { "result": 50 }
    }

3. Asynchronous Request Test (fetch-posts)

Demonstrates the use of an async callback function, returning a set of fake user data (an array).

  • Request Payload: {"name": "fetch-posts"}

  • Response Example:

    {
        "code": 200,
        "message": "success",
        "data": [
            {
                "id": 1,
                "name": "Leanne Graham",
                "username": "Bret",
                "email": "Sincere@april.biz"
                // ... (其他資料畄)
            }
        ]
    }

šŸ“ Developing and Extending Custom Tools

You can modify index.js and add your tools through chainable .register() calls.

API Signature

server.register(toolDefinition, callback);
  • toolDefinition (Object): must contain name, and may optionally provide description and args (parameter definitions).

  • callback (Function / Async Function): the callback executed when a request is received. It receives a single object parameter from req.params.args.

Registration Example

const { McpServer } = require("./mcp.core");

new McpServer(8889)
    // čØ»å†Šäø€å€‹éœ€č¦åƒę•øēš„éžåŒę­„å·„å…·
    .register(
        {
            name: "get_user",
            description: "ē²å–ē‰¹å®šä½æē”Øč€…č³‡ę–™",
            args: { userId: "number" },
        },
        async ({ userId }) => {
            // āš ļø åæ…é ˆä½æē”Øē‰©ä»¶č§£ę§‹č®€å–åƒę•ø
            const user = await database.find(userId);
            return { result: user };
        },
    )
    .start();

šŸ’” Key Development Reminders:

  1. Parameter reception: Because the args sent by the client are passed to the callback function as a single object, if your tool defines multiple parameters, be sure to use object destructuring with { param1, param2 } in the callback function.

  2. Asynchronous support: McpRegistry internally uses await to execute tools, so you can safely use async/await in your callback functions for database queries or network requests.


šŸ“„ License

This project is open-sourced under the terms of the MIT License.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    A lightweight, modular API service that provides useful tools like weather, date/time, calculator, search, email, and task management through a RESTful interface, designed for integration with AI agents and automated workflows.
    5
    1
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Server that ingests Swagger/OpenAPI specifications and Postman collections, providing just 4 strategic tools that allow AI agents to dynamically discover and interact with APIs instead of generating hundreds of individual tools.
    3
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    A lightweight Node.js-based MCP server that exposes custom tools via HTTP and Server-Sent Events (SSE) for clients like Postman. It allows users to register tools with type-safe validation to establish bidirectional communication with MCP clients.
    1,026 npm
    1
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    A modular server for managing and registering tools, enabling extensible functionality through tool registration and configuration.
    -