Repository navigation
Positions the gateway as a governance layer rather than a proxy, and makes it deployable on its own.
<dependency>
<groupId>io.github.ashishgituser</groupId>
<artifactId>mcp-gateway-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>Or try it with nothing but Docker: docker compose up --build.
Authorization-aware discovery
tools/list, prompts/list and resources/list now run through the same policy engine as the calls themselves. A caller is only ever shown what it could actually invoke — no more handing every agent the name, description and argument schema of every tool behind the gateway. On by default; mcp.gateway.policy.filter-tool-list=false restores the old behaviour.
The MCP SDK's McpServer can't do this — it answers list requests from collections fixed at build time, identical for every caller — so the gateway now installs its own JSON-RPC handler map on the transport provider.
Prompts and resources are proxied
Tools were not the only way to reach data through MCP. Prompts are namespaced <serverId>__<name> like tools; resources keep their URI, since the URI is meaningful to the client. All three share one policy namespace, so a rule written for a tool cannot be sidestepped by asking for the same content as a resource.
Spring Boot 3.x
Nothing but the Actuator health indicator depends on a Boot-4-only API, and that autoconfiguration is guarded so it is skipped rather than thrown. compat/boot3 boots the published starter on Boot 3.5, drives it with a real MCP client, and runs in CI on every push. Two lines of dependency change — see docs/spring-boot-3.md.
Runs as its own service
mcp-gateway-server is a container-ready distribution for platform teams who want the gateway next to the MCP servers it fronts rather than embedded in an application. Images publish to GHCR:
ghcr.io/ashishgituser/mcp-gateway-server:0.2.0
Survives its upstreams
Sessions open lazily behind a configurable circuit breaker, so one unreachable MCP server no longer fails startup or costs every caller a request timeout. Catalogs refresh on a schedule, so a server deployed after the gateway joins by itself and clients get notifications/tools/list_changed.
Also
- Redis-backed distributed rate limiting (
store: REDIS) — quota shared across replicas instead of multiplied by them, via an atomic Lua token bucket. - Audit argument capture with redaction — off by default; masked, not dropped, when enabled.
- Published benchmarks — +0.30 ms at p50 over calling the upstream directly, with policy, quotas and audit all on.
- New docs: architecture, security model.
Breaking
- The
McpSyncServerbean is gone; useGatewayRouteror the registries. ToolVisibilityis a name predicate rather than aList<Tool>filter.UpstreamServerexposeslistTools()/callTool()/ping()instead of a rawclient().
Full detail in CHANGELOG.md.