wmcp
Provides transport/wiring layer for running Model Context Protocol servers, supporting stdio, Streamable HTTP, and legacy SSE, with example and optional personas server for prompts.
README
wmcp
MCP exposure infrastructure — how to run Model Context Protocol servers so Cursor, Claude Desktop, and Claude Code can reach them from WSL, Windows, or macOS.
This repo is the transport/wiring layer, plus an optional personas server (compose / list_prompts). It also ships a tiny example server (echo / ping) so you can verify the plumbing. Bring your own tools and prompt packs.
Requires Node.js ≥ 18.
What an MCP server is (short version)
An MCP server is a process that speaks Model Context Protocol — JSON-RPC messages describing tools, prompts, and/or resources. Clients (Cursor, Claude) call those tools during a chat.
The interesting part is not the tools themselves. It is how the client connects:
| Transport | Who speaks it | How it runs |
|---|---|---|
| stdio | Cursor (local), Claude Desktop | Client spawns node dist/….js and talks over stdin/stdout |
| Streamable HTTP | Cursor, Claude Desktop (URL mode) | One long-lived Node HTTP server; client POSTs to http://host:port/<name> |
| Legacy SSE | Claude Code CLI | Same HTTP server; GET /<name>/sse + POST /<name>/message |
wmcp implements all three from one codebase.
┌─────────────────┐ stdio ┌──────────────────┐
│ Cursor / Claude │ ◄────────────► │ example-server │ (per-process)
│ (local spawn) │ │ or stdio-bridge │
└─────────────────┘ └──────────────────┘
┌─────────────────┐ HTTP/SSE ┌──────────────────┐
│ Cursor / Claude │ ◄────────────► │ http-server │──► example
│ (URL mode) │ │ :8820 │──► personas (opt)
└─────────────────┘ └──────────────────┘
Typical setup when the real Node runtime lives in WSL:
- Run
http-serverinside WSL (systemd user unit ornpm start). - Point Windows/mac Cursor at
http://localhost:8820/example(WSL localhost forwarding). - Or, for stdio-only clients on Windows:
wsl.exe … node dist/example-server.js.
On macOS / native Linux, skip the wsl.exe path — run Node locally and point Cursor at http://localhost:8820/<server> or a direct node dist/….js stdio command.
Quick start
git clone https://github.com/mwhobrey/wmcp.git
cd wmcp
npm install
npm run build
npm start # HTTP front door on :8820
curl http://localhost:8820/health
stdio smoke test (separate terminal):
node dist/example-server.js
# or: node dist/stdio-bridge.js example
Wire Cursor
If transport is "sse" (the default in the example config), start the HTTP server first (npm start) and leave it running. Cursor connects to URLs; nothing is listening otherwise.
Option A — paste a minimal entry (safest; does not touch other MCP servers):
{
"mcpServers": {
"example": {
"url": "http://localhost:8820/example"
}
}
}
Add that under your existing mcpServers in Cursor's MCP config, then reload MCP and call ping on example.
For stdio instead of HTTP:
{
"mcpServers": {
"example": {
"command": "node",
"args": ["/absolute/path/to/wmcp/dist/example-server.js"]
}
}
}
Option B — generate configs from this repo (WSL + Windows):
Warning:
npm run sync:mcpoverwrites~/.cursor/mcp.jsonand, when/mnt/cis present,C:\Users\<windowsUser>\.cursor\mcp.json. Back up first if you already have other servers configured.
-
Copy and edit config:
cp config/mcp-servers.example.json config/mcp-servers.json # set projectRoot, nodePath, wslUser, windowsUser -
With the HTTP server running (for
"transport": "sse"):npm run sync:mcp -
Reload MCP in Cursor. Call the
pingtool on theexampleserver.
transport in mcp-servers.json:
"sse"(default) → Cursor entries are{ "url": "http://localhost:8820/example" }— http-server must be up"stdio"→ Cursor spawns Node (orwsl.exeon Windows) — no shared HTTP process needed
Optional: personas server
Markdown prompt packs with hot reload. Tools:
| Tool | Purpose |
|---|---|
compose |
Merge layers into one system prompt (see order below) |
list_prompts |
List loaded prompts by category |
Also exposes MCP prompts (list / get) for clients that use that capability.
Compose merge order (each layer optional except when base is left on):
base(personas/base) — omitted ifbase: falseteam— repo/org policy cardpersona— roleskill— modescript— playbook
Sections are joined with ---. Template args apply to every included layer.
Enable on the HTTP front door:
cp env.example .env # then set WMCP_ENABLE_PERSONAS=1
# PERSONAS_DIR=/absolute/path/to/prompts # optional; default ./prompts
npm start
# → http://localhost:8820/personas
Cursor URL entry:
{
"mcpServers": {
"personas": {
"url": "http://localhost:8820/personas"
}
}
}
Or run stdio directly (no WMCP_ENABLE_PERSONAS required):
npm run start:personas
# or: node dist/stdio-bridge.js personas
Sample prompts ship under prompts/ (personas/, skills/, scripts/, teams/). Replace them with your own — edits hot-reload; no restart needed.
Frontmatter shape:
---
name: engineer
description: Short description for list_prompts
category: persona
args:
- name: stack
description: Primary tech stack
required: false
---
# Role: Engineer
{{stack}}Primary stack: {{stack}}.{{/stack}}
Template syntax: {{var}}, {{var|default}}, and {{var}}…{{/var}} (block omitted when unset).
Adding your own MCP server
- Create
src/my-server.ts— construct an MCPServer, register tools, exposegetServer(). - Register a factory in
src/registry.ts. - Add a
servers.myentry inconfig/mcp-servers.jsonwith"script": "my-server.js". npm run build && npm run sync:mcp(and restarthttp-serverif using URL mode).
The HTTP and stdio layers stay unchanged. They only need a name → () => Server factory.
Layout
src/
example-server.ts # reference MCP tools (echo, ping)
personas-server.ts # optional compose / list_prompts
registry.ts # name → factory map (+ env toggles)
http-server.ts # Streamable HTTP + legacy SSE multiplexer
stdio-bridge.ts # named stdio launcher
env-flags.ts
is-main-module.ts
prompts/ # sample prompt pack (swap for yours)
config/
mcp-servers.example.json
scripts/
sync-mcp-config.mjs
fix-permissions.mjs
systemd/
wmcp.service
Environment
| Variable | Default | Purpose |
|---|---|---|
MCP_PORT |
8820 |
HTTP listen port |
MCP_SSE_PING_MS |
30000 |
SSE keep-alive comment interval (0 disables) |
WMCP_ENABLE_PERSONAS |
off | Register personas on the HTTP front door (1/true/yes/on) |
PERSONAS_DIR |
./prompts |
Markdown prompt root (personas/, skills/, scripts/, teams/) |
See env.example. Load via .env in the project root (dotenv) or export in the shell / systemd unit.
systemd (optional)
# edit User / paths in systemd/wmcp.service first
mkdir -p ~/.config/systemd/user
cp systemd/wmcp.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now wmcp
systemctl --user status wmcp
To enable personas under systemd, set WMCP_ENABLE_PERSONAS=1 in .env (or Environment= in the unit).
Design notes
- One HTTP process, many logical servers — routes by path prefix; each request gets a fresh MCP
Serverinstance for Streamable HTTP (stateless). - Fail per server at boot — a broken factory is skipped; others still serve.
- Personas are optional — off by default so the public repo stays a transport template; flip the env when you want compose/list_prompts on HTTP. Direct
npm run start:personasalways works. - Private prompt packs stay private — point
PERSONAS_DIRat an external directory, or replaceprompts/locally and don't commit company content.
License
MIT
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.