Skip to content
This repository was archived by the owner on Feb 23, 2026. It is now read-only.

Commit e6967bf

Browse files
Merge pull request #57 from runbasehq/dev
Release 0.4.2
1 parent 2a1d3da commit e6967bf

File tree

7 files changed

+63
-107
lines changed

7 files changed

+63
-107
lines changed

packages/mcp-check/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# mcp-testing-library
22

3+
## 0.4.2
4+
5+
### Patch Changes
6+
7+
- improve typings
8+
39
## 0.4.1
410

511
### Patch Changes

packages/mcp-check/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "mcp-check",
33
"module": "dist/src/index.js",
4-
"version": "0.4.1",
4+
"version": "0.4.2",
55
"type": "module",
66
"main": "dist/src/index.js",
77
"types": "dist/src/index.d.ts",

packages/mcp-check/src/agents/client.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ export class AgentsClient<T extends ModelName = ModelName> {
7676
* @example
7777
* ```typescript
7878
* const result = await client
79-
* .prompt("What tools are available?")
80-
* .execute();
79+
* .prompt("What tools are available?");
8180
*
8281
* console.log("Execution time:", result.getExecutionResult().summary.executionTime);
8382
* console.log("Successful models:", result.getSuccessfulAgents());

packages/mcp-check/src/chunks/types.ts

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import type { BetaRawContentBlockDeltaEvent, BetaRawContentBlockStartEvent, BetaRawContentBlockStopEvent, BetaRawMessageStreamEvent } from "@anthropic-ai/sdk/resources/beta.js";
2+
import type OpenAI from "openai";
3+
14
export interface ToolCall {
25
/** Arguments passed to the tool function */
36
args: Record<string, any>;
@@ -233,11 +236,9 @@ export type NormalizedChunkType =
233236
* };
234237
* ```
235238
*/
236-
export interface NormalizedChunk {
239+
export interface BaseNormalizedChunk {
237240
/** The type of chunk being processed */
238241
type: NormalizedChunkType;
239-
/** The AI provider that generated this chunk */
240-
provider: "anthropic" | "openai";
241242
/** Timestamp when the chunk was received */
242243
timestamp: number;
243244
/** The normalized data payload for this chunk */
@@ -255,8 +256,25 @@ export interface NormalizedChunk {
255256
/** Additional data properties */
256257
[key: string]: any;
257258
};
258-
/** The original provider-specific chunk data */
259-
originalChunk?: any;
259+
}
260+
261+
/**
262+
* Union type of all possible normalized chunk types.
263+
*
264+
* Defines the different types of streaming chunks that can be processed
265+
* from AI providers.
266+
*
267+
*
268+
**/
269+
export type NormalizedChunk = NormalizedChunkAnthropic | NormalizedChunkOpenAI;
270+
export interface NormalizedChunkAnthropic extends BaseNormalizedChunk {
271+
provider: "anthropic";
272+
originalChunk: BetaRawMessageStreamEvent;
273+
}
274+
275+
export interface NormalizedChunkOpenAI extends BaseNormalizedChunk {
276+
provider: "openai";
277+
originalChunk: OpenAI.Responses.ResponseStreamEvent;
260278
}
261279

262280
/**
@@ -296,9 +314,7 @@ export type ChunkCallback = (chunk: NormalizedChunk) => void | Promise<void>;
296314
* };
297315
* ```
298316
*/
299-
export type ChunkTypeCallback = (
300-
data: NormalizedChunk["data"],
301-
) => void | Promise<void>;
317+
export type ChunkTypeCallback = (data: NormalizedChunk["data"]) => void | Promise<void>;
302318

303319
/**
304320
* Configuration object for chunk handlers.
@@ -347,17 +363,17 @@ export interface ChunkHandlerConfig {
347363
/** Provider-specific handlers for Anthropic */
348364
anthropic?: {
349365
/** Handler for Anthropic content block delta chunks */
350-
onContentBlockDelta?: (chunk: any) => void | Promise<void>;
366+
onContentBlockDelta?: (chunk: BetaRawContentBlockDeltaEvent) => void | Promise<void>;
351367
/** Handler for Anthropic content block start chunks */
352-
onContentBlockStart?: (chunk: any) => void | Promise<void>;
368+
onContentBlockStart?: (chunk: BetaRawContentBlockStartEvent) => void | Promise<void>;
353369
/** Handler for Anthropic content block stop chunks */
354-
onContentBlockStop?: (chunk: any) => void | Promise<void>;
370+
onContentBlockStop?: (chunk: BetaRawContentBlockStopEvent) => void | Promise<void>;
355371
};
356372
/** Provider-specific handlers for OpenAI */
357373
openai?: {
358374
/** Handler for OpenAI response output item added chunks */
359-
onResponseOutputItemAdded?: (chunk: any) => void | Promise<void>;
375+
onResponseOutputItemAdded?: (chunk: OpenAI.Responses.ResponseOutputItemAddedEvent) => void | Promise<void>;
360376
/** Handler for OpenAI response output item done chunks */
361-
onResponseOutputItemDone?: (chunk: any) => void | Promise<void>;
377+
onResponseOutputItemDone?: (chunk: OpenAI.Responses.ResponseOutputItemDoneEvent) => void | Promise<void>;
362378
};
363379
}

packages/mcp-check/src/index.ts

Lines changed: 17 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
import { config } from "dotenv";
22
import type { ModelName } from "./providers";
33
import type { ProviderConfig } from "./providers/types";
4-
import type {
5-
AgentResponse,
6-
AgentsExecutionResult,
7-
ToolCall,
8-
ToolCallStats,
9-
} from "./chunks/types";
4+
import type { AgentResponse, AgentsExecutionResult, ToolCall, ToolCallStats } from "./chunks/types";
105
import { createProvider } from "./providers";
116

127
config();
@@ -31,7 +26,6 @@ export {
3126
* @template T - The type of model names to use
3227
* @param mcpServer - The MCP server configuration
3328
* @param models - Array of model names to execute
34-
* @param scorers - Array of scorers to score the output of the tools
3529
* @param config - Optional provider configuration (API keys, silent mode, etc.)
3630
* @returns A configured AgentsClient instance
3731
*
@@ -53,13 +47,8 @@ export {
5347
* ```
5448
*/
5549

56-
export function client<T extends ModelName>(
57-
mcpServer: McpServer,
58-
models: T[],
59-
scorers?: Scorer[],
60-
config: ProviderConfig = {},
61-
): AgentsClient<T> {
62-
return new AgentsClient(mcpServer, models, scorers, config);
50+
export function client<T extends ModelName>(mcpServer: McpServer, models: T[], config: ProviderConfig = {}): AgentsClient<T> {
51+
return new AgentsClient(mcpServer, models, config);
6352
}
6453

6554
/**
@@ -86,15 +75,7 @@ export class Scorer {
8675
public scorer: (toolResponse: any) => number;
8776
public tool: string;
8877

89-
constructor({
90-
name,
91-
scorer,
92-
tool,
93-
}: {
94-
name: string;
95-
scorer: (toolResponse: any) => number;
96-
tool: string;
97-
}) {
78+
constructor({ name, scorer, tool }: { name: string; scorer: (toolResponse: any) => number; tool: string }) {
9879
this.name = name;
9980
this.scorer = scorer;
10081
this.tool = tool;
@@ -107,17 +88,7 @@ export class McpServer {
10788
public name: string;
10889
public type: string;
10990

110-
constructor({
111-
url,
112-
authorizationToken,
113-
name,
114-
type,
115-
}: {
116-
url: string;
117-
authorizationToken: string;
118-
name: string;
119-
type: string;
120-
}) {
91+
constructor({ url, authorizationToken, name, type }: { url: string; authorizationToken: string; name: string; type: string }) {
12192
this.url = url;
12293
this.authorizationToken = authorizationToken;
12394
this.name = name;
@@ -139,7 +110,7 @@ export class AgentsResult<T extends ModelName = ModelName> {
139110
endTime: number,
140111
models: T[],
141112
agentsInstance?: AgentsClient<T>,
142-
scorers?: Scorer[],
113+
scorers?: Scorer[]
143114
) {
144115
this.responses = responses;
145116
this.executionStartTime = startTime;
@@ -189,15 +160,13 @@ export class AgentsResult<T extends ModelName = ModelName> {
189160
const successfulExecutions = Object.keys(this.responses).length;
190161
const failedExecutions = this.models.length - successfulExecutions;
191162

192-
const allTools = (Object.values(this.responses) as AgentResponse[]).flatMap(
193-
(r) => r.usedTools,
194-
);
163+
const allTools = (Object.values(this.responses) as AgentResponse[]).flatMap((r) => r.usedTools);
195164
const toolCounts = allTools.reduce(
196165
(acc, tool) => {
197166
acc[tool] = (acc[tool] || 0) + 1;
198167
return acc;
199168
},
200-
{} as Record<string, number>,
169+
{} as Record<string, number>
201170
);
202171

203172
const commonTools = Object.entries(toolCounts)
@@ -231,18 +200,13 @@ export class AgentsResult<T extends ModelName = ModelName> {
231200
}
232201

233202
stats[toolName].callCount += (calls as any[]).length;
234-
stats[toolName].lastCalled = Math.max(
235-
stats[toolName].lastCalled || 0,
236-
response.metadata?.timestamp || 0,
237-
);
203+
stats[toolName].lastCalled = Math.max(stats[toolName].lastCalled || 0, response.metadata?.timestamp || 0);
238204
});
239205
});
240206

241207
return Object.values(stats).map((stat) => ({
242208
...stat,
243-
averageDuration: stat.totalDuration
244-
? stat.totalDuration / stat.callCount
245-
: undefined,
209+
averageDuration: stat.totalDuration ? stat.totalDuration / stat.callCount : undefined,
246210
}));
247211
}
248212

@@ -286,15 +250,10 @@ export class AgentsClient<T extends ModelName = ModelName> {
286250
private config: ProviderConfig;
287251
private _scorers: Scorer[] = [];
288252

289-
constructor(
290-
mcpServer: McpServer,
291-
models: T[],
292-
scorers?: Scorer[],
293-
config: ProviderConfig = {},
294-
) {
253+
constructor(mcpServer: McpServer, models: T[], config: ProviderConfig = {}) {
295254
this.models = models;
296255
this.mcpServer = mcpServer;
297-
this._scorers = scorers || [];
256+
this._scorers = config.scorers || [];
298257
this.config = { silent: true, ...config };
299258
}
300259

@@ -313,26 +272,21 @@ export class AgentsClient<T extends ModelName = ModelName> {
313272
name: string;
314273
tool: string;
315274
scorer: (toolResponse: any) => number;
316-
}>,
275+
}>
317276
): this {
318277
this._scorers = scorers.map((s) => new Scorer(s));
319278
return this;
320279
}
321280

322-
async execute(): Promise<AgentsResult<T>> {
281+
private async execute(): Promise<AgentsResult<T>> {
323282
if (!this.mcpServer) {
324283
throw new Error("MCP server not set");
325284
}
326285

327286
const executionStartTime = Date.now();
328287

329288
this.executionPromises = this.models.map(async (model) => {
330-
const provider = createProvider(
331-
model,
332-
this.mcpServer!,
333-
this.promptText,
334-
this.config,
335-
);
289+
const provider = createProvider(model, this.mcpServer!, this.promptText, this.config);
336290
const result = await provider.stream(model);
337291

338292
this.usedTools[model] = result.usedTools;
@@ -358,16 +312,9 @@ export class AgentsClient<T extends ModelName = ModelName> {
358312
acc[response.model as T] = response;
359313
return acc;
360314
},
361-
{} as Record<T, AgentResponse>,
315+
{} as Record<T, AgentResponse>
362316
);
363317

364-
return new AgentsResult(
365-
responsesMap,
366-
executionStartTime,
367-
executionEndTime,
368-
this.models,
369-
this,
370-
this._scorers,
371-
);
318+
return new AgentsResult(responsesMap, executionStartTime, executionEndTime, this.models, this, this._scorers);
372319
}
373320
}

packages/mcp-check/src/providers/types.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { Scorer } from "src/index.js";
12
import type { ChunkHandlerConfig } from "../chunks/types.js";
23

34
/**
@@ -28,6 +29,6 @@ export interface ProviderConfig {
2829
chunkHandlers?: ChunkHandlerConfig;
2930
/** Whether to suppress console output during execution */
3031
silent?: boolean;
31-
/** Additional configuration properties */
32-
[key: string]: any;
32+
/** Scorers to score the output of the tools */
33+
scorers?: Scorer[];
3334
}

packages/mcp-check/tests/index.test.ts

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ const mcpServer = new McpServer({
99

1010
describe("get branches tool", function () {
1111
test("should retrieve available branches from Basehub", async function () {
12-
const result = await client(mcpServer, [
13-
"claude-3-haiku-20240307",
14-
"claude-3-5-haiku-20241022",
15-
])
12+
const result = await client(mcpServer, ["claude-3-haiku-20240307", "claude-3-5-haiku-20241022"])
1613
.scorers([
1714
{
1815
name: "contains id",
@@ -21,9 +18,7 @@ describe("get branches tool", function () {
2118
try {
2219
const resultText = output[0]?.text;
2320
const branches = JSON.parse(resultText);
24-
return branches.some((branch: { id: string }) => branch.id)
25-
? 1
26-
: 0;
21+
return branches.some((branch: { id: string }) => branch.id) ? 1 : 0;
2722
} catch (e) {
2823
console.log("Parse error:", e);
2924
return 0;
@@ -33,16 +28,10 @@ describe("get branches tool", function () {
3328
])
3429
.prompt("What branches are available in this Basehub repo?");
3530

36-
expect(
37-
result.hasUsedTool("claude-3-5-haiku-20241022", "list_branches"),
38-
).toBe(true);
39-
expect(result.getUsedTools("claude-3-5-haiku-20241022")).toEqual(
40-
expect.arrayContaining(["list_branches"]),
41-
);
31+
expect(result.hasUsedTool("claude-3-5-haiku-20241022", "list_branches")).toBe(true);
32+
expect(result.getUsedTools("claude-3-5-haiku-20241022")).toEqual(expect.arrayContaining(["list_branches"]));
4233

43-
expect(
44-
result.getToolCallCount("claude-3-5-haiku-20241022", "list_branches"),
45-
).toBeGreaterThan(0);
34+
expect(result.getToolCallCount("claude-3-5-haiku-20241022", "list_branches")).toBeGreaterThan(0);
4635

4736
const response = result.getResponse("claude-3-5-haiku-20241022");
4837

@@ -56,9 +45,7 @@ describe("get branches tool", function () {
5645
expect(executionResult.summary.executionTime).toBeGreaterThan(0);
5746

5847
expect(executionResult.responses["claude-3-haiku-20240307"]).toBeDefined();
59-
expect(
60-
executionResult.responses["claude-3-5-haiku-20241022"],
61-
).toBeDefined();
48+
expect(executionResult.responses["claude-3-5-haiku-20241022"]).toBeDefined();
6249

6350
expect(result.getResponse("claude-3-5-haiku-20241022")).toBeDefined();
6451
expect(result.getAgentNames()).toContain("claude-3-haiku-20240307");

0 commit comments

Comments
 (0)