@toolbox-sdk/core
Version:
JavaScript Base SDK for interacting with the Toolbox service
138 lines • 5.19 kB
JavaScript
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { z } from 'zod';
export var Protocol;
(function (Protocol) {
Protocol["MCP_v20241105"] = "2024-11-05";
Protocol["MCP_v20250326"] = "2025-03-26";
Protocol["MCP_v20250618"] = "2025-06-18";
Protocol["MCP_v20251125"] = "2025-11-25";
Protocol["MCP_v20260728"] = "2026-07-28";
Protocol["MCP_DRAFT_2026_v1"] = "2026-07-28";
Protocol["MCP"] = "2026-07-28";
Protocol["MCP_LATEST"] = "2026-07-28";
Protocol["MCP_DRAFT"] = "2026-07-28";
})(Protocol || (Protocol = {}));
export const MCP_LATEST = Protocol.MCP_LATEST;
export function getSupportedMcpVersions() {
return [
Protocol.MCP_v20260728,
Protocol.MCP_v20251125,
Protocol.MCP_v20250618,
Protocol.MCP_v20250326,
Protocol.MCP_v20241105,
];
}
export function isVersionAtLeast(currentVersion, minVersion) {
const supported = getSupportedMcpVersions();
const currentIndex = supported.indexOf(currentVersion);
if (currentIndex === -1) {
throw new Error(`Unrecognized protocol version: '${currentVersion}'`);
}
const minIndex = supported.indexOf(minVersion);
if (minIndex === -1) {
throw new Error(`Unrecognized target protocol version: '${minVersion}'`);
}
return currentIndex <= minIndex;
}
const ZodPrimitiveTypeSchema = z.discriminatedUnion('type', [
z.object({ type: z.literal('string') }),
z.object({ type: z.literal('integer') }),
z.object({ type: z.literal('float') }),
z.object({ type: z.literal('number') }),
z.object({ type: z.literal('boolean') }),
]);
// Zod schema for the pure type definitions. This must be lazy for recursion.
const ZodTypeSchema = z.lazy(() => z.discriminatedUnion('type', [
z.object({ type: z.literal('string') }),
z.object({ type: z.literal('integer') }),
z.object({ type: z.literal('float') }),
z.object({ type: z.literal('number') }),
z.object({ type: z.literal('boolean') }),
z.object({ type: z.literal('array'), items: ZodTypeSchema.optional() }),
z.object({
type: z.literal('object'),
additionalProperties: z
.union([z.boolean(), ZodPrimitiveTypeSchema])
.optional(),
}),
]));
// Zod schema for the base properties.
const ZodBaseParameter = z.object({
name: z.string().min(1, 'Parameter name cannot be empty'),
description: z.string(),
authSources: z.array(z.string()).optional(),
required: z.boolean().optional(),
default: z.any().optional(),
});
export const ZodParameterSchema = ZodBaseParameter.and(ZodTypeSchema);
export const ZodToolSchema = z.object({
description: z.string().min(1, 'Tool description cannot be empty'),
parameters: z.array(ZodParameterSchema),
authRequired: z.array(z.string()).optional(),
});
export const ZodManifestSchema = z.object({
serverVersion: z.string().min(1, 'Server version cannot be empty'),
tools: z.record(z.string().min(1, 'Tool name cannot be empty'), ZodToolSchema),
});
function buildZodShapeFromTypeSchema(typeSchema) {
switch (typeSchema.type) {
case 'string':
return z.string();
case 'integer':
return z.number().int();
case 'float':
case 'number':
return z.number();
case 'boolean':
return z.boolean();
case 'array':
if (!typeSchema.items) {
return z.array(z.any());
}
return z.array(buildZodShapeFromTypeSchema(typeSchema.items));
case 'object':
if (typeof typeSchema.additionalProperties === 'object') {
return z.record(z.string(), buildZodShapeFromTypeSchema(typeSchema.additionalProperties));
}
else if (typeSchema.additionalProperties === false) {
return z.object({});
}
else {
return z.record(z.string(), z.any());
}
default: {
const _exhaustiveCheck = typeSchema;
throw new Error(`Unknown parameter type: ${_exhaustiveCheck['type']}`);
}
}
}
function buildZodShapeFromParam(param) {
let schema = buildZodShapeFromTypeSchema(param);
if (param.required === false) {
schema = schema.nullish();
}
if (param.default !== undefined) {
schema = schema.default(param.default);
}
return schema;
}
export function createZodSchemaFromParams(params) {
const shape = {};
for (const param of params) {
shape[param.name] = buildZodShapeFromParam(param);
}
return z.object(shape).strict();
}
//# sourceMappingURL=protocol.js.map