McpVanguard on Railway#
This is the minimum public setup for running the current McpVanguard SSE gateway on Railway so an external evaluator can validate the deployment, auth path, and remote MCP connection flow without local support.
What This Solves#
- Brings up a remote McpVanguard gateway with the start command the repo ships today.
- Exposes a stable public health check.
- Makes the auth header and SSE endpoint explicit.
- Calls out the current semantic and behavioral caveats before evaluation starts.
Uses#
- Railway
- SSE
- MCP
Current Railway Fit#
| Concern | Current behavior |
|---|---|
| Web port | vanguard sse reads Railway's PORT automatically and defaults to 8080 |
| Public routes | GET /health is public; GET /sse and POST /messages are the main remote MCP routes |
| Auth | When VANGUARD_API_KEY is set, /sse and /messages accept either X-Api-Key or Authorization: Bearer ... |
| Start command | Railway config starts vanguard sse --server "$MCP_SERVER_COMMAND" --semantic --behavioral |
| Semantic health | The Railway start command enables semantic checks, so /health can degrade if no cloud provider is configured and Ollama is unreachable |
| Behavioral state | Single-instance deploys work with in-memory state; multi-instance deployments need Redis for shared state |
Railway can use GET /health as the public readiness path, but this endpoint checks more than process liveness. With the current start command, semantic and behavioral layers are enabled, so missing semantic provider configuration can push the endpoint to 503 even if the web process itself is up.
Recommended Service Commands#
The repository already includes Railway and Nixpacks config. The effective start command is:
That command works on Railway because the SSE server binds to 0.0.0.0 and reads PORT directly from the environment.
Required Variables#
| Variable | Required | Why |
|---|---|---|
MCP_SERVER_COMMAND | Yes | The MCP server process Vanguard wraps and protects |
VANGUARD_API_KEY | Yes | Protects the public /sse and /messages routes |
VANGUARD_MODE | Recommended | Set enforce for blocking or audit for shadow-mode evaluation |
Example MCP_SERVER_COMMAND:
Optional Variables#
| Variable | When to set it | Effect |
|---|---|---|
VANGUARD_OPENAI_API_KEY | You want semantic scoring without self-hosting Ollama | Enables the built-in OpenAI semantic provider |
VANGUARD_SEMANTIC_CUSTOM_URL | You have an OpenAI-compatible provider | Points semantic scoring at a custom backend |
VANGUARD_SEMANTIC_CUSTOM_KEY | Your custom provider requires auth | Authenticates the custom semantic backend |
VANGUARD_SEMANTIC_CUSTOM_MODEL | Your custom provider needs an explicit model | Selects the model used for semantic scoring |
VANGUARD_OLLAMA_URL | You have reachable Ollama infrastructure | Lets semantic health pass through Ollama instead of a cloud provider |
VANGUARD_REDIS_URL | You plan to run more than one replica | Shares behavioral session state across instances |
VANGUARD_VEX_URL | You want VEX-backed audit receipts | Sends audit events to a VEX deployment |
VANGUARD_VEX_KEY | Your VEX deployment requires auth | Authenticates the VEX audit write path |
VANGUARD_LOG_LEVEL | You need more deployment detail | Raises log verbosity |
VANGUARD_AUDIT_FORMAT | You want machine-readable audit logs | Switches logs to JSON output |
First Smoke Test#
Once Railway assigns a public domain, check the public health endpoint first:
Expected response shape:
The exact version, layer values, and timestamp can differ. The stable contract is that status, version, layers, and timestamp are present.
Step 2: Connect a Remote MCP Client#
Download the example client config:
Exact config shape:
Artifact produced:
- A remote MCP client entry that routes tool calls through the Railway-hosted McpVanguard gateway
How to inspect it:
- Confirm the client points at
/sse, not the root domain - Confirm the header name is
X-Api-Keyif you are using key-based auth - If your client prefers bearer auth, send the same key as
Authorization: Bearer <key>
Step 3: Verify the Protected Message Path#
Once a client is attached, McpVanguard will receive MCP traffic on:
Expected behavior:
- Authorized requests are proxied to the wrapped MCP server
- Blocked calls return a JSON-RPC error before the underlying MCP server sees them
GET /healthremains public for deployment checks
Evaluation Flow After Deploy#
- Run the public
/healthcheck. - Attach a remote MCP client using the
/sseURL andX-Api-Keyheader. - Confirm the wrapped server responds through Vanguard.
- If you need cryptographic audit receipts, pair the deployment with Deploy on Railway for the VEX service.
Current Limitations#
- The Railway config enables
--semanticby default. If no cloud semantic provider is configured and no reachable Ollama instance exists,/healthcan return503. - Multi-instance deployments should use
VANGUARD_REDIS_URL; otherwise behavioral state is isolated per instance. - The public evaluation path is SSE-first. Stdio examples still exist, but they are not the Railway integration surface.
MCP_SERVER_COMMANDmust be fully runnable inside the Railway container; if it depends on local desktop paths or host-only binaries, the deploy will start but the wrapped MCP server will not behave correctly.