fix(compass-agent): derive LITELLM_MCP_URL from the delivered base URL (RIG-2674) - #587
Open
rigel-mintaka wants to merge 2 commits into
Open
fix(compass-agent): derive LITELLM_MCP_URL from the delivered base URL (RIG-2674)#587rigel-mintaka wants to merge 2 commits into
rigel-mintaka wants to merge 2 commits into
Conversation
…L (RIG-2674)
The fleet mcp.json declares the LiteLLM MCP server as
`{ "url": "${LITELLM_MCP_URL}", ... }`, expanded from the agent's
process.env at MCP connect. But `LITELLM_MCP_URL` is a DERIVED var, not a
stored secret: in the wave the personal SOPS loader computes it from
`LITELLM_BASE_URL` (secrets-env.nix). Compass's keyring delivers
`LITELLM_BASE_URL` + `LITELLM_API_KEY` but NOT the derived MCP URL, so in a
live Compass agent `${LITELLM_MCP_URL}` expands empty and the LiteLLM MCP
server fails to connect.
Derive it in the agent-env assembly (Matt-ruled option (b)) rather than
seeding a second secret: single source of truth, no base/MCP drift, and
Compass owns the load-bearing path rule in code. The rule mirrors the loader
byte-for-byte: strip one trailing slash, strip a trailing `/v1`, append
`/mcp/`. The trailing slash is load-bearing -- LiteLLM 307-redirects `/mcp`
and MCP clients don't re-POST across the redirect. So
`https://host/v1` -> `https://host/mcp/`.
`deriveLitellmMcpUrl` is a pure resolver (sibling of `resolveModelSelector`);
`main` fills the gap AFTER sourcing the env file and BEFORE the MCP connect,
only when `LITELLM_MCP_URL` is not already present -- an explicitly-delivered
value still wins (same file-defines-it posture as the env merge). Unset/blank
base derives nothing (no gateway configured).
Tests: pure-resolver unit block (derive, trailing-slash-then-v1 order,
no-/v1 base, load-bearing slash, unset/blank/trim) + two `main` integration
tests (derive lands in process.env; explicit URL wins). Red-green proven by
mutation on both the call-site guard and the trailing-slash strip. Full
compass-agent suite green for the touched files; no new deps (no FOD bump).
Spec-impact: none (activation of an existing delivery contract; no proto or
public-API change).
Co-authored-by: Matt Wilkinson <matt@rigel.build>
|
Compass engineering docs preview: https://compass-agent-rig-2674-deriv.compass-eng-docs.pages.dev Deployed from |
… connect (RIG-2674)
Review-fold: the existing integration test asserted the derived value lands
in process.env only after main() resolves, which would still pass if a future
refactor moved the derive block AFTER the MCP manager connects -- silently
breaking the fix (the connector reads ${LITELLM_MCP_URL} from process.env at
dial time). This adds a test that captures process.env at the connect instant
via the connectMcp seam (main calls it unconditionally, after the env merge
and before session construction), pinning the load-bearing ordering. Non-vacuity:
disabling the derive reds it at the capture point.
Spec-impact: none (test-only; strengthens the RIG-2674 ordering invariant).
Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka
marked this pull request as ready for review
August 24, 2026 17:54
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The fleet mcp.json declares the LiteLLM MCP server as
{ "url": "${LITELLM_MCP_URL}", ... }, expanded from the agent'sprocess.env at MCP connect. But
LITELLM_MCP_URLis a DERIVED var, not astored secret: in the wave the personal SOPS loader computes it from
LITELLM_BASE_URL(secrets-env.nix). Compass's keyring deliversLITELLM_BASE_URL+LITELLM_API_KEYbut NOT the derived MCP URL, so in alive Compass agent
${LITELLM_MCP_URL}expands empty and the LiteLLM MCPserver fails to connect.
Derive it in the agent-env assembly (Matt-ruled option (b)) rather than
seeding a second secret: single source of truth, no base/MCP drift, and
Compass owns the load-bearing path rule in code. The rule mirrors the loader
byte-for-byte: strip one trailing slash, strip a trailing
/v1, append/mcp/. The trailing slash is load-bearing -- LiteLLM 307-redirects/mcpand MCP clients don't re-POST across the redirect. So
https://host/v1->https://host/mcp/.deriveLitellmMcpUrlis a pure resolver (sibling ofresolveModelSelector);mainfills the gap AFTER sourcing the env file and BEFORE the MCP connect,only when
LITELLM_MCP_URLis not already present -- an explicitly-deliveredvalue still wins (same file-defines-it posture as the env merge). Unset/blank
base derives nothing (no gateway configured).
Tests: pure-resolver unit block (derive, trailing-slash-then-v1 order,
no-/v1 base, load-bearing slash, unset/blank/trim) + two
mainintegrationtests (derive lands in process.env; explicit URL wins). Red-green proven by
mutation on both the call-site guard and the trailing-slash strip. Full
compass-agent suite green for the touched files; no new deps (no FOD bump).
Spec-impact: none (activation of an existing delivery contract; no proto or
public-API change).
Co-authored-by: Matt Wilkinson matt@rigel.build