94 lines · 3.7 KB · TypeScript
RawDownload
// Selfhost-only: on a multi-method MCP integration, the connection's CHOSEN// method is what renders the credential on the wire. A real MCP test server// (in this test process — the selfhost dev server dials it over loopback)// only accepts `Authorization: Bearer <token>`. The integration declares BOTH// OAuth and a bearer-header method; a connection created through the header// method must discover the server's tools, and the recorded requests must// carry the rendered header — proving template selection by slug, not by// "whatever the config says".import { randomBytes } from "node:crypto"; import { expect } from "@effect/vitest";import { Effect } from "effect";import { composePluginApi } from "@executor-js/api/server";import { mcpHttpPlugin } from "@executor-js/plugin-mcp/api";import { makeGreetingMcpServer, serveMcpServer } from "@executor-js/plugin-mcp/testing";import { AuthTemplateSlug, ConnectionName, IntegrationSlug } from "@executor-js/sdk/shared"; import { scenario } from "../src/scenario"; const api = composePluginApi([mcpHttpPlugin()] as const); scenario(  "Auth methods · the connection's chosen method renders the credential on the wire",  { needs: ["api"] },  (ctx) =>    Effect.scoped(      Effect.gen(function* () {        const token = `e2e-key-${randomBytes(6).toString("hex")}`;        const server = yield* serveMcpServer(() => makeGreetingMcpServer(), {          auth: {            validateAuthorization: (authorization) =>              Effect.succeed(authorization === `Bearer ${token}`),          },        });         const identity = yield* ctx.target.newIdentity();        const client = yield* ctx.api.client(api, identity);        const slug = freshSlug("mcp-wire-auth");         // Two declared methods — the connection must pick the right one.        yield* client.mcp.addServer({          payload: {            transport: "remote",            name: "Wire-auth MCP",            endpoint: server.endpoint,            slug,            authenticationTemplate: [              { kind: "oauth2" },              {                type: "apiKey",                headers: { Authorization: ["Bearer ", { type: "variable", name: "token" }] },              },            ],          },        });         yield* Effect.gen(function* () {          // Create the connection through the HEADER method (template slug          // "header") with a pasted key. Tool discovery dials the server with          // the rendered credential at create time.          yield* client.connections.create({            payload: {              owner: "org",              name: ConnectionName.make("wire-auth-key"),              integration: IntegrationSlug.make(slug),              template: AuthTemplateSlug.make("header"),              value: token,            },          });           const tools = yield* client.tools.list();          const mine = tools.filter((tool) => String(tool.integration) === slug);          expect(            mine.map((tool) => String(tool.name)).join(", "),            "discovery through the header method found the server's tool",          ).toContain("simple_echo");           const requests = yield* server.requests;          expect(            requests.some((request) => request.authorization === `Bearer ${token}`),            "the server saw the credential rendered through the chosen method",          ).toBe(true);        }).pipe(          Effect.ensuring(            client.mcp              .removeServer({ params: { slug: IntegrationSlug.make(slug) } })              .pipe(Effect.ignore),          ),        );      }),    ),); const freshSlug = (prefix: string): string => `${prefix}-${randomBytes(4).toString("hex")}`;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t