// Cross-target: multi-method authentication — an integration declares SEVERAL// auth methods and a connection picks one by template slug. Covers the unified// placements model: one apikey method can mix header and query placements,// each rendered from its own credential input; the merge-append configureAuth// flow (a custom API key must never displace a detected OAuth method);// declaring a method on a server that advertises none; GraphQL's multi-method// add — and the EXTREME case end-to-end: an integration declaring// [oauth] [bearer header + team-id query] [bearer header] [query token],// one connection per credential method, every invocation asserted against// what a real recording MCP server received.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 { makeEchoMcpServer, serveMcpServer } from "@executor-js/plugin-mcp/testing";import { graphqlHttpPlugin } from "@executor-js/plugin-graphql/api";import { AuthTemplateSlug, ConnectionName, IntegrationSlug } from "@executor-js/sdk/shared"; import { variable } from "@executor-js/sdk/http-auth"; import { scenario } from "../src/scenario";import { Api, Mcp, Target } from "../src/services"; const api = composePluginApi([mcpHttpPlugin(), graphqlHttpPlugin()] as const); const freshSlug = (prefix: string): string => `${prefix}_${randomBytes(4).toString("hex")}`; // Registration never dials the endpoint, so a closed local port is fine for// the catalog-only scenarios.const MCP_ENDPOINT = "http://127.0.0.1:59998/mcp"; scenario( "Auth methods · an MCP server can declare OAuth and an API key side by side", {}, Effect.gen(function* () { const target = yield* Target; const { client: makeApiClient } = yield* Api; const identity = yield* target.newIdentity(); const client = yield* makeApiClient(api, identity); const slug = freshSlug("mcp_multiauth"); yield* client.mcp.addServer({ payload: { transport: "remote", name: "Multi-auth MCP", endpoint: MCP_ENDPOINT, slug, authenticationTemplate: [ { kind: "oauth2" }, { type: "apiKey", headers: { "X-Api-Key": ["Bearer ", variable("token")] } }, ], }, }); yield* Effect.gen(function* () { const integration = yield* client.integrations.get({ params: { slug: IntegrationSlug.make(slug) }, }); // Both methods project into the catalog (a slug-less single-header // apikey method gets the carrier-derived `header` slug), so the // connect flow can offer either and a connection binds one by slug. expect( integration.authMethods.map((m) => ({ kind: m.kind, template: m.template })), "the catalog lists both declared methods", ).toEqual([ { kind: "oauth", template: "oauth2" }, { kind: "apikey", template: "header" }, ]); const apiKey = integration.authMethods.find((m) => m.kind === "apikey"); expect(apiKey?.placements, "the API key method carries its header placement").toEqual([ { carrier: "header", name: "X-Api-Key", prefix: "Bearer " }, ]); }).pipe( Effect.ensuring( client.mcp .removeServer({ params: { slug: IntegrationSlug.make(slug) } }) .pipe(Effect.ignore), ), ); }),); scenario( "Auth methods · adding an API key method keeps a detected OAuth method", {}, Effect.gen(function* () { const target = yield* Target; const { client: makeApiClient } = yield* Api; const identity = yield* target.newIdentity(); const client = yield* makeApiClient(api, identity); const slug = freshSlug("mcp_oauth_plus_key"); // The add flow registered what the probe detected: OAuth only. yield* client.mcp.addServer({ payload: { transport: "remote", name: "OAuth MCP", endpoint: MCP_ENDPOINT, slug, authenticationTemplate: [{ kind: "oauth2" }], }, }); yield* Effect.gen(function* () { // "+ Custom method" merge-appends — it must not displace OAuth. const configured = yield* client.mcp.configureAuth({ params: { slug: IntegrationSlug.make(slug) }, payload: { authenticationTemplate: [ { type: "apiKey", headers: { "X-Api-Key": [variable("token")] } }, ], }, }); expect( configured.authenticationTemplate.map((m) => m.kind), "the declared set now holds both methods", ).toEqual(["oauth2", "apikey"]); expect( configured.authenticationTemplate[1]?.slug, "the custom method gets its own custom_ slug", ).toMatch(/^custom_/); const integration = yield* client.integrations.get({ params: { slug: IntegrationSlug.make(slug) }, }); expect( integration.authMethods.map((m) => m.kind), "the catalog offers OAuth and the API key", ).toEqual(["oauth", "apikey"]); }).pipe( Effect.ensuring( client.mcp .removeServer({ params: { slug: IntegrationSlug.make(slug) } }) .pipe(Effect.ignore), ), ); }),); scenario( "Auth methods · a no-auth MCP server can declare an API key method later", {}, Effect.gen(function* () { const target = yield* Target; const { client: makeApiClient } = yield* Api; const identity = yield* target.newIdentity(); const client = yield* makeApiClient(api, identity); const slug = freshSlug("mcp_open_plus_key"); // No declared auth — the server advertises nothing. yield* client.mcp.addServer({ payload: { transport: "remote", name: "Open MCP", endpoint: MCP_ENDPOINT, slug }, }); yield* Effect.gen(function* () { const before = yield* client.integrations.get({ params: { slug: IntegrationSlug.make(slug) }, }); expect( before.authMethods.map((m) => m.kind), "an open server starts with the no-auth method", ).toEqual(["none"]); yield* client.mcp.configureAuth({ params: { slug: IntegrationSlug.make(slug) }, payload: { authenticationTemplate: [ { type: "apiKey", headers: { Authorization: ["Bearer ", variable("token")] } }, ], }, }); const after = yield* client.integrations.get({ params: { slug: IntegrationSlug.make(slug) }, }); expect( after.authMethods.map((m) => m.kind), "no-auth and the declared API key coexist", ).toEqual(["none", "apikey"]); }).pipe( Effect.ensuring( client.mcp .removeServer({ params: { slug: IntegrationSlug.make(slug) } }) .pipe(Effect.ignore), ), ); }),); scenario( "Auth methods · a GraphQL integration registers multiple auth methods at add time", {}, Effect.gen(function* () { const target = yield* Target; const { client: makeApiClient } = yield* Api; const identity = yield* target.newIdentity(); const client = yield* makeApiClient(api, identity); const slug = freshSlug("graphql_multiauth"); yield* client.graphql.addIntegration({ payload: { endpoint: "http://127.0.0.1:59998/graphql", slug, name: "Multi-auth GraphQL", authenticationTemplate: [ { slug: "apiKey", type: "apiKey", headers: { "X-Api-Key": [variable("token")] } }, { slug: "apikey-2", type: "apiKey", queryParams: { api_key: [variable("token")] } }, ], }, }); yield* Effect.gen(function* () { const integration = yield* client.integrations.get({ params: { slug: IntegrationSlug.make(slug) }, }); expect( integration.authMethods.map((m) => ({ template: m.template, kind: m.kind })), "both declared methods are in the catalog", ).toEqual([ { template: "apiKey", kind: "apikey" }, { template: "apikey-2", kind: "apikey" }, ]); expect( integration.authMethods[1]?.placements, "the second method carries its query placement", ).toEqual([{ carrier: "query", name: "api_key", prefix: "" }]); }).pipe( Effect.ensuring( client.integrations .remove({ params: { slug: IntegrationSlug.make(slug) } }) .pipe(Effect.ignore), ), ); }),); // ---------------------------------------------------------------------------// THE EXTREME CASE — one integration, four methods, three live connections, every// invocation asserted against what the server actually received:// [oauth2] (declared; connect flow not exercised here)// [bearer header + team-id query] (TWO inputs on ONE method)// [bearer header] (single input)// [auth-token query param] (single input, the ui.sh shape)// --------------------------------------------------------------------------- scenario( "Auth methods · one integration mixes oauth, a 2-input header+query method, a bearer header, and a query token", {}, Effect.scoped( Effect.gen(function* () { const target = yield* Target; const { client: makeApiClient } = yield* Api; const mcp = yield* Mcp; const identity = yield* target.newIdentity(); const client = yield* makeApiClient(api, identity); const slug = freshSlug("mcp_extreme"); // A real MCP server that records every request it receives. const server = yield* serveMcpServer(() => makeEchoMcpServer({ name: "extreme-auth", toolName: "whoami", toolDescription: "Echoes a marker so the test can prove the invoke reached the server", inputName: "marker", text: (marker) => `ok:${marker}`, }), ); yield* client.mcp.addServer({ payload: { transport: "remote", name: "Extreme auth MCP", endpoint: server.url, slug, authenticationTemplate: [ { kind: "oauth2" }, { slug: "token_and_team", type: "apiKey", headers: { Authorization: ["Bearer ", variable("api_token")] }, queryParams: { team_id: [variable("team_id")] }, }, { slug: "bearer", type: "apiKey", headers: { Authorization: ["Bearer ", variable("token")] }, }, { slug: "query_token", type: "apiKey", queryParams: { auth_token: [variable("token")] }, }, ], }, }); yield* Effect.gen(function* () { // All four methods project into the catalog, the 2-input method with // both placements and their distinct variables (what drives the two // credential fields in the connect modal). const integration = yield* client.integrations.get({ params: { slug: IntegrationSlug.make(slug) }, }); expect( integration.authMethods.map((m) => ({ kind: m.kind, template: m.template })), "the catalog lists all four methods", ).toEqual([ { kind: "oauth", template: "oauth2" }, { kind: "apikey", template: "token_and_team" }, { kind: "apikey", template: "bearer" }, { kind: "apikey", template: "query_token" }, ]); expect( integration.authMethods[1]?.placements, "the 2-input method carries both placements with their variables", ).toEqual([ { carrier: "header", name: "Authorization", prefix: "Bearer ", variable: "api_token" }, { carrier: "query", name: "team_id", prefix: "", variable: "team_id" }, ]); // One connection per credential method. The 2-input method takes a // `values` map (one entry per placement variable). yield* client.connections.create({ payload: { owner: "org", name: ConnectionName.make("mixed"), integration: IntegrationSlug.make(slug), template: AuthTemplateSlug.make("token_and_team"), values: { api_token: "tok_mixed", team_id: "team_42" }, }, }); yield* client.connections.create({ payload: { owner: "org", name: ConnectionName.make("bearer"), integration: IntegrationSlug.make(slug), template: AuthTemplateSlug.make("bearer"), value: "tok_bearer", }, }); yield* client.connections.create({ payload: { owner: "org", name: ConnectionName.make("token"), integration: IntegrationSlug.make(slug), template: AuthTemplateSlug.make("query_token"), value: "tok_query", }, }); // Discovery dialed the server per connection; every connection // produced its own addressed tool. const tools = yield* client.tools.list({ query: {} }); const names = tools .filter((tool) => String(tool.integration) === slug) .map((tool) => String(tool.address)); for (const conn of ["mixed", "bearer", "token"]) { expect(names, `connection "${conn}" resolved the server's tool`).toContain( `tools.${slug}.org.${conn}.whoami`, ); } // Invoke through the MCP surface (the real agent path: execute runs // sandbox code that calls the addressed tool), then assert the WIRE: // what the recording server received for each connection. const session = mcp.session(identity); const invokeAndCapture = (conn: string, marker: string) => Effect.gen(function* () { const before = (yield* server.requests).length; const result = yield* session.call("execute", { // Return the whole result — the assertion only needs the echoed // marker to prove the call reached the server. code: `return JSON.stringify(await tools.${slug}.org.${conn}.whoami({ marker: ${JSON.stringify(marker)} }));`, }); expect(result.text, `the ${conn} invocation reached the server`).toContain( `ok:${marker}`, ); return (yield* server.requests).slice(before); }); const mixedRequests = yield* invokeAndCapture("mixed", "m1"); expect( mixedRequests.every((r) => r.authorization === "Bearer tok_mixed"), "the 2-input method rendered its bearer header", ).toBe(true); expect( mixedRequests.every((r) => r.url.includes("team_id=team_42")), "…and its team-id query param, from the second input", ).toBe(true); const bearerRequests = yield* invokeAndCapture("bearer", "b1"); expect( bearerRequests.every((r) => r.authorization === "Bearer tok_bearer"), "the bearer method rendered only its header", ).toBe(true); expect( bearerRequests.every( (r) => !r.url.includes("team_id=") && !r.url.includes("auth_token="), ), "…with no query credential bleeding in from sibling methods", ).toBe(true); const queryRequests = yield* invokeAndCapture("token", "q1"); expect( queryRequests.every((r) => r.url.includes("auth_token=tok_query")), "the query method rendered its token param", ).toBe(true); expect( queryRequests.every((r) => r.authorization === undefined), "…and no Authorization header", ).toBe(true); }).pipe( Effect.ensuring( Effect.gen(function* () { for (const name of ["mixed", "bearer", "token"]) { yield* client.connections .remove({ params: { owner: "org", integration: IntegrationSlug.make(slug), name: ConnectionName.make(name), }, }) .pipe(Effect.ignore); } yield* client.mcp .removeServer({ params: { slug: IntegrationSlug.make(slug) } }) .pipe(Effect.ignore); }), ), ); }), ),);
// Cross-target: multi-method authentication — an integration declares SEVERAL
// auth methods and a connection picks one by template slug. Covers the unified
// placements model: one apikey method can mix header and query placements,
// each rendered from its own credential input; the merge-append configureAuth
// flow (a custom API key must never displace a detected OAuth method);
// declaring a method on a server that advertises none; GraphQL's multi-method
// add — and the EXTREME case end-to-end: an integration declaring
// [oauth] [bearer header + team-id query] [bearer header] [query token],
// one connection per credential method, every invocation asserted against
// what a real recording MCP server received.
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 { makeEchoMcpServer, serveMcpServer } from "@executor-js/plugin-mcp/testing";
import { graphqlHttpPlugin } from "@executor-js/plugin-graphql/api";
import { AuthTemplateSlug, ConnectionName, IntegrationSlug } from "@executor-js/sdk/shared";
import { variable } from "@executor-js/sdk/http-auth";
import { scenario } from "../src/scenario";
import { Api, Mcp, Target } from "../src/services";
const api = composePluginApi([mcpHttpPlugin(), graphqlHttpPlugin()] as const);
const freshSlug = (prefix: string): string => `${prefix}_${randomBytes(4).toString("hex")}`;
// Registration never dials the endpoint, so a closed local port is fine for
// the catalog-only scenarios.
const MCP_ENDPOINT = "http://127.0.0.1:59998/mcp";
scenario(
"Auth methods · an MCP server can declare OAuth and an API key side by side",
{},
Effect.gen(function* () {
const target = yield* Target;
const { client: makeApiClient } = yield* Api;
const identity = yield* target.newIdentity();
const client = yield* makeApiClient(api, identity);
const slug = freshSlug("mcp_multiauth");
yield* client.mcp.addServer({
payload: {
transport: "remote",
name: "Multi-auth MCP",
endpoint: MCP_ENDPOINT,
slug,
authenticationTemplate: [
{ kind: "oauth2" },
{ type: "apiKey", headers: { "X-Api-Key": ["Bearer ", variable("token")] } },
],
},
});
yield* Effect.gen(function* () {
const integration = yield* client.integrations.get({
params: { slug: IntegrationSlug.make(slug) },
});
// Both methods project into the catalog (a slug-less single-header
// apikey method gets the carrier-derived `header` slug), so the
// connect flow can offer either and a connection binds one by slug.
expect(
integration.authMethods.map((m) => ({ kind: m.kind, template: m.template })),
"the catalog lists both declared methods",
).toEqual([
{ kind: "oauth", template: "oauth2" },
{ kind: "apikey", template: "header" },
]);
const apiKey = integration.authMethods.find((m) => m.kind === "apikey");
expect(apiKey?.placements, "the API key method carries its header placement").toEqual([
{ carrier: "header", name: "X-Api-Key", prefix: "Bearer " },
]);
}).pipe(
Effect.ensuring(
client.mcp
.removeServer({ params: { slug: IntegrationSlug.make(slug) } })
.pipe(Effect.ignore),
),
);
}),
);
scenario(
"Auth methods · adding an API key method keeps a detected OAuth method",
{},
Effect.gen(function* () {
const target = yield* Target;
const { client: makeApiClient } = yield* Api;
const identity = yield* target.newIdentity();
const client = yield* makeApiClient(api, identity);
const slug = freshSlug("mcp_oauth_plus_key");
// The add flow registered what the probe detected: OAuth only.
yield* client.mcp.addServer({
payload: {
transport: "remote",
name: "OAuth MCP",
endpoint: MCP_ENDPOINT,
slug,
authenticationTemplate: [{ kind: "oauth2" }],
},
});
yield* Effect.gen(function* () {
// "+ Custom method" merge-appends — it must not displace OAuth.
const configured = yield* client.mcp.configureAuth({
params: { slug: IntegrationSlug.make(slug) },
payload: {
authenticationTemplate: [
{ type: "apiKey", headers: { "X-Api-Key": [variable("token")] } },
],
},
});
expect(
configured.authenticationTemplate.map((m) => m.kind),
"the declared set now holds both methods",
).toEqual(["oauth2", "apikey"]);
expect(
configured.authenticationTemplate[1]?.slug,
"the custom method gets its own custom_ slug",
).toMatch(/^custom_/);
const integration = yield* client.integrations.get({
params: { slug: IntegrationSlug.make(slug) },
});
expect(
integration.authMethods.map((m) => m.kind),
"the catalog offers OAuth and the API key",
).toEqual(["oauth", "apikey"]);
}).pipe(
Effect.ensuring(
client.mcp
.removeServer({ params: { slug: IntegrationSlug.make(slug) } })
.pipe(Effect.ignore),
),
);
}),
);
scenario(
"Auth methods · a no-auth MCP server can declare an API key method later",
{},
Effect.gen(function* () {
const target = yield* Target;
const { client: makeApiClient } = yield* Api;
const identity = yield* target.newIdentity();
const client = yield* makeApiClient(api, identity);
const slug = freshSlug("mcp_open_plus_key");
// No declared auth — the server advertises nothing.
yield* client.mcp.addServer({
payload: { transport: "remote", name: "Open MCP", endpoint: MCP_ENDPOINT, slug },
});
yield* Effect.gen(function* () {
const before = yield* client.integrations.get({
params: { slug: IntegrationSlug.make(slug) },
});
expect(
before.authMethods.map((m) => m.kind),
"an open server starts with the no-auth method",
).toEqual(["none"]);
yield* client.mcp.configureAuth({
params: { slug: IntegrationSlug.make(slug) },
payload: {
authenticationTemplate: [
{ type: "apiKey", headers: { Authorization: ["Bearer ", variable("token")] } },
],
},
});
const after = yield* client.integrations.get({
params: { slug: IntegrationSlug.make(slug) },
});
expect(
after.authMethods.map((m) => m.kind),
"no-auth and the declared API key coexist",
).toEqual(["none", "apikey"]);
}).pipe(
Effect.ensuring(
client.mcp
.removeServer({ params: { slug: IntegrationSlug.make(slug) } })
.pipe(Effect.ignore),
),
);
}),
);
scenario(
"Auth methods · a GraphQL integration registers multiple auth methods at add time",
{},
Effect.gen(function* () {
const target = yield* Target;
const { client: makeApiClient } = yield* Api;
const identity = yield* target.newIdentity();
const client = yield* makeApiClient(api, identity);
const slug = freshSlug("graphql_multiauth");
yield* client.graphql.addIntegration({
payload: {
endpoint: "http://127.0.0.1:59998/graphql",
slug,
name: "Multi-auth GraphQL",
authenticationTemplate: [
{ slug: "apiKey", type: "apiKey", headers: { "X-Api-Key": [variable("token")] } },
{ slug: "apikey-2", type: "apiKey", queryParams: { api_key: [variable("token")] } },
],
},
});
yield* Effect.gen(function* () {
const integration = yield* client.integrations.get({
params: { slug: IntegrationSlug.make(slug) },
});
expect(
integration.authMethods.map((m) => ({ template: m.template, kind: m.kind })),
"both declared methods are in the catalog",
).toEqual([
{ template: "apiKey", kind: "apikey" },
{ template: "apikey-2", kind: "apikey" },
]);
expect(
integration.authMethods[1]?.placements,
"the second method carries its query placement",
).toEqual([{ carrier: "query", name: "api_key", prefix: "" }]);
}).pipe(
Effect.ensuring(
client.integrations
.remove({ params: { slug: IntegrationSlug.make(slug) } })
.pipe(Effect.ignore),
),
);
}),
);
// ---------------------------------------------------------------------------
// THE EXTREME CASE — one integration, four methods, three live connections, every
// invocation asserted against what the server actually received:
// [oauth2] (declared; connect flow not exercised here)
// [bearer header + team-id query] (TWO inputs on ONE method)
// [bearer header] (single input)
// [auth-token query param] (single input, the ui.sh shape)
// ---------------------------------------------------------------------------
scenario(
"Auth methods · one integration mixes oauth, a 2-input header+query method, a bearer header, and a query token",
{},
Effect.scoped(
Effect.gen(function* () {
const target = yield* Target;
const { client: makeApiClient } = yield* Api;
const mcp = yield* Mcp;
const identity = yield* target.newIdentity();
const client = yield* makeApiClient(api, identity);
const slug = freshSlug("mcp_extreme");
// A real MCP server that records every request it receives.
const server = yield* serveMcpServer(() =>
makeEchoMcpServer({
name: "extreme-auth",
toolName: "whoami",
toolDescription: "Echoes a marker so the test can prove the invoke reached the server",
inputName: "marker",
text: (marker) => `ok:${marker}`,
}),
);
yield* client.mcp.addServer({
payload: {
transport: "remote",
name: "Extreme auth MCP",
endpoint: server.url,
slug,
authenticationTemplate: [
{ kind: "oauth2" },
{
slug: "token_and_team",
type: "apiKey",
headers: { Authorization: ["Bearer ", variable("api_token")] },
queryParams: { team_id: [variable("team_id")] },
},
{
slug: "bearer",
type: "apiKey",
headers: { Authorization: ["Bearer ", variable("token")] },
},
{
slug: "query_token",
type: "apiKey",
queryParams: { auth_token: [variable("token")] },
},
],
},
});
yield* Effect.gen(function* () {
// All four methods project into the catalog, the 2-input method with
// both placements and their distinct variables (what drives the two
// credential fields in the connect modal).
const integration = yield* client.integrations.get({
params: { slug: IntegrationSlug.make(slug) },
});
expect(
integration.authMethods.map((m) => ({ kind: m.kind, template: m.template })),
"the catalog lists all four methods",
).toEqual([
{ kind: "oauth", template: "oauth2" },
{ kind: "apikey", template: "token_and_team" },
{ kind: "apikey", template: "bearer" },
{ kind: "apikey", template: "query_token" },
]);
expect(
integration.authMethods[1]?.placements,
"the 2-input method carries both placements with their variables",
).toEqual([
{ carrier: "header", name: "Authorization", prefix: "Bearer ", variable: "api_token" },
{ carrier: "query", name: "team_id", prefix: "", variable: "team_id" },
]);
// One connection per credential method. The 2-input method takes a
// `values` map (one entry per placement variable).
yield* client.connections.create({
payload: {
owner: "org",
name: ConnectionName.make("mixed"),
integration: IntegrationSlug.make(slug),
template: AuthTemplateSlug.make("token_and_team"),
values: { api_token: "tok_mixed", team_id: "team_42" },
},
});
yield* client.connections.create({
payload: {
owner: "org",
name: ConnectionName.make("bearer"),
integration: IntegrationSlug.make(slug),
template: AuthTemplateSlug.make("bearer"),
value: "tok_bearer",
},
});
yield* client.connections.create({
payload: {
owner: "org",
name: ConnectionName.make("token"),
integration: IntegrationSlug.make(slug),
template: AuthTemplateSlug.make("query_token"),
value: "tok_query",
},
});
// Discovery dialed the server per connection; every connection
// produced its own addressed tool.
const tools = yield* client.tools.list({ query: {} });
const names = tools
.filter((tool) => String(tool.integration) === slug)
.map((tool) => String(tool.address));
for (const conn of ["mixed", "bearer", "token"]) {
expect(names, `connection "${conn}" resolved the server's tool`).toContain(
`tools.${slug}.org.${conn}.whoami`,
);
}
// Invoke through the MCP surface (the real agent path: execute runs
// sandbox code that calls the addressed tool), then assert the WIRE:
// what the recording server received for each connection.
const session = mcp.session(identity);
const invokeAndCapture = (conn: string, marker: string) =>
Effect.gen(function* () {
const before = (yield* server.requests).length;
const result = yield* session.call("execute", {
// Return the whole result — the assertion only needs the echoed
// marker to prove the call reached the server.
code: `return JSON.stringify(await tools.${slug}.org.${conn}.whoami({ marker: ${JSON.stringify(marker)} }));`,
});
expect(result.text, `the ${conn} invocation reached the server`).toContain(
`ok:${marker}`,
);
return (yield* server.requests).slice(before);
});
const mixedRequests = yield* invokeAndCapture("mixed", "m1");
expect(
mixedRequests.every((r) => r.authorization === "Bearer tok_mixed"),
"the 2-input method rendered its bearer header",
).toBe(true);
expect(
mixedRequests.every((r) => r.url.includes("team_id=team_42")),
"…and its team-id query param, from the second input",
).toBe(true);
const bearerRequests = yield* invokeAndCapture("bearer", "b1");
expect(
bearerRequests.every((r) => r.authorization === "Bearer tok_bearer"),
"the bearer method rendered only its header",
).toBe(true);
expect(
bearerRequests.every(
(r) => !r.url.includes("team_id=") && !r.url.includes("auth_token="),
),
"…with no query credential bleeding in from sibling methods",
).toBe(true);
const queryRequests = yield* invokeAndCapture("token", "q1");
expect(
queryRequests.every((r) => r.url.includes("auth_token=tok_query")),
"the query method rendered its token param",
).toBe(true);
expect(
queryRequests.every((r) => r.authorization === undefined),
"…and no Authorization header",
).toBe(true);
}).pipe(
Effect.ensuring(
Effect.gen(function* () {
for (const name of ["mixed", "bearer", "token"]) {
yield* client.connections
.remove({
params: {
owner: "org",
integration: IntegrationSlug.make(slug),
name: ConnectionName.make(name),
},
})
.pipe(Effect.ignore);
}
yield* client.mcp
.removeServer({ params: { slug: IntegrationSlug.make(slug) } })
.pipe(Effect.ignore);
}),
),
);
}),
),
);