Rpc Tools
MCP server: Rpc Tools
Installation
npx mcp-server-rpc-toolsAsk AI about Rpc Tools
Powered by Claude Β· Grounded in docs
I know everything about Rpc Tools. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
MCP Server + RPC Tools Monorepo
A complete end-to-end demo system showcasing Cloudflare Workers + Hono + MCP (Model Context Protocol) as a monorepo using PNPM workspaces.
Live Demo
Try the live Streamlit client here: https://mcp-server-rpc-tools-gzlapy2fedh6ff2wohnnhl.streamlit.app/
Try the live CopilotKit client here: https://mcp-server-rpc-tools-mcp-client-cop.vercel.app/
Architecture
- mcp-gateway-worker: MCP server entrypoint that routes tool calls to domain workers via secure RPC
- domain-a-tools-worker: RPC endpoint exposing Domain A tools (hello, list-top-customers)
- domain-b-tools-worker: RPC endpoint exposing Domain B tools (sum, normalize-text)
- mcp-client-streamlit: Python UI for testing the MCP gateway
- mcp-client-copilotkit: Next.js CopilotKit UI for testing MCP tools via chat
Quick Start
Prerequisites
- Node.js 18+
- PNPM 8+
- Wrangler CLI:
npm install -g wrangler - Python 3.9+ (for Streamlit app)
Setup Order
1. Install Dependencies
pnpm install
2. Deploy Domain Workers First
Configure and deploy domain-a-tools-worker:
cd apps/domain-a-tools-worker
wrangler secret put DOMAIN_SHARED_SECRET
# Enter a shared secret (e.g., "dev-secret-123")
Deploy:
pnpm deploy:domain-a
Then domain-b-tools-worker:
cd ../domain-b-tools-worker
wrangler secret put DOMAIN_SHARED_SECRET
# Use same secret
pnpm deploy:domain-b
3. Get Deployed URLs
After successful deployments, note the URLs:
- Domain A:
https://domain-a-<unique>.workers.dev - Domain B:
https://domain-b-<unique>.workers.dev
4. Configure & Deploy Gateway
Update apps/mcp-gateway-worker/wrangler.toml:
[env.production]
vars = { DOMAIN_A_URL = "https://domain-a-<unique>.workers.dev", DOMAIN_B_URL = "https://domain-b-<unique>.workers.dev", ALLOWED_ORIGINS = "localhost:3000,localhost:8501" }
Deploy gateway:
cd apps/mcp-gateway-worker
wrangler secret put DOMAIN_SHARED_SECRET
# Use same secret
pnpm deploy:gateway
Gateway URL: https://mcp-gateway-<unique>.workers.dev
5. Run Streamlit Client
cd apps/mcp-client-streamlit
pip install -r requirements.txt
streamlit run app.py
Open browser to http://localhost:8501, set MCP URL to the gateway URL + /mcp.
Local Development
All three Workers can run in local dev mode simultaneously:
# Terminal 1
pnpm dev:domain-a
# Terminal 2
pnpm dev:domain-b
# Terminal 3
pnpm dev:gateway
# Terminal 4 (after Workers are running)
cd apps/mcp-client-streamlit
streamlit run app.py
Default local URLs:
- Domain A: http://localhost:8001
- Domain B: http://localhost:8002
- Gateway: http://localhost:8000
- Streamlit: http://localhost:8501
Project Structure
repo-root/
βββ apps/
β βββ mcp-gateway-worker/ # MCP server endpoint
β β βββ src/
β β β βββ index.ts
β β β βββ registry.ts
β β β βββ types.ts
β β βββ package.json
β β βββ wrangler.toml
β β βββ tsconfig.json
β βββ domain-a-tools-worker/ # Domain A RPC tools
β β βββ src/
β β β βββ index.ts
β β β βββ types.ts
β β βββ package.json
β β βββ wrangler.toml
β β βββ tsconfig.json
β βββ domain-b-tools-worker/ # Domain B RPC tools
β β βββ src/
β β β βββ index.ts
β β β βββ types.ts
β β βββ package.json
β β βββ wrangler.toml
β β βββ tsconfig.json
β βββ mcp-client-streamlit/ # Python Streamlit client
β βββ app.py
β βββ requirements.txt
βββ pnpm-workspace.yaml
βββ package.json
βββ README.md
Testing Checklist
After deployment, verify the system:
- tools/list: Returns all 4 tools (2 from Domain A, 2 from Domain B)
- hello: Accepts
{ name: string }, returns greeting message - list-top-customers: Accepts
{ limit: number }, returns mock customer data - sum: Accepts
{ a: number, b: number }, returns sum result - normalize-text: Accepts
{ text, mode: "lower"|"upper"|"title" }, returns normalized text - Scope validation: Request with missing
customers:readheader fails for list-top-customers - Origin validation: Request from unlisted origin is blocked
- Token validation: RPC call without correct gateway token returns 403
Available Scripts
# Development
pnpm dev:gateway # Start gateway in local dev mode
pnpm dev:domain-a # Start domain A in local dev mode
pnpm dev:domain-b # Start domain B in local dev mode
pnpm dev:all # Start all Workers in parallel
# Production Deployment
pnpm deploy:gateway # Deploy gateway to Cloudflare
pnpm deploy:domain-a # Deploy domain A to Cloudflare
pnpm deploy:domain-b # Deploy domain B to Cloudflare
pnpm deploy:all # Deploy all (domains first, then gateway)
# Build
pnpm build # Build all projects
Security Notes
- Shared Secret:
DOMAIN_SHARED_SECRETis a simple shared token between gateway and domain workers (not production-grade; use mTLS in production) - Origin Allowlist: Configured via
ALLOWED_ORIGINSin gateway wrangler.toml - Scope Enforcement: Incoming
x-scopesheader is validated against tool requirements - Secrets Management: Never commit secrets; use
wrangler secretto store them
MCP Specification
The gateway exposes a standard MCP 1.0 server at /mcp using streaming HTTP transport.
Two primary RPC methods:
- tools/list: Discover available tools
- tools/call: Execute a tool with input validation and scope checking
See individual app READMEs for detailed integration examples.
Troubleshooting
"DOMAIN_A_URL is not configured"
- Update wrangler.toml in mcp-gateway-worker with deployed domain URLs
- Redeploy gateway:
pnpm deploy:gateway
401 Unauthorized on domain workers
- Verify
DOMAIN_SHARED_SECRETis set and identical on all workers - Check
x-gateway-tokenheader is included in gateway β domain RPC calls
CORS errors from Streamlit
- Ensure gateway URL is in
ALLOWED_ORIGINSin wrangler.toml - Test with curl first before using Streamlit
Scope rejection errors
- Pass
x-scopes: customers:read,data:readheader in Streamlit UI - Check tool definitions in registry for required scopes
License
MIT
