logo
Free, unlimited AI code reviews that run on commit
git-lrc git-lrc GitHub Install Now We'd appreciate a star git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt

2025_McpLab_RapidMCP

A robust, TypeScript-based web service engine engineered for Model Context Protocol (MCP) client session orchestration. It natively supports defining custom tools, resources, and prompt templates, while incorporating essential backend features like secure authentication mechanisms, comprehensive activity logging, and live data streaming via Server-Sent Events (SSE). This framework also bundles utilities for streamlined testing and diagnostics through Command Line Interface (CLI) apparatus.

Author

2025_McpLab_RapidMCP logo

yamato-snow

MIT License

Quick Info

GitHub GitHub Stars 0
NPM Weekly Downloads 0
Tools 1
Last Updated 2026-02-19

Tags

apis2025_mcplab_fastmcprequeststypescript serverrequests yamatoapis http

RapidMCP: High-Velocity MCP Server Implementation

RapidMCP constitutes a comprehensive TypeScript framework enabling the swift establishment of an MCP (Model Context Protocol) server environment, specializing in managing concurrent client sessions.

[!NOTE]

For those utilizing Python, an alternative implementation, FastMCP Python, is available at FastMCP Python.

Core Capabilities Overview

RapidMCP furnishes developers with a rich feature set:

Acquisition Instructions

Install via npm:

bash npm install fastmcp

Initiating Usage

[!NOTE]

Extensive documentation on practical applications is available in the Example Showcase section.

ts import { FastMCP } from "fastmcp"; import { z } from "zod"; // Or any other Standard Schema compliant validation library

const server = new FastMCP({ name: "My Swift Server", version: "1.0.0", });

server.addTool({ name: "add", description: "Computes the summation of two numerical inputs", parameters: z.object({ a: z.number(), b: z.number(), }), execute: async (args) => { return String(args.a + args.b); }, });

server.start({ transportType: "stdio", });

This minimal configuration launches a functional MCP endpoint! Test it immediately from your terminal:

bash git clone https://github.com/punkpeye/fastmcp.git cd fastmcp

pnpm install pnpm build

Test the addition server example via CLI:

npx fastmcp dev src/examples/addition.ts

Inspect the addition server example using MCP Inspector:

npx fastmcp inspect src/examples/addition.ts

Server-Sent Events (SSE)

Server-Sent Events represent a unidirectional communication channel where the server pushes updates to a client over a persistent HTTPS connection. Within the MCP context, SSE primarily enables remote MCP communications, facilitating the relaying of updates across a network from an externally hosted MCP instance.

To initialize the server with SSE capability:

ts server.start({ transportType: "sse", sse: { endpoint: "/sse", port: 8080, }, });

This action launches the service, actively listening for SSE connections at http://localhost:8080/sse.

Subsequently, connectivity can be established using the SSEClientTransport:

ts import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";

const client = new Client( { name: "example-client", version: "1.0.0", }, { capabilities: {}, }, );

const transport = new SSEClientTransport(new URL(http://localhost:8080/sse));

await client.connect(transport);

Fundamental Constructs

Tools

MCP Tools expose callable functions that the server can execute, enabling clients or LLMs to trigger specific actions.

RapidMCP leverages the Standard Schema specification for defining tool parameters, allowing flexibility in using validation libraries like Zod, ArkType, or Valibot that adhere to the specification.

Zod Example:

typescript import { z } from "zod";

server.addTool({ name: "fetch-zod", description: "Retrieves content from a specified URL (using Zod)", parameters: z.object({ url: z.string(), }), execute: async (args) => { return await fetchWebpageContent(args.url); }, });

ArkType Example:

typescript import { type } from "arktype";

server.addTool({ name: "fetch-arktype", description: "Retrieves content from a specified URL (using ArkType)", parameters: type({ url: "string", }), execute: async (args) => { return await fetchWebpageContent(args.url); }, });

Valibot Example:

Valibot requires the peer dependency @valibot/to-json-schema.

typescript import * as v from "valibot";

server.addTool({ name: "fetch-valibot", description: "Retrieves content from a specified URL (using Valibot)", parameters: v.object({ url: v.string(), }), execute: async (args) => { return await fetchWebpageContent(args.url); }, });

Returning Strings

The execute function can return a simple string:

js server.addTool({ name: "download", description: "Initiates a file download", parameters: z.object({ url: z.string(), }), execute: async (args) => { return "Hello, World!"; }, });

This is semantically equivalent to:

js server.addTool({ name: "download", description: "Initiates a file download", parameters: z.object({ url: z.string(), }), execute: async (args) => { return { content: [ { type: "text", text: "Hello, World!", }, ], }; }, });

Returning Lists

To return a sequence of messages, return an object containing the content property:

js server.addTool({ name: "download", description: "Initiates a file download", parameters: z.object({ url: z.string(), }), execute: async (args) => { return { content: [ { type: "text", text: "First message in sequence" }, { type: "text", text: "Second message in sequence" }, ], }; }, });

Image Output

To construct an image content object, utilize the imageContent helper:

js import { imageContent } from "fastmcp";

server.addTool({ name: "download", description: "Initiates a file download", parameters: z.object({ url: z.string(), }), execute: async (args) => { return imageContent({ url: "https://example.com/image.png", });

// Alternatively...
// return imageContent({
//   path: "/path/to/image.png",
// });

// Or...
// return imageContent({
//   buffer: Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=", "base64"),
// });

// Or wrap in a content array:
// return {
//   content: [
//     await imageContent(...)
//   ],
// };

}, });

The imageContent utility accepts one of the following mutually exclusive options:

  • url: A direct URL to the image resource.
  • path: A file system path to the image.
  • buffer: The raw image data encapsulated as a Buffer.

The above example translates to the following direct MCP structure:

js server.addTool({ name: "download", description: "Initiates a file download", parameters: z.object({ url: z.string(), }), execute: async (args) => { return { content: [ { type: "image", data: "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=", mimeType: "image/png", }, ], }; }, });

Logging

Tools can relay messages back to the client via the log utility provided in the context object:

js server.addTool({ name: "download", description: "Initiates a file download", parameters: z.object({ url: z.string(), }), execute: async (args, { log }) => { log.info("Commencing file retrieval...", { url: args.url, });

// ... Operation continues ...

log.info("File retrieval successfully concluded");

return "Operation Complete";

}, });

The log interface exposes the following serialization methods:

  • debug(message: string, data?: SerializableValue)
  • error(message: string, data?: SerializableValue)
  • info(message: string, data?: SerializableValue)
  • warn(message: string, data?: SerializableValue)

Errors

Errors intended for display to the end-user must be raised as instances of UserError:

js import { UserError } from "fastmcp";

server.addTool({ name: "download", description: "Initiates a file download", parameters: z.object({ url: z.string(), }), execute: async (args) => { if (args.url.startsWith("https://example.com")) { throw new UserError("Access to this URL domain is explicitly forbidden"); }

return "Success";

}, });

Progress Updates

Tools can signal operational progress back to the client by invoking reportProgress on the context object:

js server.addTool({ name: "download", description: "Initiates a file download", parameters: z.object({ url: z.string(), }), execute: async (args, { reportProgress }) => { reportProgress({ progress: 0, total: 100, });

// ... Processing steps ...

reportProgress({
  progress: 100,
  total: 100,
});

return "Finished";

}, });

Resources

Resources define any data payload the MCP server wishes to expose to connected clients. This encompasses:

  • File contents.
  • Visual assets like screenshots or images.
  • System log files.
  • Various other arbitrary data streams.

Each resource is uniquely addressable via a URI and can carry either textual or binary content.

ts server.addResource({ uri: "file:///logs/app.log", name: "Primary Application Log", mimeType: "text/plain", async load() { return { text: await readLogFile(), }; }, });

[!NOTE]

The load function supports returning an array of resource data objects. This pattern is useful, for instance, when simulating the reading of a directory to present a list of files.

ts async load() { return [ { text: "Content of File One", }, { text: "Content of File Two", }, ]; }

Binary content can also be served from load:

ts async load() { return { blob: 'Base64-encoded data payload' }; }

Resource Templates

It is also possible to establish parameterized Resource Templates:

ts server.addResourceTemplate({ uriTemplate: "file:///logs/{name}.log", name: "Templated Application Log", mimeType: "text/plain", arguments: [ { name: "name", description: "Identifier for the specific log file", required: true, }, ], async load({ name }) { return { text: ${name} sample log entry data, }; }, });

Resource Template Argument Autocompletion

To enable intelligent suggestion for resource template parameters, supply a complete function:

ts server.addResourceTemplate({ uriTemplate: "file:///logs/{name}.log", name: "Templated Application Log", mimeType: "text/plain", arguments: [ { name: "name", description: "Identifier for the specific log file", required: true, complete: async (value) => { if (value === "Sample") { return { values: ["SampleLogData"], }; }

    return {
      values: [],
    };
  },
},

], async load({ name }) { return { text: ${name} sample log entry data, }; }, });

Prompts

Prompts allow the server to pre-define reusable interaction templates and workflows, making it straightforward for clients to present standardized conversational sequences to users or LLMs. This standardizes and facilitates shared complex LLM interactions.

ts server.addPrompt({ name: "git-commit", description: "Generates an appropriate Git commit message", arguments: [ { name: "changes", description: "Description of git diff or summary of modifications", required: true, }, ], load: async (args) => { return Please synthesize a concise and descriptive commit message for the following alterations:\n\n${args.changes}; }, });

Prompt Argument Autocompletion

Prompts can offer dynamic suggestions for their input arguments:

js server.addPrompt({ name: "countryPoem", description: "Composes a short verse about a nation", load: async ({ name }) => { return Greetings, inhabitant of ${name}!; }, arguments: [ { name: "name", description: "The name of the country", required: true, complete: async (value) => { if (value === "J") { return { values: ["Japan"], }; }

    return {
      values: [],
    };
  },
},

], });

Prompt Argument Autocompletion via enum

Supplying an enum array for an argument automatically configures server-side completion suggestions for that parameter.

js server.addPrompt({ name: "countryPoem", description: "Composes a short verse about a nation", load: async ({ name }) => { return Greetings, inhabitant of ${name}!; }, arguments: [ { name: "name", description: "The name of the country", required: true, enum: ["Japan", "France", "Italy"], }, ], });

Authentication

RapidMCP allows defining custom logic to authenticate incoming client connections via a dedicated handler:

ts import { AuthError } from "fastmcp";

const server = new FastMCP({ name: "My Secure Server", version: "1.0.0", authenticate: ({request}) => { const apiKey = request.headers["x-api-key"];

if (apiKey !== '123') {
  throw new Response(null, {
    status: 401,
    statusText: "Unauthorized",
  });
}

// The returned object populates the context.session object
return {
  id: 1,
}

}, });

Authenticated session data then becomes accessible within tool execution contexts:

ts server.addTool({ name: "sayHello", execute: async (args, { session }) => { return Hello to authenticated user ID: ${session.id}!; }, });

Sessions

The session object provides a handle to the active client's connection context, conforming to the FastMCPSession interface.

Access the collection of active sessions via:

ts server.sessions;

To ensure isolated 1:1 communication channels, a new server instance context is allocated for every unique client connection.

Type-Safe Server Events

The on method facilitates listening to events emitted directly from the server instance:

ts server.on("connect", (event) => { console.log("New client connected:", event.session); });

server.on("disconnect", (event) => { console.log("Client disconnected:", event.session); });

FastMCPSession Interface Details

FastMCPSession encapsulates the state and operational methods for an active client connection.

Details on retrieving a FastMCPSession instance are covered in the Sessions section.

requestSampling

The requestSampling method allows for initiating an explicit Sampling request against the server's model capabilities, returning the processed result:

ts await session.requestSampling({ messages: [ { role: "user", content: { type: "text", text: "What files are present in the current directory structure?", }, }, ], systemPrompt: "You are a helpful file system navigation assistant.", includeContext: "thisServer", maxTokens: 100, });

clientCapabilities

This read-only property exposes the feature set declared by the connecting client.

ts session.clientCapabilities;

loggingLevel

This property reflects the verbosity level configured by the client for receiving logs.

ts session.loggingLevel;

roots

This property contains the set of context roots currently registered by the client.

ts session.roots;

server

This property provides a reference back to the underlying MCP server instance managing this session.

ts session.server;

Type-Safe Session Events

Events specific to the session lifecycle can be monitored using the session's on method:

ts session.on("rootsChanged", (event) => { console.log("Client context roots updated to:", event.roots); });

session.on("error", (event) => { console.error("Session-specific error occurred:", event.error); });

Server Deployment

Testing with MCP-CLI

The quickest method for validating and debugging your server implementation is via the fastmcp dev command:

bash npx fastmcp dev server.js npx fastmcp dev server.ts

This command launches the server environment, enabling immediate testing and interactive debugging using the mcp-cli tool directly in the terminal.

Inspection via MCP Inspector

Alternatively, you can examine the server's exposed interfaces via the official Web UI tool, the MCP Inspector:

bash npx fastmcp inspect server.ts

Frequently Asked Questions

Integration with Claude Desktop

Follow the instructions detailed in the official guide https://modelcontextprotocol.io/quickstart/user, and configure your Claude settings file with an entry similar to this:

{ "mcpServers": { "my-mcp-server": { "command": "npx", "args": [ "tsx", "/path/to/your/project/src/index.ts" ], "env": { "ENVIRONMENT_VARIABLE_NAME": "Value" } } } }

Example Showcase

[!NOTE]

If you build a server utilizing FastMCP, consider submitting a Pull Request to have it featured here!

Acknowledgements

See Also

`