fix(mcp): reject a Hub scope that cannot reach YouTrack #113
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/YT-55-hub-scope-validation"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
scope_has_youtrack_service_idasked only whether the scope carried a token that was neither0-0-0-0-0noroffline_access, so any string passed. The one it had to catch isYOUTRACK_MCP_HUB_CLIENT_ID: an operator putting the OAuth client id in the slot documented as<youtrack-service-id>sailed through the guard, and Hub then issued a well-formed token (aud: ["0-0-0-0-0", "youtrack-mcp"]) that YouTrack answers with401 Invalid tokenon every call, forever, while Hub login, the OAuth dance, and token refresh all look healthy. The guard also ran only ininstall, so the hand-editedmcp.envthat produced this was never checked at all.The check now lives in
youtrack_mcp::hub_scopeand is shared byinstalland startup, so the two cannot drift. It has two modes, because0-0-0-0-0is genuinely ambiguous: it is YouTrack's own service on a bundled/self-hosted instance and Hub on InCloud. Given YouTrack's service id resolved from Hub the check is exact; without one it is syntactic (some service id beyond Hub's universal one, and not this server's client id), which is what a Hub that cannot be read degrades to.yt mcp hub serviceslists Hub's services with id, name, applicationName, and homeUrl and marks YouTrack's, so the id is read off a list instead of copied out of a Hub URL.installresolves the same id and rejects a--hub-scopethat misses it, naming the value to use, before writing any file.AppState::loadre-checks at startup and refuses to boot. When a 401 still happens, the stored token'saudis decoded and, if it lacks the resolved service id, the caller is told the scope is missing YouTrack's service id and which one to configure, rather than getting YouTrack's opaqueInvalid tokenpassed through.Reading Hub's service list uses the client-credentials grant, so docs/deployment.md now asks for that flow on the Hub Service and says what is lost by leaving it off. The docs and
.env.examplealso state the bundled-vs-InCloud split for0-0-0-0-0rather than describing it only as "Hub's universal service id", which is true and is exactly what made the placeholder easy to fill in wrongly.#YT-55