mock-mcp-server
A test MCP server that validates gateway connectivity, identity propagation, and provides mock tools for testing purposes.
README
mock-mcp-server
A test MCP server that runs behind mcp-auth-gateway.
It exists to validate the platform plumbing — not to be a real product.
Purpose
This server is used to verify:
- gateway → backend MCP server connectivity
- path-based
/mock/mcprouting - gateway-signed
X-MCP-Identityverification - propagation of the user
loginid - the Streamable HTTP MCP transport
- GitOps / Kubernetes deployment
How it fits in
client ──TLS──> mcp-auth-gateway ──/mock/mcp──> mock-mcp-server (this repo)
(Keycloak / OAuth, (verifies X-MCP-Identity,
mints X-MCP-Identity) runs MCP tools)
- It runs only behind the gateway. External clients reach it exclusively via
https://gateway.mcp.aidev.samsungds.net/mock/mcp. - It does NOT do Keycloak / OAuth verification itself. All external auth is the gateway's job.
- It DOES verify the gateway's internal
X-MCP-IdentityJWT on every/mcprequest and rejects anything missing or invalid with401. - Tools read the caller's identity — especially
loginid— through a sharedget_current_user()helper; they never parse HTTP headers directly.
Identity: X-MCP-Identity
The gateway injects a signed internal JWT:
X-MCP-Identity: <gateway-signed-internal-jwt>
Example payload:
{
"iss": "mcp-auth-gateway",
"aud": "mock-mcp-server",
"sub": "keycloak-user-sub",
"loginid": "user.loginid",
"username": "user.name",
"email": "user@example.com",
"groups": ["engineering"],
"scopes": ["mcp:mock:use"],
"request_id": "01J...",
"iat": 1730000000,
"exp": 1730000060
}
Verified on every /mcp request:
- JWT signature
iss == mcp-auth-gatewayaud == mock-mcp-serverexp(not expired)loginidpresentsubpresent
The MVP uses shared-secret HS256 via MCP_IDENTITY_JWT_SECRET. The verifier
lives behind a small abstraction (identity.IdentityVerifier) so a production
RS256 / JWKS implementation can be dropped in without touching tools or
middleware.
loginid usage
loginid is the primary per-user key. Tools use it to build deterministic,
user-scoped mock data (mock_profile, mock_search) and to echo the caller's
identity (echo, whoami).
Endpoints
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | /healthz |
none | liveness |
| GET | /readyz |
none | readiness |
| ANY | /mcp |
X-MCP-Identity (JWT) |
Streamable HTTP MCP endpoint |
Requests to /mcp without a valid X-MCP-Identity are rejected at the HTTP layer
with 401 Unauthorized before reaching any tool.
MCP tools
| Tool | Input | Returns |
|---|---|---|
whoami |
– | full identity asserted by the gateway |
echo |
message: str |
{ loginid, message } |
mock_profile |
– | deterministic mock profile derived from loginid |
mock_search |
query: str |
deterministic, user-scoped mock search results |
Configuration
All configuration is via environment variables.
| Variable | Default | Notes |
|---|---|---|
APP_HOST |
0.0.0.0 |
|
APP_PORT |
8080 |
container port |
MCP_ENDPOINT |
/mcp |
Streamable HTTP path |
MCP_IDENTITY_ISSUER |
mcp-auth-gateway |
required iss |
MCP_IDENTITY_AUDIENCE |
mock-mcp-server |
required aud |
MCP_IDENTITY_ALGORITHM |
HS256 |
verifier algorithm |
MCP_IDENTITY_JWT_SECRET |
– | required unless dev mode is on |
MCP_IDENTITY_DEV_MODE |
false |
if true, unauthenticated calls get a dummy user |
LOG_LEVEL |
info |
MCP_IDENTITY_JWT_SECRETis mandatory in production; the server refuses to start without it.MCP_IDENTITY_DEV_MODE=trueis only for local development. It defaults tofalseand must never be enabled in the cluster.
Local development
Requirements: Python ≥ 3.11 and uv (or pip).
# 1. install
uv venv
uv pip install -e ".[dev]"
# (pip fallback: pip install -r requirements.txt && pip install -e .)
# 2. run the server
export MCP_IDENTITY_JWT_SECRET=dev-secret
export MCP_IDENTITY_DEV_MODE=false
python -m mock_mcp_server.main
Generate a dev identity token
Without the gateway you must supply your own X-MCP-Identity JWT:
export MCP_IDENTITY_JWT_SECRET=dev-secret
python scripts/make-dev-identity-token.py \
--loginid test.user \
--subject test-sub \
--aud mock-mcp-server
# -> export X_MCP_IDENTITY='<jwt>'
eval "$(python scripts/make-dev-identity-token.py --loginid test.user --subject test-sub)"
Test with curl
/mcp speaks Streamable HTTP (JSON-RPC). In stateless JSON mode you can call a
tool directly:
# health (no auth)
curl -s localhost:8080/healthz
# whoami (requires identity)
curl -s localhost:8080/mcp \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-H "X-MCP-Identity: ${X_MCP_IDENTITY}" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"whoami","arguments":{}}}'
# missing identity -> 401
curl -i -s localhost:8080/mcp \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
Test with MCP Inspector
npx @modelcontextprotocol/inspector
In the Inspector UI: choose Streamable HTTP transport, set the URL to
http://localhost:8080/mcp, and add a header X-MCP-Identity with your dev token.
Run the tests
uv run pytest # or: .venv/bin/python -m pytest
Docker
Image name (pushed to cr.aidev.samsungds.net/mcp-platform):
cr.aidev.samsungds.net/mcp-platform/mock-mcp-server:<commit-sha>
Build & push:
COMMIT_SHA=$(git rev-parse --short HEAD)
docker build -t cr.aidev.samsungds.net/mcp-platform/mock-mcp-server:${COMMIT_SHA} .
docker push cr.aidev.samsungds.net/mcp-platform/mock-mcp-server:${COMMIT_SHA}
The image runs as a non-root user, exposes 8080, and ships a HEALTHCHECK
against /healthz. Tag images by commit SHA (no latest in the cluster) so
GitOps pins an exact, reproducible build.
Deployment (mcp-platform-gitops)
Full Kubernetes / GitOps manifests live in mcp-platform-gitops, not here.
This repo only ships the app and image. The gitops repo should deploy it as a
ClusterIP Service with these values:
| Setting | Value |
|---|---|
| Namespace | mcp-gateway |
| Service name | mcp-mock |
| Service type | ClusterIP |
| Container port | 8080 |
| Internal DNS | http://mcp-mock.mcp-gateway.svc.cluster.local:8080 |
| Internal MCP URL | http://mcp-mock.mcp-gateway.svc.cluster.local:8080/mcp |
| External MCP URL | https://gateway.mcp.aidev.samsungds.net/mock/mcp (gateway) |
Required Secret (mcp-identity-jwt, key secret) holds the shared HS256 secret,
which must match the gateway's signing secret.
Container env:
env:
- name: MCP_IDENTITY_JWT_SECRET
valueFrom:
secretKeyRef:
name: mcp-identity-jwt
key: secret
- name: MCP_IDENTITY_ISSUER
value: mcp-auth-gateway
- name: MCP_IDENTITY_AUDIENCE
value: mock-mcp-server
Probes: GET /healthz (liveness), GET /readyz (readiness), both on 8080.
Do NOT create a public Ingress
This service must never be exposed with its own public Ingress / LoadBalancer.
- It performs no external authentication (no Keycloak, no OAuth). It only trusts
the gateway-signed
X-MCP-Identity. A direct public route would let anyone reach/mcpwhile bypassing the gateway's real authentication. - All external access must go through the gateway, which authenticates the user,
mints
X-MCP-Identity, and routes/mock/mcpto thisClusterIPService.
The only external entry point is:
https://gateway.mcp.aidev.samsungds.net/mock/mcp
Project layout
src/mock_mcp_server/
__init__.py
main.py # ASGI app factory + uvicorn entrypoint
settings.py # env-based configuration (fails fast)
identity.py # X-MCP-Identity JWT verification (HS256; RS256-ready)
middleware.py # pure-ASGI identity enforcement (401) + scope injection
context.py # McpUserContext + get_current_user()
tools.py # whoami / echo / mock_profile / mock_search
scripts/
make-dev-identity-token.py
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.