Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- Added `outputSchema` support for local MCP tools.
- Added `appcheck:providers:list`, `appcheck:providers:get` and `appcheck:providers:set` to configure App Check attestation providers for an app.
- Added `appcheck:apps:list` to show every app with its configured App Check providers.
- Added web app support for Crashlytics MCP tools and prompts.
Expand Down
2 changes: 2 additions & 0 deletions src/mcp/onemcp/onemcp_server.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
name: "test_tool",
description: "A test tool",
inputSchema: { type: "object", properties: {} },
outputSchema: { type: "object", properties: { status: { type: "string" } } },
};
clientRequestStub.resolves({
body: {
Expand All @@ -47,13 +48,14 @@
expect(tools).to.have.length(1);
expect(tools[0].mcp.name).to.equal("auth_test_tool");
expect(tools[0].mcp.description).to.equal(mockMcpTool.description);
expect(tools[0].mcp.outputSchema).to.deep.equal(mockMcpTool.outputSchema);
expect(tools[0].mcp._meta).to.deep.equal({
requiresAuth: false,
requiresProject: true,
feature: "auth",
});
expect(clientRequestStub).to.have.been.calledOnce;
expect(clientRequestStub.firstCall.args[0].headers).to.deep.include({

Check warning on line 58 in src/mcp/onemcp/onemcp_server.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe member access .headers on an `any` value
"MCP-Protocol-Version": LATEST_PROTOCOL_VERSION,
"Mcp-Method": "tools/list",
});
Expand Down Expand Up @@ -104,7 +106,7 @@
});

describe("callTool", () => {
const mockContext: any = {

Check warning on line 109 in src/mcp/onemcp/onemcp_server.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unexpected any. Specify a different type
projectId: "test-project",
};

Expand All @@ -122,11 +124,11 @@
body: { result: mockCallResult },
});

const result = await tool.fn({ arg: "val" }, mockContext);

Check warning on line 127 in src/mcp/onemcp/onemcp_server.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe argument of type `any` assigned to a parameter of type `McpContext`

expect(result).to.deep.equal(mockCallResult);
expect(ensureStub).to.have.been.calledOnceWith(
mockContext.projectId,

Check warning on line 131 in src/mcp/onemcp/onemcp_server.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe member access .projectId on an `any` value
serverUrl,
feature,
true,
Expand All @@ -143,7 +145,7 @@
id: 1,
},
});
expect(clientRequestStub.secondCall.args[0].headers).to.deep.include({

Check warning on line 148 in src/mcp/onemcp/onemcp_server.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe member access .headers on an `any` value
"MCP-Protocol-Version": LATEST_PROTOCOL_VERSION,
"Mcp-Method": "tools/call",
"Mcp-Name": "test_tool",
Expand Down Expand Up @@ -178,9 +180,9 @@
body: { result: { content: [] } },
});

await tool.fn({ region: "us-west1", query: "SELECT 1" }, mockContext);

Check warning on line 183 in src/mcp/onemcp/onemcp_server.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe argument of type `any` assigned to a parameter of type `McpContext`

expect(clientRequestStub.secondCall.args[0].headers).to.deep.include({

Check warning on line 185 in src/mcp/onemcp/onemcp_server.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe member access .headers on an `any` value
"MCP-Protocol-Version": LATEST_PROTOCOL_VERSION,
"Mcp-Method": "tools/call",
"Mcp-Name": "execute_sql",
Expand All @@ -202,10 +204,10 @@
body: { result: { content: [] } },
});

await tool.fn({ arg: "val" }, { ...mockContext, projectId: undefined });

Check warning on line 207 in src/mcp/onemcp/onemcp_server.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe argument of type `any` assigned to a parameter of type `McpContext`

expect(clientRequestStub.secondCall.args[0].headers?.["x-goog-user-project"]).to.be.undefined;

Check warning on line 209 in src/mcp/onemcp/onemcp_server.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe member access .headers on an `any` value
expect(clientRequestStub.secondCall.args[0].headers).to.deep.equal({

Check warning on line 210 in src/mcp/onemcp/onemcp_server.spec.ts

View workflow job for this annotation

GitHub Actions / lint (24)

Unsafe member access .headers on an `any` value
"MCP-Protocol-Version": LATEST_PROTOCOL_VERSION,
"Mcp-Method": "tools/call",
"Mcp-Name": "test_tool",
Expand Down
3 changes: 3 additions & 0 deletions src/mcp/tool.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,15 @@ describe("tool", () => {
name: "test_tool",
description: "A test tool",
inputSchema: z.object({}),
outputSchema: z.object({ result: z.string() }),
},
testFn,
);

expect(testTool.mcp.name).to.equal("test_tool");
expect(testTool.mcp.description).to.equal("A test tool");
expect(testTool.mcp.outputSchema).to.not.be.undefined;
expect(testTool.mcp.outputSchema.properties.result.type).to.equal("string");
expect(testTool.fn).to.equal(testFn);
});

Expand Down
13 changes: 11 additions & 2 deletions src/mcp/tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface ServerTool<InputSchema extends ZodTypeAny = z.ZodAny> {
name: string;
description?: string;
inputSchema: any;
outputSchema?: any;
annotations?: {
title?: string;

Expand All @@ -47,10 +48,11 @@ export interface ServerTool<InputSchema extends ZodTypeAny = z.ZodAny> {
isAvailable: (ctx: McpContext) => Promise<boolean>;
}

export function tool<InputSchema extends ZodTypeAny>(
export function tool<InputSchema extends ZodTypeAny, OutputSchema extends ZodTypeAny = z.ZodAny>(
feature: ServerFeature,
options: Omit<ServerTool<InputSchema>["mcp"], "inputSchema"> & {
options: Omit<ServerTool<InputSchema>["mcp"], "inputSchema" | "outputSchema"> & {
inputSchema: InputSchema;
outputSchema?: OutputSchema;
isAvailable?: (ctx: McpContext) => Promise<boolean>;
},
fn: ServerTool<InputSchema>["fn"],
Expand All @@ -63,6 +65,13 @@ export function tool<InputSchema extends ZodTypeAny>(
inputSchema: cleanSchema(
z.toJSONSchema(options.inputSchema, { target: "draft-7", io: "input" }),
),
...(options.outputSchema
? {
outputSchema: cleanSchema(
z.toJSONSchema(options.outputSchema, { target: "draft-7", io: "output" }),
),
}
: {}),
},
fn,
isAvailable: (ctx: McpContext) => {
Expand Down
Loading