| 118 | const oauthClientKey = (owner: Owner, slug: OAuthClientSlug): string => `${owner}:${String(slug)}`; |
| 119 | |
| 120 | const legacyMcpClientMatches = ( |
| 121 | client: OAuthClientSummary, |
| 122 | candidates: ReadonlySet<string>, |
| 123 | config: McpIntegrationConfigType | null, |
| 124 | ): boolean => { |
| 125 | if (!candidates.has(String(client.slug))) return false; |
| 126 | if ( |
| 127 | !config || |
| 128 | config.transport !== "remote" || |
| 129 | !config.authenticationTemplate.some((method: McpAuthMethod) => method.kind === "oauth2") |
| 130 | ) { |
| 131 | return false; |
| 132 | } |
| 133 | return client.grant === "authorization_code" && (client.resource ?? null) === config.endpoint; |
| 134 | }; |
| 135 | |
| 136 | // --------------------------------------------------------------------------- |
| 137 | // Tool annotations carry an `mcp` envelope alongside the executor's policy |