Skip to content

Commit 35e7fef

Browse files
authored
feat!: add MCP support (#196)
* feat: add MCP v20241105 (#189) * refactor: move transport logic to a ToolboxTransport class * rename file * update license * basic lint * lint * log errors properly * fix error handling * add test cov * lint * add new version * add e2e tests for mcp * update license * basic lint * update license * fix tests * add tests * keep toolbox protocol to be default * add test cov * add test cov * lint * rename e2e test file * lint * fix tests * fix license * fix tests * small refactor * lint * fix e2e tests * fix unit tests * lint * lint * add more tests * lint * fix tests * fix error handling * fix e2e tests * add mcp tests to jest config * use package version * Revert "use package version" This reverts commit 9f13278. * use dynamic versions * lint * better way to use dynamic versions * chore: fix package release versioning (#197) * fix versioning * cc * remove version from adk * feat: add MCP v20250326 (#190) * refactor: move transport logic to a ToolboxTransport class * rename file * update license * basic lint * lint * log errors properly * fix error handling * add test cov * lint * add new version * add e2e tests for mcp * update license * basic lint * update license * fix tests * add tests * keep toolbox protocol to be default * add test cov * add test cov * lint * rename e2e test file * lint * fix tests * fix license * fix tests * small refactor * lint * fix e2e tests * fix unit tests * lint * lint * add more tests * lint * fix tests * fix error handling * fix e2e tests * add new version * cc * add mcp tests to jest config * use package version * Revert "use package version" This reverts commit 9f13278. * use dynamic versions * update version * fix merge issues * feat: add MCP v20250618 (#198) * refactor: move transport logic to a ToolboxTransport class * rename file * update license * basic lint * lint * log errors properly * fix error handling * add test cov * lint * add new version * add e2e tests for mcp * update license * basic lint * update license * fix tests * add tests * keep toolbox protocol to be default * add test cov * add test cov * lint * rename e2e test file * lint * fix tests * fix license * fix tests * small refactor * lint * fix e2e tests * fix unit tests * lint * lint * add more tests * lint * fix tests * fix error handling * fix e2e tests * add new version * cc * add mcp tests to jest config * use package version * Revert "use package version" This reverts commit 9f13278. * use dynamic versions * update version * fix merge issues * feat: add MCP v20250618 (#191) * feat: add MCP v20250618 * fix version issue * lint * feat!: make mcp the default protocol (#199) * refactor: move transport logic to a ToolboxTransport class * rename file * update license * basic lint * lint * log errors properly * fix error handling * add test cov * lint * add new version * add e2e tests for mcp * update license * basic lint * update license * fix tests * add tests * keep toolbox protocol to be default * add test cov * add test cov * lint * rename e2e test file * lint * fix tests * fix license * fix tests * small refactor * lint * fix e2e tests * fix unit tests * lint * lint * add more tests * lint * fix tests * fix error handling * fix e2e tests * add new version * cc * feat: add MCP v20250618 * feat: make mcp the default protocol * allow protocol passing into toolbox-adk * run e2e test with toolbox protocol * expose protocol from adk package * add mcp tests to jest config * use package version * Revert "use package version" This reverts commit 9f13278. * use dynamic versions * update version * fix merge issues * fix version issue * fix(mcp): correctly propagate client headers during init (#201) * fix(mcp): correctly propagate client headers during init * fix packaging conflicts * docs(mcp): add transport protocol info (#202) * docs(mcp): add transport protocol info * Update README.md * update toc
1 parent 202ebab commit 35e7fef

29 files changed

+4808
-21
lines changed

package-lock.json

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/toolbox-adk/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ involving Large Language Models (LLMs).
2020
- [Installation](#installation)
2121
- [Quickstart](#quickstart)
2222
- [Usage](#usage)
23+
- [Transport Protocols](#transport-protocols)
24+
- [Available Protocols](#available-protocols)
25+
- [Specifying a Protocol](#specifying-a-protocol)
2326
- [Loading Tools](#loading-tools)
2427
- [Load a toolset](#load-a-toolset)
2528
- [Load a single tool](#load-a-single-tool)
@@ -123,6 +126,34 @@ All interactions for loading and invoking tools happen through this client.
123126
> For advanced use cases, you can provide an external `AxiosInstance`
124127
> during initialization (e.g., `ToolboxClient(url, my_session)`).
125128
129+
130+
## Transport Protocols
131+
132+
The SDK supports multiple transport protocols to communicate with the Toolbox server. You can specify the protocol version during client initialization.
133+
134+
### Available Protocols
135+
136+
- `Protocol.MCP`: The default protocol (currently aliases to `MCP_v20250618`).
137+
- `Protocol.MCP_v20241105`: Use this for compatibility with older MCP servers (November 2024 version).
138+
- `Protocol.MCP_v20250326`: March 2025 version.
139+
- `Protocol.MCP_v20250618`: June 2025 version.
140+
- `Protocol.TOOLBOX`: Legacy Toolbox protocol.
141+
142+
### Specifying a Protocol
143+
144+
You can explicitly set the protocol by passing the `protocol` argument to the `ToolboxClient` constructor.
145+
146+
```javascript
147+
import { ToolboxClient, Protocol } from '@toolbox-sdk/adk';
148+
149+
const URL = 'http://127.0.0.1:5000';
150+
151+
// Initialize with a specific protocol version
152+
const client = new ToolboxClient(URL, null, null, Protocol.MCP_v20241105);
153+
154+
const tools = await client.loadToolset();
155+
```
156+
126157
## Loading Tools
127158

128159
You can load tools individually or in groups (toolsets) as defined in your

packages/toolbox-adk/src/toolbox_adk/client.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
AuthTokenGetters,
1818
BoundParams,
1919
ClientHeadersConfig,
20+
Protocol,
2021
} from '@toolbox-sdk/core';
2122
import {ToolboxTool, CoreTool} from './tool.js';
2223
import type {AxiosInstance} from 'axios';
@@ -44,8 +45,14 @@ export class ToolboxClient {
4445
url: string,
4546
session?: AxiosInstance | null,
4647
clientHeaders?: ClientHeadersConfig | null,
48+
protocol: Protocol = Protocol.MCP,
4749
) {
48-
this.coreClient = new CoreToolboxClient(url, session, clientHeaders);
50+
this.coreClient = new CoreToolboxClient(
51+
url,
52+
session,
53+
clientHeaders,
54+
protocol,
55+
);
4956
}
5057

5158
/**

packages/toolbox-adk/src/toolbox_adk/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717
// Export the main factory function and the core tool type
1818
export {ToolboxClient} from './client.js';
1919
export {ToolboxTool} from './tool.js';
20+
export {Protocol} from '@toolbox-sdk/core';

packages/toolbox-adk/test/e2e/test.e2e.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
import {ToolboxClient} from '../../src/toolbox_adk/client.js';
16-
import {ToolboxTool} from '../../src/toolbox_adk/tool.js';
15+
import {
16+
ToolboxClient,
17+
ToolboxTool,
18+
Protocol,
19+
} from '../../src/toolbox_adk/index.js';
1720

1821
import {AxiosError} from 'axios';
1922
import {CustomGlobal} from './types.js';
@@ -30,7 +33,12 @@ describe('ToolboxClient E2E Tests', () => {
3033
const mockToolContext = {} as ToolContext;
3134

3235
beforeAll(async () => {
33-
commonToolboxClient = new ToolboxClient(testBaseUrl);
36+
commonToolboxClient = new ToolboxClient(
37+
testBaseUrl,
38+
undefined,
39+
undefined,
40+
Protocol.TOOLBOX,
41+
);
3442
});
3543

3644
beforeEach(async () => {

packages/toolbox-adk/test/test.client.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type MockCoreClientConstructor = (
3434
url: string,
3535
session?: AxiosInstance | null,
3636
clientHeaders?: ClientHeadersConfig | null,
37+
protocol?: string | null,
3738
) => MockCoreClient;
3839

3940
const mockLoadTool =
@@ -66,6 +67,10 @@ const MockToolboxTool = jest.fn();
6667

6768
jest.unstable_mockModule('@toolbox-sdk/core', () => ({
6869
ToolboxClient: MockCoreToolboxClient,
70+
Protocol: {
71+
MCP: 'mcp-default',
72+
TOOLBOX: 'toolbox',
73+
},
6974
}));
7075

7176
jest.unstable_mockModule('../src/toolbox_adk/tool.js', () => ({
@@ -94,6 +99,7 @@ describe('ToolboxClient', () => {
9499
'http://test.url',
95100
mockSession,
96101
mockHeaders,
102+
'mcp-default',
97103
);
98104
});
99105

packages/toolbox-core/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ involving Large Language Models (LLMs).
1818
- [Installation](#installation)
1919
- [Quickstart](#quickstart)
2020
- [Usage](#usage)
21+
- [Transport Protocols](#transport-protocols)
22+
- [Available Protocols](#available-protocols)
23+
- [Specifying a Protocol](#specifying-a-protocol)
2124
- [Loading Tools](#loading-tools)
2225
- [Load a toolset](#load-a-toolset)
2326
- [Load a single tool](#load-a-single-tool)
@@ -121,6 +124,34 @@ All interactions for loading and invoking tools happen through this client.
121124
> For advanced use cases, you can provide an external `AxiosInstance`
122125
> during initialization (e.g., `ToolboxClient(url, my_session)`).
123126
127+
128+
## Transport Protocols
129+
130+
The SDK supports multiple transport protocols to communicate with the Toolbox server. You can specify the protocol version during client initialization.
131+
132+
### Available Protocols
133+
134+
- `Protocol.MCP`: The default protocol (currently aliases to `MCP_v20250618`).
135+
- `Protocol.MCP_v20241105`: Use this for compatibility with older MCP servers (November 2024 version).
136+
- `Protocol.MCP_v20250326`: March 2025 version.
137+
- `Protocol.MCP_v20250618`: June 2025 version.
138+
- `Protocol.TOOLBOX`: Legacy Toolbox protocol.
139+
140+
### Specifying a Protocol
141+
142+
You can explicitly set the protocol by passing the `protocol` argument to the `ToolboxClient` constructor.
143+
144+
```javascript
145+
import { ToolboxClient, Protocol } from '@toolbox-sdk/core';
146+
147+
const URL = 'http://127.0.0.1:5000';
148+
149+
// Initialize with a specific protocol version
150+
const client = new ToolboxClient(URL, null, null, Protocol.MCP_v20241105);
151+
152+
const tools = await client.loadToolset();
153+
```
154+
124155
## Loading Tools
125156

126157
You can load tools individually or in groups (toolsets) as defined in your

packages/toolbox-core/jest.config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"testMatch": [
3-
"<rootDir>/test/*.ts"
3+
"<rootDir>/test/*.ts",
4+
"<rootDir>/test/mcp/*.ts"
45
],
56
"preset": "ts-jest",
67
"transform": {

packages/toolbox-core/package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717
],
1818
"exports": {
1919
".": {
20-
"import": "./build/index.js",
20+
"import": "./build/esm/index.js",
2121
"require": "./build/cjs/index.js",
22-
"types": "./build/index.d.ts"
22+
"types": "./build/esm/index.d.ts"
2323
},
2424
"./auth": {
25-
"import": "./build/authMethods.js",
25+
"import": "./build/esm/authMethods.js",
2626
"require": "./build/cjs/authMethods.js",
27-
"types": "./build/authMethods.d.ts"
27+
"types": "./build/esm/authMethods.d.ts"
2828
}
2929
},
3030
"files": [
@@ -63,6 +63,7 @@
6363
"zod": "^3.24.4"
6464
},
6565
"devDependencies": {
66+
"@types/uuid": "^10.0.0",
6667
"rimraf": "^6.1.2"
6768
}
6869
}

packages/toolbox-core/src/toolbox_core/client.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ import {
2020
createZodSchemaFromParams,
2121
ParameterSchema,
2222
ZodManifestSchema,
23+
Protocol,
24+
getSupportedMcpVersions,
2325
} from './protocol.js';
26+
import {McpHttpTransportV20241105} from './mcp/v20241105/mcp.js';
27+
import {McpHttpTransportV20250618} from './mcp/v20250618/mcp.js';
28+
import {McpHttpTransportV20250326} from './mcp/v20250326/mcp.js';
2429
import {BoundParams, identifyAuthRequirements, resolveValue} from './utils.js';
2530
import {AuthTokenGetters, RequiredAuthnParams} from './tool.js';
2631

@@ -51,9 +56,36 @@ class ToolboxClient {
5156
url: string,
5257
session?: AxiosInstance | null,
5358
clientHeaders?: ClientHeadersConfig | null,
59+
protocol: Protocol = Protocol.MCP,
5460
) {
55-
this.#transport = new ToolboxTransport(url, session || undefined);
5661
this.#clientHeaders = clientHeaders || {};
62+
if (protocol === Protocol.TOOLBOX) {
63+
this.#transport = new ToolboxTransport(url, session || undefined);
64+
} else if (getSupportedMcpVersions().includes(protocol)) {
65+
if (protocol === Protocol.MCP_v20241105) {
66+
this.#transport = new McpHttpTransportV20241105(
67+
url,
68+
session || undefined,
69+
protocol,
70+
);
71+
} else if (protocol === Protocol.MCP_v20250326) {
72+
this.#transport = new McpHttpTransportV20250326(
73+
url,
74+
session || undefined,
75+
protocol,
76+
);
77+
} else if (protocol === Protocol.MCP_v20250618) {
78+
this.#transport = new McpHttpTransportV20250618(
79+
url,
80+
session || undefined,
81+
protocol,
82+
);
83+
} else {
84+
throw new Error(`Unsupported MCP protocol version: ${protocol}`);
85+
}
86+
} else {
87+
throw new Error(`Unsupported protocol version: ${protocol}`);
88+
}
5789
}
5890

5991
/**

0 commit comments

Comments
 (0)