mcp-local-gateway
Minimal MCP server exposing a single tool, run_date, to execute the local date command via a Streamable HTTP endpoint.
README
mcp-local-gateway
P0 goal: run a minimal local MCP server that exposes exactly one tool, run_date, through a Streamable HTTP /mcp endpoint.
This project is intentionally small. It does not expose arbitrary Bash. It does not use an OpenAI API key. It is designed for this validation chain:
ChatGPT Web
-> HTTPS /mcp
-> Cloudflare Tunnel or another HTTPS tunnel
-> 127.0.0.1:8787
-> Hono
-> MCP Server
-> policy layer
-> fixed date command
Terms
- MCP: Model Context Protocol, 模型上下文协议,用来让 AI Host 通过标准协议发现并调用外部工具。
- Streamable HTTP: 可流式 HTTP 传输,适合远程 MCP server。
- Hono: 轻量 HTTP framework,HTTP 框架。
- OAuth: Open Authorization,开放授权。P0 只预留结构,不实现完整授权码流程。
- Policy layer: 策略层,本项目中用于拒绝任意命令,只允许
run_date -> date。
Requirements
- Node.js >= 20.11
- npm
- Linux / WSL recommended
Install
cd ~/project/mcp-local-gateway
npm install
cp .env.example .env
Start
npm run dev
Expected startup lines:
mcp-local-gateway listening on http://127.0.0.1:8787
health: http://127.0.0.1:8787/healthz
mcp: http://127.0.0.1:8787/mcp
auth: off
Local validation
In another terminal:
cd ~/project/mcp-local-gateway
npm run typecheck
npm run build
npm test
npm run test:local
The tools/list response should include run_date. The tools/call response should include JSON text containing stdout from the local date command.
Persistent user service / 用户级常驻服务
Use the user-level systemd service when you want the gateway to keep running after the terminal closes.
npm run service:install
npm run service:status
npm run service:logs
npm run service:uninstall
service:install runs npm run build and starts dist/index.js; it does not use npm run dev.
The service keeps running after the terminal exits.
Cloudflare Tunnel access to mcp.songlei.me depends on this service listening on 127.0.0.1:8787.
Persistent OpenAI Tunnel / OpenAI Tunnel 常驻运行
Use the user-level systemd service when you want tunnel-client to keep the OpenAI Tunnel process running after the terminal closes.
npm run tunnel:install
npm run tunnel:status
npm run tunnel:logs
npm run tunnel:uninstall
tunnel:install runs npm ci and npm run build, checks tunnel-client, ~/.config/homelab-mcp/openai-tunnel.env, and ~/.config/tunnel-client/homelab-stdio.yaml, then installs openai-tunnel-client.service.
The service uses WorkingDirectory at the repository root, loads ~/.config/homelab-mcp/openai-tunnel.env, and runs:
tunnel-client run --profile homelab-stdio --health.listen-addr 127.0.0.1:18080 --health.url-file /tmp/homelab-openai-tunnel-stdio-health.url --log.file /tmp/homelab-openai-tunnel-stdio.log
After install, the script runs systemctl --user daemon-reload, enable, restart, and status for openai-tunnel-client.service, then waits for both /healthz and /readyz to succeed through the URL written to /tmp/homelab-openai-tunnel-stdio-health.url.
Static bearer mode
Use this before exposing through a tunnel if you are not using OAuth yet.
cat > .env <<'ENDENV'
HOST=127.0.0.1
PORT=8787
MCP_AUTH_MODE=static_bearer
MCP_STATIC_BEARER_TOKEN=replace-this-with-a-long-random-token
MCP_ALLOWED_ORIGINS=http://127.0.0.1:8787,http://localhost:8787,https://chatgpt.com
AUDIT_TO_STDOUT=true
AUDIT_LOG_FILE=logs/audit.jsonl
ENDENV
npm run dev
Validation with token:
MCP_STATIC_BEARER_TOKEN='replace-this-with-a-long-random-token' npm run test:local
Cloudflare Tunnel sketch
Do not bind this server to 0.0.0.0. Keep HOST=127.0.0.1 and publish it with a tunnel.
Example target mapping:
https://mcp.songlei.me/mcp -> http://127.0.0.1:8787/mcp
After that, create a ChatGPT connector and set Connector URL to:
https://mcp.songlei.me/mcp
P0 recommendation: use static bearer only for a private short-lived test. P1 should implement OAuth / OIDC token validation or put the MCP server behind a compatible identity-aware proxy.
Security constraints in P0
- No arbitrary Bash.
run_dateaccepts no arguments.- Command execution uses
spawnwithshell: false. - Server refuses
HOST=0.0.0.0. /mcpchecks Origin when Origin is present./mcpcan enforce static Bearer token.- Each tool call writes JSONL audit records.
File map
src/index.ts entry point
src/config.ts environment config and startup safety checks
src/http/app.ts Hono app, health endpoint, /mcp route
src/http/origin.ts Origin allowlist guard
src/auth/auth.ts off/static_bearer/oauth_placeholder auth middleware
src/mcp/server.ts MCP server creation and tool registration
src/mcp/transport.ts Streamable HTTP transport creation
src/tools/run-date.ts run_date MCP tool
src/policy/policy.ts P0 allow/deny logic
src/shell/exec-fixed.ts fixed date command execution
src/audit/audit.ts JSONL audit logger
scripts/local-validate.sh curl-based validation script
test/*.test.ts minimal unit tests
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.