@gleanwork/mcp-server-tester 1.0.0-beta.0 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1836,11 +1836,11 @@ function parseNullableDef(def, refs) {
1836
1836
  ]
1837
1837
  };
1838
1838
  }
1839
- const base2 = parseDef(def.innerType._def, {
1839
+ const base3 = parseDef(def.innerType._def, {
1840
1840
  ...refs,
1841
1841
  currentPath: [...refs.currentPath, "anyOf", "0"]
1842
1842
  });
1843
- return base2 && { anyOf: [base2, { type: "null" }] };
1843
+ return base3 && { anyOf: [base3, { type: "null" }] };
1844
1844
  }
1845
1845
  function parseNumberDef(def) {
1846
1846
  const res = {
@@ -3160,6 +3160,7 @@ var StdioConfigSchema = zod.z.object({
3160
3160
  command: zod.z.string().min(1, "command is required for stdio transport"),
3161
3161
  args: zod.z.array(zod.z.string()).optional(),
3162
3162
  cwd: zod.z.string().optional(),
3163
+ env: zod.z.record(zod.z.string(), zod.z.string()).optional(),
3163
3164
  capabilities: MCPHostCapabilitiesSchema.optional(),
3164
3165
  connectTimeoutMs: zod.z.number().positive().optional(),
3165
3166
  requestTimeoutMs: zod.z.number().positive().optional(),
@@ -4406,7 +4407,7 @@ function escapeHtml(text) {
4406
4407
 
4407
4408
  // package.json
4408
4409
  var package_default = {
4409
- version: "1.0.0-beta.0"};
4410
+ version: "1.0.0-beta.1"};
4410
4411
 
4411
4412
  // src/mcp/clientFactory.ts
4412
4413
  function getRetryAfterDelayMs(err) {
@@ -4478,7 +4479,14 @@ async function createMCPClientForConfig(config, options) {
4478
4479
  args: validatedConfig.args ?? [],
4479
4480
  ...validatedConfig.cwd && { cwd: validatedConfig.cwd },
4480
4481
  // Suppress server stderr when quiet mode is enabled
4481
- ...validatedConfig.quiet && { stderr: "ignore" }
4482
+ ...validatedConfig.quiet && { stderr: "ignore" },
4483
+ ...validatedConfig.env && {
4484
+ env: Object.fromEntries(
4485
+ Object.entries({ ...process.env, ...validatedConfig.env }).filter(
4486
+ (entry) => entry[1] !== void 0
4487
+ )
4488
+ )
4489
+ }
4482
4490
  });
4483
4491
  debugClient("Connecting via stdio: %O", {
4484
4492
  command: validatedConfig.command,
@@ -4617,7 +4625,10 @@ async function closeMCPClient(client) {
4617
4625
  try {
4618
4626
  await client.close();
4619
4627
  } catch (error) {
4620
- console.error("[MCP] Error closing client:", error);
4628
+ debugClient(
4629
+ "Error closing client: %s",
4630
+ error instanceof Error ? error.message : String(error)
4631
+ );
4621
4632
  throw error;
4622
4633
  } finally {
4623
4634
  const agent = agentRegistry.get(client);
@@ -5147,7 +5158,7 @@ function validateToolCalls(response, expectation) {
5147
5158
  ).length;
5148
5159
  const recall = requiredCalls.length > 0 ? calledRequiredCount / requiredCalls.length : 1;
5149
5160
  const allowedNames = new Set(expectation.calls.map((c) => c.name));
5150
- const precision = actual.length > 0 && expectation.exclusive === true ? actual.filter((c) => allowedNames.has(c.name)).length / actual.length : 1;
5161
+ const precision = actual.length > 0 ? actual.filter((c) => allowedNames.has(c.name)).length / actual.length : 1;
5151
5162
  const metrics = { precision, recall };
5152
5163
  const order = expectation.order ?? "any";
5153
5164
  if (order === "strict") {
@@ -5550,9 +5561,8 @@ Validation errors: ${JSON.stringify(validation.error.issues)}`
5550
5561
 
5551
5562
  // src/judge/judgeClient.ts
5552
5563
  function createJudge(config = {}) {
5553
- const provider = config.provider ?? "claude";
5564
+ const provider = config.provider ?? "anthropic";
5554
5565
  switch (provider) {
5555
- case "claude":
5556
5566
  case "anthropic":
5557
5567
  return createClaudeAgentJudge(config);
5558
5568
  case "openai":
@@ -6209,6 +6219,106 @@ var test = test$1.test.extend({
6209
6219
  await use(api);
6210
6220
  }
6211
6221
  });
6222
+
6223
+ // src/fixtures/mcpAuth.ts
6224
+ init_oauthClientProvider();
6225
+ var StaticTokenAuthProvider = class {
6226
+ accessToken;
6227
+ constructor(accessToken) {
6228
+ this.accessToken = accessToken;
6229
+ }
6230
+ get redirectUrl() {
6231
+ throw new Error("StaticTokenAuthProvider does not support OAuth redirects");
6232
+ }
6233
+ get clientMetadata() {
6234
+ return {
6235
+ redirect_uris: [],
6236
+ token_endpoint_auth_method: "none",
6237
+ grant_types: [],
6238
+ response_types: [],
6239
+ client_name: "@gleanwork/mcp-server-tester"
6240
+ };
6241
+ }
6242
+ async clientInformation() {
6243
+ return void 0;
6244
+ }
6245
+ async tokens() {
6246
+ return {
6247
+ access_token: this.accessToken,
6248
+ token_type: "Bearer"
6249
+ };
6250
+ }
6251
+ async saveTokens() {
6252
+ }
6253
+ async redirectToAuthorization() {
6254
+ throw new Error("StaticTokenAuthProvider does not support OAuth redirects");
6255
+ }
6256
+ async saveCodeVerifier() {
6257
+ throw new Error("StaticTokenAuthProvider does not support PKCE");
6258
+ }
6259
+ async codeVerifier() {
6260
+ throw new Error("StaticTokenAuthProvider does not support PKCE");
6261
+ }
6262
+ };
6263
+ var test2 = test$1.test.extend({
6264
+ /**
6265
+ * Create auth provider based on environment configuration
6266
+ */
6267
+ // eslint-disable-next-line no-empty-pattern
6268
+ mcpAuthProvider: async ({}, use) => {
6269
+ const authConfig = getAuthConfigFromEnv();
6270
+ if (!authConfig) {
6271
+ await use(void 0);
6272
+ return;
6273
+ }
6274
+ if (authConfig.accessToken) {
6275
+ const provider = new StaticTokenAuthProvider(authConfig.accessToken);
6276
+ await use(provider);
6277
+ return;
6278
+ }
6279
+ if (authConfig.oauth) {
6280
+ const provider = createOAuthProvider(authConfig.oauth);
6281
+ await use(provider);
6282
+ return;
6283
+ }
6284
+ await use(void 0);
6285
+ }
6286
+ });
6287
+ function createOAuthProvider(oauthConfig) {
6288
+ if (!oauthConfig.authStatePath) {
6289
+ throw new Error(
6290
+ "OAuth configuration requires authStatePath. Use performOAuthSetup() in globalSetup to create auth state first."
6291
+ );
6292
+ }
6293
+ const providerConfig = {
6294
+ storagePath: oauthConfig.authStatePath,
6295
+ redirectUri: oauthConfig.redirectUri ?? "http://localhost:3000/oauth/callback",
6296
+ clientId: oauthConfig.clientId,
6297
+ clientSecret: oauthConfig.clientSecret
6298
+ };
6299
+ return new exports.PlaywrightOAuthClientProvider(providerConfig);
6300
+ }
6301
+ function getAuthConfigFromEnv() {
6302
+ const accessToken = process.env.MCP_ACCESS_TOKEN;
6303
+ if (accessToken) {
6304
+ return { accessToken };
6305
+ }
6306
+ const oauthServerUrl = process.env.MCP_OAUTH_SERVER_URL;
6307
+ const authStatePath = process.env.MCP_AUTH_STATE_PATH;
6308
+ if (oauthServerUrl || authStatePath) {
6309
+ return {
6310
+ oauth: {
6311
+ serverUrl: oauthServerUrl ?? "",
6312
+ authStatePath,
6313
+ clientId: process.env.MCP_OAUTH_CLIENT_ID,
6314
+ clientSecret: process.env.MCP_OAUTH_CLIENT_SECRET,
6315
+ scopes: process.env.MCP_OAUTH_SCOPES?.split(","),
6316
+ resource: process.env.MCP_OAUTH_RESOURCE
6317
+ }
6318
+ };
6319
+ }
6320
+ return void 0;
6321
+ }
6212
6322
  var LLMHostConfigSchema = zod.z.object({
6213
6323
  provider: zod.z.enum([
6214
6324
  "openai",
@@ -6216,7 +6326,6 @@ var LLMHostConfigSchema = zod.z.object({
6216
6326
  "azure",
6217
6327
  "google",
6218
6328
  "mistral",
6219
- "ollama",
6220
6329
  "deepseek",
6221
6330
  "openrouter",
6222
6331
  "xai",
@@ -6263,7 +6372,7 @@ var EvalExpectBlockSchema = zod.z.object({
6263
6372
  reference: zod.z.unknown().optional(),
6264
6373
  threshold: zod.z.number().min(0).max(1).optional(),
6265
6374
  reps: zod.z.number().int().min(1).optional(),
6266
- provider: zod.z.enum(["claude", "anthropic", "openai", "google"]).optional(),
6375
+ provider: zod.z.enum(["anthropic", "openai", "google"]).optional(),
6267
6376
  model: zod.z.string().optional(),
6268
6377
  apiKeyEnvVar: zod.z.string().optional(),
6269
6378
  maxTokens: zod.z.number().int().positive().optional(),
@@ -6405,10 +6514,6 @@ async function loadModel(provider, model) {
6405
6514
  const { azure } = await import('@ai-sdk/azure');
6406
6515
  return azure(model);
6407
6516
  }
6408
- case "ollama": {
6409
- const { ollama } = await import('@ai-sdk/ollama');
6410
- return ollama(model);
6411
- }
6412
6517
  case "deepseek": {
6413
6518
  const { deepseek } = await import('@ai-sdk/deepseek');
6414
6519
  return deepseek(model);
@@ -6515,7 +6620,6 @@ var allProviders = [
6515
6620
  "azure",
6516
6621
  "google",
6517
6622
  "mistral",
6518
- "ollama",
6519
6623
  "deepseek",
6520
6624
  "openrouter",
6521
6625
  "xai",
@@ -6543,7 +6647,6 @@ function getMissingDependencyMessage(provider) {
6543
6647
  google: "npm install ai @ai-sdk/google",
6544
6648
  azure: "npm install ai @ai-sdk/azure",
6545
6649
  mistral: "npm install ai @ai-sdk/mistral",
6546
- ollama: "npm install ai @ai-sdk/ollama",
6547
6650
  deepseek: "npm install ai @ai-sdk/deepseek",
6548
6651
  openrouter: "npm install ai @openrouter/ai-sdk-provider",
6549
6652
  xai: "npm install ai @ai-sdk/xai",
@@ -6790,15 +6893,17 @@ async function runSingleIteration(evalCase, context, options) {
6790
6893
  function isInfrastructureError(err) {
6791
6894
  let name15;
6792
6895
  let msg;
6896
+ let code = "";
6793
6897
  if (err instanceof Error) {
6794
6898
  name15 = err.name;
6795
6899
  msg = err.message.toLowerCase();
6900
+ code = (err.code ?? "").toLowerCase();
6796
6901
  } else if (typeof err === "string") {
6797
6902
  msg = err.toLowerCase();
6798
6903
  } else {
6799
6904
  return false;
6800
6905
  }
6801
- return name15 === "AbortError" || msg.includes("econnreset") || msg.includes("etimedout") || msg.includes("econnrefused") || msg.includes("rate limit") || msg.includes("429") || msg.includes("503") || msg.includes("network");
6906
+ return name15 === "AbortError" || msg.includes("econnreset") || msg.includes("etimedout") || msg.includes("econnrefused") || msg.includes("rate limit") || msg.includes("429") || msg.includes("503") || msg.includes("network") || code.includes("econnreset") || code.includes("etimedout") || code.includes("econnrefused");
6802
6907
  }
6803
6908
  async function runEvalCase(evalCase, context, options = {}) {
6804
6909
  const iterations = evalCase.iterations ?? 1;
@@ -7272,6 +7377,7 @@ exports.loadEvalDataset = loadEvalDataset;
7272
7377
  exports.loadEvalDatasetFromObject = loadEvalDatasetFromObject;
7273
7378
  exports.loadTokens = loadTokens;
7274
7379
  exports.loadTokensFromEnv = loadTokensFromEnv;
7380
+ exports.mcpAuthTest = test2;
7275
7381
  exports.normalizeToolResponse = normalizeToolResponse;
7276
7382
  exports.normalizeWhitespace = normalizeWhitespace;
7277
7383
  exports.performClientCredentialsFlow = performClientCredentialsFlow;