Building a Multi‑Protocol MCP Server in TypeScript: Full Guide and Code

This article introduces a TypeScript MCP‑Server framework that simultaneously supports stdio, streamableHttp, and SSE protocols, explains its design motivations, outlines its modular architecture, provides setup and deployment instructions, and showcases key source code and usage examples.

JD Tech Talk
JD Tech Talk
JD Tech Talk
Building a Multi‑Protocol MCP Server in TypeScript: Full Guide and Code

Overview

This TypeScript framework implements an MCP‑Server that supports three transport protocols— stdio , streamableHttp (also called streamableHttpless), and SSE —allowing a single codebase to run in all modes.

Motivation

Different business scenarios require different MCP protocols (stdio, network request, etc.).

Platform requirements vary: some platforms need streamableHttp, others only SSE, leading to duplicated effort.

Developers often lack MCP knowledge and must learn it on the fly, extending development cycles.

These factors increase time and cost.

Key Features

Unified support for stdio, streamableHttp, and SSE; one‑time development covers all three.

All functionalities are split into independent modules, so developers only need to implement business logic in designated files.

Configuration via environment variables for domain, host, port, and base path, making the server production‑ready.

Mode switching is performed by changing the start command in the launch script.

Built‑in logging for startup and service call tracing.

Repository

GitHub: https://github.com/XingtongCai/mcp-server-ts

Coding platform (demo): http://xingyun.jd.com/codingRoot/jdcloud-fe/mcp-server/tree/main/demo

Directory Structure

- build: compiled files
- src
  -- router: routes for streamableHttp and SSE
    --- index.ts: entry for streamableHttp routes
    --- mcp.ts: path config (default /mcp, customizable via process.env.MCP_BASE_PATH)
    --- sse.ts: path config for SSE
  -- tools: utility modules
    --- index.ts: tool registration
    --- mockFunc.ts: example tool (business‑specific)
  -- cli.ts: command‑line parser
  -- index.ts: main entry
  -- server.ts: creates MCP service and registers tools
  -- sse.ts: runs SSE mode
  -- stdio.ts: runs stdio mode
  -- streamableHttp.ts: runs streamableHttp mode
- xingyun/bin: deployment scripts for the Xingyun platform (adapt for other platforms)
- build_xingyun.sh: auxiliary build script

Local Startup Commands

Start stdio (default): npm run start Start StreamableHttp (default port 3001): npm run start:http Start StreamableHttp on a custom port: npm run dev:http or npm run start -- -t http -p 3001 Start SSE (default port 3001):

npm run start:sse

Command‑line Flags

-t http

– selects StreamableHttp transport. -p 3001 – sets the listening port.

Deployment Script Example

start(){
  npm run start:http
  sleep 3
  status
}

Production Environment Variables

# Bind to a specific internal IP
export MCP_HOST=192.168.1.100
export MCP_PORT=3001
# Optional internal domain
export MCP_DOMAIN=mcp-server.internal.com
# Optional base path (default /mcp)
export MCP_BASE_PATH=/api/mcp

Configuration Priority

Port: MCP_PORT (environment) > --port (CLI) > default 3001.

Domain: MCP_DOMAIN (environment) > MCP_HOST (environment) > default localhost.

Access URLs

# Basic access
http://192.168.1.100:3001/sales
# With domain
http://mcp-server.internal.com/sales
# Custom base path
http://192.168.1.100:3001/api/mcp

package.json Scripts

"scripts": {
  "build": "tsc && chmod 755 build/src/index.js  build/src/cli.js",
  "start": "node ./build/src/cli.js",
  "start:http": "node ./build/src/cli.js --transport http",
  "start:sse": "node ./build/src/cli.js --transport sse",
  "dev:http": "node ./build/src/cli.js --transport http --port 3002",
  "stop": "pkill -f \"demo\" || true",
  "restart": "npm run stop && npm run start:http",
  "inspector": "npx @modelcontextprotocol/inspector"
}

Core Modules

tools/index.ts : registers utility tools.

router folder: registers routes for streamableHttp and SSE.

streamableHttp/index.ts : defines basePath for custom API prefixes.

sse.ts : implements GET and POST handlers for SSE.

Results

stdio mode packaged as an npm module (https://npm.m.jd.com/package/@jd/demo-mcp-server) and successfully connected via Joycode.

streamableHttp mode connected and runnable via Joycode.

SSE mode integrated into the Autobots project for permission‑intercepted MCP services.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

TypeScriptMCPNode.jsSSEStreamableHttp
JD Tech Talk
Written by

JD Tech Talk

Official JD Tech public account delivering best practices and technology innovation.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.