chore: remove the old toolset MCP hosting code path
AIM-731 (2 of 3). Stacked on #8125.
Customer impact: none. On the prod replica (2026-10-26), every non-deleted toolset in a live project has a hosted MCP server. The 52 toolsets without one are all in deleted projects (40 MCP-enabled, 12 not). In the last 30 days, the legacy fallback reached a toolset without a hosted server only once: 4 requests on 10-12, to a toolset in a deleted project.
Summary
- A toolset without a canonical hosted MCP server is not hosted. The toolset's own hosting columns no longer stand in when it has none:
- The legacy
/mcp/<slug>fallback, install page, export and well-known metadata treat such a toolset as not found. - Toolset views report it as disabled with no address.
- It is no longer plugin-eligible, a mint target, or an issuer owner.
- The usage counts, the indexing scan, access visibility and the external MCP migration ignore it.
- Admin no longer lists
toolset_onlyservers: the project server count and health view covermcp_serversrows only.
- The legacy
- Toolset views: hosting fields now come from the hosted server: its servable endpoint, else its legacy alias (which still serves until AIM-670), else nothing. Without a server, a toolset reads as disabled with no address.
- External MCP migration: issuers now come from the server fronting the toolset. A toolset without a hosted server is now listed for deletion, because nothing serves it.
- Logging: a legacy alias that resolves to a toolset without a hosted server now logs a warning (
legacy MCP alias names a toolset without a hosted MCP server) before the 404, so the rollout can be watched. - Writers removed:
CreateToolsetand the clone no longer pass hosting values.- The issuer migration no longer moves toolset issuer columns.
- The external MCP migration no longer runs
DisableToolset; the switched server is not canonical, so the alias stops serving anyway. - The
UpdateToolsetandUpdateToolsetUserSessionIssuertest fixtures lose their hosting fields.
- Retired:
hostedmcp.BackfillSyncand thehosted-mcp-wrappersmigration tool (cmd/tools/migrations/hostedmcpbackfill).testenv.LinkRetiredOAuthProxy: the column it set is dropped on main (#8020).
- New test fixtures:
testenv.SetHostedMCPwrites visibility, issuer and endpoint onto the canonical server.testenv.SetLegacyAliassets the alias.- The
oauthtestlegacy fixtures now create an endpointless canonical server with an alias.
- No API fields are removed. The toolset response hosting fields stay and are derived from the server only.
Motivation
Code must stop reading the toolset MCP hosting columns before AIM-671 drops them. The only remaining readers here are the wrapperless fallbacks, and those serve nothing real:
- New toolsets always get a canonical server: create and clone both call
hostedmcp.CreateCanonical. - The prod replica had 0 live wrapperless toolsets with an address. The 52 that exist are in soft-deleted projects.
After this PR, only the legacy alias (mcp_slug/custom_domain_id, owned by AIM-670) still names the columns. The next PR fences that off.
Rollout
-
Pre-merge check: Datadog shows 4 fallback hits with
canonical_wrapper=false, all from one toolset on 2026-10-12. Confirm on the replica that it now has a hosted server or is dead. -
Admin and API enums keep
toolset_onlyand the issuer reference kindtoolsetfor wire compatibility. Both are no longer emitted. Admin MCP needs no change: its health tool only reads the source the API reports. -
Old pods still serve a wrapperless toolset from its columns. Since there are none live, a mixed fleet behaves the same.
-
Old pods' toolset create and clone still write
mcp_slug = NULL/mcp_enabled = false, which this code ignores. -
Reverting restores the column fallback.
- One write here can leave stale state for a revert: deleting an issuer that only a wrapperless toolset's column names.
- The reverted code then fails closed for that toolset: its alias returns 401 and the well-known metadata returns 404.
š¤ Generated with Claude Code