@genkit-ai/mcp 1.33.0 → 1.34.0

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.
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Copyright 2026 Google LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
18
+ import * as assert from 'assert';
19
+ import { genkit } from 'genkit';
20
+ import { describe, it } from 'node:test';
21
+ import { registerAllTools } from '../src/util/tools.js';
22
+ import { FakeTransport } from './fakes.js';
23
+
24
+ describe('registerAllTools', () => {
25
+ it('should pass _meta from context to callTool request', async () => {
26
+ const ai = genkit({});
27
+ const transport = new FakeTransport();
28
+ transport.tools.push({
29
+ name: 'testTool',
30
+ description: 'A tool for testing',
31
+ inputSchema: {
32
+ type: 'object',
33
+ properties: {},
34
+ $schema: 'http://json-schema.org/draft-07/schema#',
35
+ },
36
+ });
37
+
38
+ transport.callToolResult = {
39
+ content: [{ type: 'text', text: 'response' }],
40
+ };
41
+
42
+ const client = new Client({ name: 'test', version: '1.0' });
43
+ await client.connect(transport);
44
+
45
+ await registerAllTools(ai, client, {
46
+ name: 'test-host',
47
+ serverName: 'test-server',
48
+ });
49
+
50
+ const action = await ai.registry.lookupAction('/tool/test-server/testTool');
51
+ assert.ok(action);
52
+
53
+ const result = await action(
54
+ {},
55
+ { context: { mcp: { _meta: { progressToken: 'token-123' } } } }
56
+ );
57
+
58
+ // The fake transport appends the _meta object to the result content
59
+ assert.deepStrictEqual(result, 'response{"progressToken":"token-123"}');
60
+ });
61
+
62
+ it('should pass _meta from context to callTool request for multipart tools', async () => {
63
+ const ai = genkit({});
64
+ const transport = new FakeTransport();
65
+ transport.tools.push({
66
+ name: 'testMultipartTool',
67
+ description: 'A tool for testing multipart',
68
+ inputSchema: {
69
+ type: 'object',
70
+ properties: {},
71
+ $schema: 'http://json-schema.org/draft-07/schema#',
72
+ },
73
+ });
74
+
75
+ transport.callToolResult = {
76
+ content: [{ type: 'text', text: 'response' }],
77
+ };
78
+
79
+ const client = new Client({ name: 'test', version: '1.0' });
80
+ await client.connect(transport);
81
+
82
+ await registerAllTools(ai, client, {
83
+ name: 'test-host',
84
+ serverName: 'test-server',
85
+ multipart: true,
86
+ });
87
+
88
+ const action = await ai.registry.lookupAction(
89
+ '/tool.v2/test-server/testMultipartTool'
90
+ );
91
+ assert.ok(action);
92
+
93
+ const result = await action(
94
+ {},
95
+ { context: { mcp: { _meta: { progressToken: 'token-multipart' } } } }
96
+ );
97
+
98
+ assert.deepStrictEqual(result, {
99
+ output: 'response{"progressToken":"token-multipart"}',
100
+ metadata: undefined,
101
+ });
102
+ });
103
+
104
+ it('should return structuredContent as output', async () => {
105
+ const ai = genkit({});
106
+ const transport = new FakeTransport();
107
+ transport.tools.push({
108
+ name: 'testStructuredTool',
109
+ description: 'A tool for testing structured content',
110
+ inputSchema: {
111
+ type: 'object',
112
+ properties: {},
113
+ $schema: 'http://json-schema.org/draft-07/schema#',
114
+ },
115
+ });
116
+
117
+ transport.callToolResult = {
118
+ content: [{ type: 'text', text: 'this text is ignored' }],
119
+ structuredContent: { foo: 'bar', count: 42 },
120
+ };
121
+
122
+ const client = new Client({ name: 'test', version: '1.0' });
123
+ await client.connect(transport);
124
+
125
+ await registerAllTools(ai, client, {
126
+ name: 'test-host',
127
+ serverName: 'test-server',
128
+ multipart: true,
129
+ });
130
+
131
+ const action = await ai.registry.lookupAction(
132
+ '/tool.v2/test-server/testStructuredTool'
133
+ );
134
+ assert.ok(action);
135
+
136
+ const result = await action({}, {});
137
+
138
+ assert.deepStrictEqual(result, {
139
+ output: { foo: 'bar', count: 42 },
140
+ metadata: undefined,
141
+ });
142
+ });
143
+
144
+ it('should map audio and resource_link to content parts', async () => {
145
+ const ai = genkit({});
146
+ const transport = new FakeTransport();
147
+ transport.tools.push({
148
+ name: 'testMediaTool',
149
+ description: 'A tool for testing audio and resource links',
150
+ inputSchema: {
151
+ type: 'object',
152
+ properties: {},
153
+ $schema: 'http://json-schema.org/draft-07/schema#',
154
+ },
155
+ });
156
+
157
+ transport.callToolResult = {
158
+ content: [
159
+ { type: 'audio', data: 'base64audio', mimeType: 'audio/wav' },
160
+ {
161
+ type: 'resource_link',
162
+ uri: 'file:///my-file.txt',
163
+ name: 'my-file.txt',
164
+ },
165
+ ],
166
+ };
167
+
168
+ const client = new Client({ name: 'test', version: '1.0' });
169
+ await client.connect(transport);
170
+
171
+ await registerAllTools(ai, client, {
172
+ name: 'test-host',
173
+ serverName: 'test-server',
174
+ multipart: true,
175
+ });
176
+
177
+ const action = await ai.registry.lookupAction(
178
+ '/tool.v2/test-server/testMediaTool'
179
+ );
180
+ assert.ok(action);
181
+
182
+ const result = await action({}, {});
183
+
184
+ assert.deepStrictEqual(result, {
185
+ content: [
186
+ {
187
+ media: {
188
+ url: 'data:audio/wav;base64,base64audio',
189
+ contentType: 'audio/wav',
190
+ },
191
+ },
192
+ {
193
+ resource: {
194
+ uri: 'file:///my-file.txt',
195
+ },
196
+ },
197
+ ],
198
+ metadata: undefined,
199
+ });
200
+ });
201
+ });