(input: string | McpProbeEndpointInput)
| 909 | const httpClientLayer = options?.httpClientLayer ?? ctx.httpClientLayer; |
| 910 | |
| 911 | const probeEndpoint = (input: string | McpProbeEndpointInput) => |
| 912 | Effect.gen(function* () { |
| 913 | const endpoint = typeof input === "string" ? input : input.endpoint; |
| 914 | const trimmed = endpoint.trim(); |
| 915 | if (!trimmed) { |
| 916 | return yield* new McpConnectionError({ |
| 917 | transport: "remote", |
| 918 | message: "Endpoint URL is required", |
| 919 | }); |
| 920 | } |
| 921 | |
| 922 | const name = yield* Effect.try({ |
| 923 | try: () => new URL(trimmed).hostname, |
| 924 | catch: () => "mcp", |
| 925 | }).pipe(Effect.orElseSucceed(() => "mcp")); |
| 926 | const slug = deriveMcpNamespace({ endpoint: trimmed }); |
| 927 | |
| 928 | const probeHeaders = typeof input === "string" ? undefined : input.headers; |
| 929 | const probeQueryParams = typeof input === "string" ? undefined : input.queryParams; |
| 930 | |
| 931 | const connector = createMcpConnector({ |
| 932 | transport: "remote", |
| 933 | endpoint: trimmed, |
| 934 | headers: probeHeaders, |
| 935 | queryParams: probeQueryParams, |
| 936 | httpClientLayer, |
| 937 | }); |
| 938 | |
| 939 | const result = yield* discoverTools(connector).pipe( |
| 940 | Effect.map((m) => ({ ok: true as const, manifest: m })), |
| 941 | Effect.catch(() => Effect.succeed({ ok: false as const, manifest: null })), |
| 942 | Effect.withSpan("mcp.plugin.discover_tools"), |
| 943 | ); |
| 944 | |
| 945 | if (result.ok && result.manifest) { |
| 946 | return { |
| 947 | connected: true, |
| 948 | requiresAuthentication: false, |
| 949 | requiresOAuth: false, |
| 950 | supportsDynamicRegistration: false, |
| 951 | name: result.manifest.server?.name ?? name, |
| 952 | slug, |
| 953 | toolCount: result.manifest.tools.length, |
| 954 | serverName: result.manifest.server?.name ?? null, |
| 955 | instructions: result.manifest.server?.instructions ?? null, |
| 956 | } satisfies McpProbeResult; |
| 957 | } |
| 958 | |
| 959 | // Confirm the endpoint actually speaks MCP before classifying it as |
| 960 | // OAuth-protected (an OAuth-protected non-MCP service would |
| 961 | // otherwise be misclassified). |
| 962 | const shape = yield* probeMcpEndpointShape(trimmed, { |
| 963 | httpClientLayer, |
| 964 | headers: probeHeaders, |
| 965 | queryParams: probeQueryParams, |
| 966 | }); |
| 967 | |
| 968 | // A `not-mcp`/auth-required shape only proves the endpoint returned |
nothing calls this directly
no test coverage detected