GitShow/modelcontextprotocol/example-remote-server
modelcontextprotocol

example-remote-server

A hosted version of the Everything server - for demonstration and testing purposes, hosted at https://example-server.modelcontextprotocol.io/mcp

by modelcontextprotocol
Star on GitHubForknpm

TypeScript

76 stars31 forks7 contributorsActive · 2d agoSince 2025MIT

Meet the team

See all 7 on GitHub →
jerome3o-anthropic
jerome3o-anthropic66 contributions
bhosmer-ant
bhosmer-ant54 contributions
ochafik
ochafik20 contributions
claude
claude4 contributions
pcarleton
pcarleton2 contributions
Guro
Guro2 contributions
antonpk1
antonpk11 contribution

Languages

View on GitHub →
TypeScript87.3%
Shell8.7%
HTML2.3%
CSS1.4%
JavaScript0.3%

Commit activity

Last 12 weeks · 8 commits

Full graph →

Community health

5 of 6 standards met

Community profile →
87
✓README✓License✓Contributing✓Code of Conduct○Issue Template✓PR Template

Recent PRs & issues

Active · 6 in progress · Last activity 2d ago
See all on GitHub →
ennsharma
Serve OAuth protected resource metadata (RFC 9728) on the MCP serverOpenPR

Fixes #22. The MCP module's already advertises a URL in 401 headers (via ), but nothing ever served that path — so clients that follow the spec's discovery flow got a 404. In EXTERNAL mode this made authorization-server discovery effectively impossible except through the legacy shim. Changes (in , mirroring the existing inline metadata shim style): Serve RFC 9728 Protected Resource Metadata at (the exact URL advertised in 401s) and (RFC 9728 §3.1 path insertion, for clients that derive the metadata URL from the endpoint themselves). points at the in-process server in INTERNAL mode and at in EXTERNAL mode. Kept the shim rather than removing it as the issue suggests: clients of the 2025-03-26 spec revision discover auth by querying that path on the MCP server directly, and in EXTERNAL mode the shim correctly points them at the external AS endpoints. It's now commented as a back-compat shim; happy to remove it instead if you'd prefer strict current-spec behavior. Verified** by booting both modes and curling: EXTERNAL (): both PRM endpoints return , and the URL in the 401's now resolves. INTERNAL: PRM returns the server itself as the authorization server. , , and the jest suite (79 tests, 6 suites) all pass. 🤖 Generated with Claude Code

ennsharma · 2w ago
ennsharma
Clean up session ownership keys in RedisOpenPR

Fixes #21. keys were written without a TTL and never deleted when the transport was cleaned up, so they accumulated in Redis indefinitely. Two complementary changes: 1. Deterministic cleanup: now deletes the session's ownership key. runs on every session-termination path — client ( → ), control messages, and the 5-minute inactivity timeout — so a finished session always removes its key. 2. Safety-net TTL: now sets a 30-minute on the key, and refreshes it on each successful (authorized) check. Live sessions therefore never expire mid-flight — every request slides the TTL — while keys orphaned by a crashed process (where never ran) still get reaped by Redis. The TTL refresh happens only on successful validation, so an attacker probing someone else's session id can't keep a foreign key alive. Added unit tests covering: TTL set on write, TTL refresh on authorized validation only, key removal on transport close, and key removal via SHUTDOWN control message. , on the touched files, and the full jest suite (83 tests, 6 suites) all pass. 🤖 Generated with Claude Code

ennsharma · 2w ago

Recent fixes

View closed PRs →
ochafik
Add lazy-auth example server (mounted at /lazy-auth)MergedPR

What this does Adds the example, served at alongside the other example MCP App servers, and bumps the ext-apps example family to 1.7.4. Unlike the other examples (plain factories behind the stateless handler), lazy-auth's value is its HTTP layer — public tools work unauthenticated; protected tools answer + ; a built-in mock OAuth authorization server completes the flow. So it mounts its full Express app () under . Why now / what's blocked without it The mobile clauditor e2e specs are blocked on reaching lazy-auth at (TTL-scoped path → 1-hour tokens, so 30s defaults don't expire mid-test on slow mobile runs). What changed — mounts the app before the host middleware, and adds the RFC 8414/9728 path-insertion well-known rewrite ( → into the mount). MCP SDK clients only try the insertion form for , so this rewrite is required for discovery under a base path. / — early mount (so the example's CORS/body handling stay self-contained), splash + console listings. No new deploy config: for the example is derived from this server's own (already the source of truth for the host's OAuth issuer). An explicit still wins (e.g. a tunnel). Tests on an ephemeral port fall back to the package's per-request Host resolution. Dependency bump: ext-apps + the example server family to 1.7.4 (which carries the base-path mount support in ). Lockfile resolves entirely via npmjs. Integration test covering the full flow: public /, on the protected tool, mount-prefixed discovery metadata, TTL-path PRM, and the PKCE → token → authed round trip. How we know it works + + + all green against the published 1.7.4 (7 suites / 85 tests, lazy-auth integration included), verified in a linux container matching CI. Driven additionally with the real client discovery machinery ( → PRM → → with PKCE) — full discovery + auth + silent refresh pass, on both and . Prod-like boot (, no ) advertises correct mount-prefixed OAuth URLs, trailing slash normalized.

ochafik · 2d ago
ochafik
Add lazy-auth example server (mounted at /lazy-auth)MergedPR

What this does Adds the example, served at alongside the other example MCP App servers, and bumps the ext-apps example family to 1.7.3. Unlike the other examples (plain factories behind the stateless handler), lazy-auth's value is its HTTP layer — public tools work unauthenticated; protected tools answer + ; a built-in mock OAuth authorization server completes the flow. So it mounts its full Express app () under . Why now / what's blocked without it The mobile clauditor e2e specs are blocked on reaching lazy-auth at (TTL-scoped path → 1-hour tokens, so 30s defaults don't expire mid-test on slow mobile runs). What changed — mounts the app before the host middleware, and adds the RFC 8414/9728 path-insertion well-known rewrite ( → into the mount). MCP SDK clients only try the insertion form for , so this rewrite is required for discovery under a base path. / — early mount (so the example's CORS/body handling stay self-contained), splash + console listings. No new deploy config: for the example is derived from this server's own (already the source of truth for the host's OAuth issuer). An explicit still wins (e.g. a tunnel). Tests on an ephemeral port fall back to the package's per-request Host resolution. Integration test covering the full flow: public /, on the protected tool, mount-prefixed discovery metadata, TTL-path PRM, and the PKCE → token → authed round trip. How we know it works , , all green (7 suites / 85 tests, lazy-auth integration included), verified in a linux container matching CI. Driven additionally with the real client discovery machinery ( → PRM → → with PKCE) — full discovery + auth + silent refresh pass, on both and . Prod-like boot (, no ) advertises correct mount-prefixed OAuth URLs, trailing slash normalized. ⚠️ Draft: blocked on a release The base-path mount support is not yet in a published release** of . This branch temporarily pins the dependency to the merged-PR preview build (, from modelcontextprotocol/ext-apps#683) so CI runs against the real code. Before merge, the finishing commit flips both and to the registry and regenerates the lockfile against npmjs. Depends on: ext-apps#683 (merged) → next ext-apps release.

ochafik · 3w ago
ochafik
chore: bump ext-apps + example servers to 1.7.1, sdk to 1.29.0MergedPR

Summary Updates the mounted MCP App example servers and to 1.7.1 (release notes). ext-apps@1.7.x peers on , so this also bumps the pinned sdk from → and adapts to its refactor (now wraps a web-standard transport via ). Code changes — is now a readonly getter on the Node wrapper; inject it (and ) on the underlying web-standard transport so resumed sessions pass . Also guard , which is now optional on . — now routes through , so the mock needs /////, and the response header now arrives via instead of . [!NOTE] The resume path reaches into the private field to set and . SDK 1.29 doesn't expose a public way to attach a pre-known session ID to a fresh transport (the previous approach of assigning directly no longer compiles since it's now a getter). The underlying is a public writable field — only the path to reach it is private. Worth raising upstream for a supported API; tracked as a follow-up. Test Plan ✅ ✅ ✅ — 79/79 ✅ Smoke-tested locally: and both return valid responses

ochafik · 2mo ago
Structured data for AI agents

Repository: modelcontextprotocol/example-remote-server. Description: A hosted version of the Everything server - for demonstration and testing purposes, hosted at https://example-server.modelcontextprotocol.io/mcp Stars: 76, Forks: 31. Primary language: TypeScript. Languages: TypeScript (87.3%), Shell (8.7%), HTML (2.3%), CSS (1.4%), JavaScript (0.3%). License: MIT. Open PRs: 6, open issues: 4. Last activity: 2d ago. Community health: 87%. Top contributors: jerome3o-anthropic, bhosmer-ant, ochafik, claude, pcarleton, Guro, antonpk1.

·@ofershap

Replace github.com with gitshow.dev