LiteLLM opens a fresh MCP session per tools/call: initialize →
notifications/initialized → tools/call. Demux forwarded everything
to the WS unchanged, so:
- notifications/initialized (no id) hung forwardMcpCall waiting on
a response id, and the 200 JSON-RPC body confused the SDK reader
into cancelling the subsequent tools/call ("duplicate response
suppressed").
- initialize added an unnecessary WS round-trip coupled to
extension availability.
Answer initialize locally, return 202 empty for notifications/*,
set explicit Content-Type + Mcp-Session-Id on the handshake.
SB-48
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Builds on push to main, deploys to infra VM via SSH, health-checks
the /health endpoint after restart.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
LiteLLM rejects server names containing `-`, but customer IDs are
UUIDs. Replace `-` with `_` in both the MCP server alias and key alias.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
At first login, provisionMcpServer() creates a sitebridge-{customer_id}
entry in LiteLLM DB via POST /v1/mcp/server, pointing to the customer's
demux URL. The virtual key is then scoped to ["sitebridge-{customer_id}"]
so LiteLLM routes tool calls only to that customer's WebSocket.
Also adds AGILITON_ACCOUNT_URL config for self-referencing in MCP URLs.
CF-3032
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Use postgres_default, redis_default, agiliton-api external networks.
Remove depends_on (services are in separate compose stacks).
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>