MCP Gateway Demo MCP Server

Local setup required. This server has to be cloned and prepared on your machine before you register it in Claude Code.
1

Set the server up locally

Run this once to clone and prepare the server before adding it to Claude Code.

Run in terminal
npm install
npm start
2

Register it in Claude Code

After the local setup is done, run this command to point Claude Code at the built server.

Run in terminal
claude mcp add -e "MCP_RESOURCE_URI=${MCP_RESOURCE_URI}" -e "AUTH_ISSUER=${AUTH_ISSUER}" -e "JWT_SECRET=${JWT_SECRET}" mcp-gateway-demo -- node "<FULL_PATH_TO_MCP_GATEWAY_DEMO>/dist/index.js"

Replace <FULL_PATH_TO_MCP_GATEWAY_DEMO>/dist/index.js with the actual folder you prepared in step 1.

Required:MCP_RESOURCE_URIAUTH_ISSUERJWT_SECRET+ 1 optional
README.md

Express-based MCP server with full OAuth 2.1 authorization and RFC9728 support.

MCP Gateway Demo

Express 实现的 MCP Server,带完整 OAuth 2.1 授权(符合 MCP AuthorizationRFC9728 Protected Resource Metadata)。

功能

  • MCP Server(资源服务器)
    • Streamable HTTP 传输:POST /mcpGET /mcp(SSE)
    • 未认证请求返回 401,并带 WWW-Authenticate: Bearer resource_metadata=..., scope=...
    • JWT 校验(audience = MCP 资源 URI),不足 scope 时返回 403 insufficient_scope
  • Protected Resource Metadata(RFC9728)
    • GET /.well-known/oauth-protected-resource 返回 resourceauthorization_serversscopes_supported
    • 可选:GET /.well-known/oauth-protected-resource/mcp
  • 内置 Authorization Server(Demo)
    • GET /.well-known/oauth-authorization-server(RFC8414)
    • GET /.well-known/openid-configuration(含 code_challenge_methods_supported
    • GET /oauth/authorize(授权码 + PKCE S256)
    • POST /oauth/token(换发 JWT,aud = 请求中的 resource

环境变量

变量 说明 示例
PORT HTTP 端口 3000
MCP_RESOURCE_URI MCP 资源 canonical URI(用于 aud 校验与 metadata) http://localhost:3000
AUTH_ISSUER 授权服务器 issuer(可与 MCP 同源) http://localhost:3000
JWT_SECRET HS256 密钥(生产建议 RS256 + JWKS) 至少 32 字符

复制 .env.example.env 并修改。

启动

npm install
npm start

开发时:

npm run dev

联调(MCP 客户端,如 Cursor)

  1. 发现
    客户端先请求 MCP 端点(无 token),收到 401 后从 WWW-Authenticateresource_metadata,再 GET 该 URL 得到 authorization_serversscopes_supported

  2. 授权
    客户端用 authorization_servers 中任一项作为 issuer,请求其 /.well-known/oauth-authorization-server,得到 authorization_endpointtoken_endpointcode_challenge_methods_supported
    使用授权码 + PKCE(S256),并在授权与 token 请求中带上 resource = MCP 的 canonical URI(如 http://localhost:3000)。

  3. 访问 MCP
    请求 POST/GET /mcp 时在 Header 中带 Authorization: Bearer <access_token>,且 Accept: application/json, text/event-stream

本地测试时,可将 MCP 服务器 URL 设为 http://localhost:3000,授权服务器与资源服务器均为同源,使用上述发现与授权流程即可。

手动测试(curl)

# 1. 未认证 → 401
curl -i -X POST http://localhost:3000/mcp -H "Content-Type: application/json" -d '{}'

# 2. Protected Resource Metadata
curl -s http://localhost:3000/.well-known/oauth-protected-resource

# 3. Authorization Server 发现
curl -s http://localhost:3000/.well-known/oauth-authorization-server

# 4. 授权(浏览器或带 approve=yes 的 GET)
# 生成 PKCE:node -e "const c=require('crypto'); const v=c.randomBytes(32).toString('base64url'); console.log('verifier:', v, 'challenge:', c.createHash('sha256').update(v).digest('base64url'));"
# 在浏览器打开 /oauth/authorize?response_type=code&client_id=test&redirect_uri=http://localhost:3000/callback&scope=mcp:read%20mcp:write&state=1&code_challenge=<CHALLENGE>&code_challenge_method=S256&resource=http://localhost:3000
# 同意后从 redirect 的 URL 中取出 code

# 5. 换 Token
curl -s -X POST http://localhost:3000/oauth/token -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code&code=<CODE>&redirect_uri=http://localhost:3000/callback&client_id=test&code_verifier=<VERIFIER>&resource=http://localhost:3000"

# 6. 带 Token 调用 MCP
curl -s -X POST http://localhost:3000/mcp -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'

安全说明

  • 生产环境请使用 HTTPS
  • JWT_SECRET 需足够强,或改用 RS256 + JWKS。
  • 本 Demo 允许的 redirect_uri 包含 localhost;生产应严格限制为已注册的 redirect_uri。

Environment Variables

PORTHTTP port for the server
MCP_RESOURCE_URIrequiredMCP resource canonical URI used for audience validation and metadata
AUTH_ISSUERrequiredAuthorization server issuer URL
JWT_SECRETrequiredHS256 secret key for signing tokens

Configuration

claude_desktop_config.json
{"mcpServers": {"mcp-gateway-demo": {"command": "node", "args": ["/path/to/mcp-gateway-demo/index.js"], "env": {"PORT": "3000", "MCP_RESOURCE_URI": "http://localhost:3000", "AUTH_ISSUER": "http://localhost:3000", "JWT_SECRET": "your-secret-key"}}}}

Try it

How do I configure an MCP client to authenticate with this gateway using the OAuth 2.1 flow?
Explain how the RFC9728 protected resource metadata is exposed by this server.
What are the steps to perform a manual token exchange using the /oauth/token endpoint?
How can I verify the JWT audience validation for my MCP resource URI?

Frequently Asked Questions

What are the key features of MCP Gateway Demo?

Full OAuth 2.1 authorization support. RFC9728 Protected Resource Metadata implementation. Streamable HTTP transport for MCP (POST and SSE). Built-in Authorization Server for testing PKCE and authorization code flows. JWT-based authentication with scope validation.

What can I use MCP Gateway Demo for?

Developing and testing secure MCP server implementations with OAuth 2.1. Learning how to implement RFC9728 protected resource metadata in MCP. Building a reference architecture for authenticated MCP communication. Testing MCP client discovery and authorization flows.

How do I install MCP Gateway Demo?

Install MCP Gateway Demo by running: npm install && npm start

What MCP clients work with MCP Gateway Demo?

MCP Gateway Demo works with any MCP-compatible client including Claude Desktop, Claude Code, Cursor, and other editors with MCP support.

Turn this server into reusable context

Keep MCP Gateway Demo docs, env vars, and workflow notes in Conare so your agent carries them across sessions.

Need the old visual installer? Open Conare IDE.
Open Conare