End-to-End Demo

From zero to governed AI agent
in under five minutes.

This is the complete walkthrough. Every feature, in order, on a real stack. No skipped steps. No slides. No marketing copy pretending to be a demo.

Phase 0

Starting the stack

Everything Synapse Relay needs ships in a single docker-compose.yml. One command starts the gateway, the API, the dashboard, Postgres, Redis, the vLLM mock server, OPA, Presidio, Prometheus, and Grafana. On a machine without a GPU, the vLLM mock responds immediately with shaped MCP server code so the full platform is testable without any hardware dependency.

Terminal
❯ git clone https://github.com/vignesh2027/synapse-relay
❯ cd synapse-relay && cp .env.example .env
❯ docker compose up -d
[+] Running 11/11
✔ Container postgres Started
✔ Container redis Started
✔ Container opa Started
✔ Container presidio-analyzer Started
✔ Container presidio-anonymizer Started
✔ Container vllm-mock Started
✔ Container otel-collector Started
✔ Container prometheus Started
✔ Container grafana Started
✔ Container api Started
✔ Container gateway Started
✔ Container web Started
✓ What just started

The full production stack is now running locally. Dashboard at localhost:3000, gateway at localhost:8080, Grafana at localhost:3002. No configuration required beyond copying the example env file.

Phase 1

Generating an MCP server

The demo flow starts by submitting the public Petstore OpenAPI specification to the generator. Synapse Relay fetches the spec, sends it to the vLLM-served model with a carefully engineered prompt, and receives back a complete TypeScript MCP server: tool definitions with full JSON Schema input validation, handler functions that call the real API using fetch, proper error handling, a package.json, and a Dockerfile.

The generation is asynchronous. The API returns a server ID immediately and transitions the record through pending → generating → ready. The dashboard live feed shows the transition in real time via WebSocket. The endpoint URL is returned the moment the server is ready.

❯ node scripts/seed.js
[0] Waiting for API to be healthy...
[0] API is ready
[1] Logging in as admin...
[1] Logged in as admin@synapse-relay.local (owner)
[2] Generating MCP server from Petstore OpenAPI spec...
[2] Server queued: 3f8a21bc-...
[3] Polling until MCP server is ready...
......
[3] Server ready! Endpoint: http://localhost:8080/mcp/3f8a21bc-...
ℹ What the model generated

The vLLM-served model produced a complete MCP server with 12 tool definitions — one per Petstore endpoint — each with properly typed JSON Schema input validation. The handlers use the Petstore base URL from the spec's servers array. The whole file is under 300 lines and compiles with zero warnings.

Phase 2

First tool call — the happy path

With the MCP server ready, the demo sends a tools/call JSON-RPC request directly to the gateway endpoint. This is the exact same request Claude Desktop, Cursor, or any MCP-compatible agent would send.

The call travels through the full pipeline: rate limit check passes, OPA policy evaluates to allow, no PII is detected in the benign input, no approval is required, the call is forwarded to the upstream server, the response comes back, and the entire transaction is logged to PostgreSQL and broadcast to every connected dashboard client via WebSocket.

The round trip adds approximately 8 milliseconds of overhead. The latency appears in the dashboard's live feed within 100 milliseconds of the call completing.

CALL
list_items → rate limit: ok · policy: allow · pii: none 8ms · completed
✓ Live in the dashboard

Open localhost:3000. The call appears in the Live Feed table within a second, showing tool name, status badge, latency, and a timestamp. The latency chart updates. The call count increments. Every subsequent call streams in the same way — no refresh needed, no polling, pure WebSocket push.

Phase 3

PII enters the payload

The demo now sends a tool call that includes a real email address and a Social Security Number embedded in the argument payload — simulating the kind of context that agents frequently include when reasoning about user data.

The gateway extracts the arguments and passes them to Microsoft Presidio's analyzer. Presidio identifies two entities: an EMAIL_ADDRESS and a US_SSN. The anonymizer replaces both with typed placeholder tokens. The redacted version is what gets logged. The original — unchanged — is what gets forwarded to the tool.

The result: the tool sees the real data it needs to function. The audit log never contains personal information. Compliance requirements are met automatically, without any changes to the agent or the tool.

CALL
get_item → rate limit: ok · policy: allow 14ms
PII
Detected: EMAIL_ADDRESS, US_SSN redacted before log
DONE
get_item input redacted · output clean · logged completed
⚠ What you see in the Audit Log

Open the Audit Log tab and expand this call. The Redacted Input panel shows "context": "Looking up <EMAIL> whose SSN is <US_SSN>". The PII badge is visible. The Prometheus counter synapse_relay_pii_detections_total has incremented. The Grafana PII Detections pie chart shows two new entries.

Phase 4

The destructive call — approval gate

The demo sends a delete_item call. The OPA policy's Rego rules match the word "delete" in the tool name and evaluate requires_approval as true.

The gateway does not forward this call. It creates an ApprovalRequest record in PostgreSQL, increments the synapse_relay_pending_approvals gauge, and broadcasts an approval:required event to the dashboard. The agent receives a JSON-RPC response with status: "approval_pending" and an approval ID.

The Approvals tab in the dashboard shows the held action with the redacted input visible to the reviewer. The approval request has a 10-minute expiry. Within that window, an owner or admin can approve or deny it. The agent waits.

CALL
delete_item → policy: requires_approval held
APPROVAL
ID: ar-8c2f... · expires in 10m · pending human review dashboard alert sent
Agent receives
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"status": "approval_pending",
"approval_id": "ar-8c2f9d41-...",
"message": "This action requires human approval."
}
}
ℹ Approving from the dashboard

Navigate to localhost:3000/dashboard/approvals. The delete call is listed with the redacted arguments visible and an expiry countdown. Click Approve — the tool call is forwarded. Click Deny — it is cancelled. Either decision is logged with the reviewer's identity and timestamp. The Grafana gauge drops to zero on resolution.

Phase 5

Importing a connector

The demo imports a GitHub connector from Composio. In a real deployment with a valid API key, this fetches the full list of GitHub actions from Composio's registry — create issue, list PRs, search code, add comment, and dozens more — and wraps each one into an MCP tool definition automatically. Without an API key, the platform generates a representative demo connector with the core tools to illustrate the shape of the result.

The imported connector immediately appears in both the Connector Hub and the MCP Servers list with its full tool registry. The endpoint URL is available instantly. An agent can call GitHub tools through Synapse Relay within seconds of the import completing — with all the same governance, PII redaction, and observability applied to every action.

[7] Importing a demo Composio connector (github)...
[7] Connector imported: Composio — github (8 tools)
Tools available:
github_list github_get
github_create github_search
github_comment github_list_prs
github_get_pr github_get_file
Phase 6

Analytics and the audit trail

After running the demo flow, the Analytics page shows a complete picture of everything that happened. Total calls broken out by status. Error rate. Average and p95 latency per tool. Token consumption. PII detection count. All filterable by time window — last hour, last 24 hours, last 7 days, last 30 days.

The Audit Log shows every single call in reverse chronological order. Each row is expandable to reveal the full redacted input, redacted output, error message if any, trace ID for correlation with the Grafana distributed tracing view, and span ID. The search bar filters by tool name. The status dropdown filters by outcome. Pagination handles millions of records efficiently through PostgreSQL's index-backed queries.

The Grafana dashboard — pre-wired and provisioned automatically on first start — shows nine panels: call rate timeseries, error rate timeseries, latency percentiles (p50/p95/p99), policy decision pie chart, PII detection breakdown by entity type, top tools by volume, pending approvals gauge, active connections gauge, and a per-server call distribution chart.

[8] Fetching analytics summary...
[8] Analytics:
list_items calls: 3 errors: 0 avg:8ms
get_item calls: 1 errors: 0 avg:14ms
delete_item calls: 1 errors: 0 avg:6ms
✓ Demo flow complete!
Dashboard: http://localhost:3000
Gateway: http://localhost:8080
Grafana: http://localhost:3002 (admin/changeme)
Prometheus: http://localhost:9090
Phase 7

Switching to a real GPU

Everything above ran on the CPU mock. Switching to real vLLM changes two things: the generated MCP servers become significantly more sophisticated (handling more edge cases, generating better error messages, following the OpenAPI spec more precisely) and the generation time stays fast because vLLM's PagedAttention and continuous batching keep the GPU fully utilized across concurrent requests.

The override is a single compose file. No code changes. No configuration migrations. The API and gateway never know the difference — they speak the OpenAI-compatible API regardless of whether vLLM is behind it or the mock server.

For a 32B model on a single A100 80GB, generation of a medium-complexity MCP server takes approximately 4 seconds. For a 7B model on a consumer RTX 4090, approximately 2 seconds. In both cases the output is validated TypeScript that compiles and runs immediately.

You've seen everything.

Read the architecture to understand how the pieces fit. See the comparison to understand why nothing else gets this close. Start the stack to make it yours.

Read Architecture → See Comparison →