@smithery/sdk 1.2.3 → 1.3.2
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.
- package/README.md +2 -2
- package/dist/client/integrations/ai-sdk.d.ts +15 -0
- package/dist/client/integrations/ai-sdk.js +39 -0
- package/dist/{integrations/error-adapter.d.ts → client/integrations/wrap-error.d.ts} +1 -1
- package/dist/{integrations/error-adapter.js → client/integrations/wrap-error.js} +4 -5
- package/dist/client/transport.d.ts +3 -3
- package/dist/client/transport.js +4 -5
- package/dist/server/session.d.ts +17 -0
- package/dist/server/session.js +36 -0
- package/dist/server/stateful.d.ts +12 -1
- package/dist/server/stateful.js +15 -13
- package/dist/server/stateless.js +1 -1
- package/dist/{config.d.ts → shared/config.d.ts} +7 -3
- package/dist/{config.js → shared/config.js} +10 -8
- package/dist/shared/patch.d.ts +12 -0
- package/dist/shared/patch.js +12 -0
- package/package.json +4 -1
- /package/dist/{integrations → client/integrations}/llm/anthropic.d.ts +0 -0
- /package/dist/{integrations → client/integrations}/llm/anthropic.js +0 -0
- /package/dist/{integrations → client/integrations}/llm/openai.d.ts +0 -0
- /package/dist/{integrations → client/integrations}/llm/openai.js +0 -0
package/README.md
CHANGED
|
@@ -22,14 +22,14 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"
|
|
|
22
22
|
function createMcpServer({ sessionId, config }) {
|
|
23
23
|
// Create and return a server instance
|
|
24
24
|
// https://github.com/modelcontextprotocol/typescript-sdk?tab=readme-ov-file#core-concepts
|
|
25
|
-
const
|
|
25
|
+
const mcpServer = new McpServer({
|
|
26
26
|
name: "My App",
|
|
27
27
|
version: "1.0.0"
|
|
28
28
|
})
|
|
29
29
|
|
|
30
30
|
// ...
|
|
31
31
|
|
|
32
|
-
return server
|
|
32
|
+
return mcpServer.server
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
// Create the stateless server using your MCP server function.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
|
+
import { type Tool } from "ai";
|
|
3
|
+
type ToolClient = Pick<Client, "listTools" | "callTool" | "setNotificationHandler">;
|
|
4
|
+
/**
|
|
5
|
+
* Watches the MCP client for tool changes and updates the tools object accordingly.
|
|
6
|
+
* @param client The MCP client to watch
|
|
7
|
+
* @returns A record of tool names to their implementations
|
|
8
|
+
*/
|
|
9
|
+
export declare function watchTools(client: ToolClient): Promise<Record<string, Tool>>;
|
|
10
|
+
/**
|
|
11
|
+
* Returns a set of wrapped AI SDK tools from the MCP server.
|
|
12
|
+
* @returns A record of tool names to their implementations
|
|
13
|
+
*/
|
|
14
|
+
export declare function listTools(client: ToolClient): Promise<Record<string, Tool>>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ToolListChangedNotificationSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import { jsonSchema, tool, } from "ai";
|
|
3
|
+
/**
|
|
4
|
+
* Watches the MCP client for tool changes and updates the tools object accordingly.
|
|
5
|
+
* @param client The MCP client to watch
|
|
6
|
+
* @returns A record of tool names to their implementations
|
|
7
|
+
*/
|
|
8
|
+
export async function watchTools(client) {
|
|
9
|
+
const tools = {};
|
|
10
|
+
client.setNotificationHandler(ToolListChangedNotificationSchema, async () => {
|
|
11
|
+
Object.assign(tools, await listTools(client));
|
|
12
|
+
});
|
|
13
|
+
Object.assign(tools, await listTools(client));
|
|
14
|
+
return tools;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Returns a set of wrapped AI SDK tools from the MCP server.
|
|
18
|
+
* @returns A record of tool names to their implementations
|
|
19
|
+
*/
|
|
20
|
+
export async function listTools(client) {
|
|
21
|
+
const tools = {};
|
|
22
|
+
const listToolsResult = await client.listTools();
|
|
23
|
+
for (const { name, description, inputSchema } of listToolsResult.tools) {
|
|
24
|
+
const parameters = jsonSchema(inputSchema);
|
|
25
|
+
tools[name] = tool({
|
|
26
|
+
description,
|
|
27
|
+
parameters,
|
|
28
|
+
execute: async (args, options) => {
|
|
29
|
+
options?.abortSignal?.throwIfAborted();
|
|
30
|
+
const result = await client.callTool({
|
|
31
|
+
name,
|
|
32
|
+
arguments: args,
|
|
33
|
+
});
|
|
34
|
+
return result;
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return tools;
|
|
39
|
+
}
|
|
@@ -2,4 +2,4 @@ import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Wraps each tool call so any errors get sent back to the LLM instead of throwing
|
|
4
4
|
*/
|
|
5
|
-
export declare function
|
|
5
|
+
export declare function wrapError<C extends Pick<Client, "callTool">>(client: C): C;
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { CallToolResultSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import { patch } from "../../shared/patch.js";
|
|
2
3
|
/**
|
|
3
4
|
* Wraps each tool call so any errors get sent back to the LLM instead of throwing
|
|
4
5
|
*/
|
|
5
|
-
export function
|
|
6
|
-
|
|
7
|
-
client.callTool = async (params, resultSchema = CallToolResultSchema, options) => {
|
|
6
|
+
export function wrapError(client) {
|
|
7
|
+
patch(client, "callTool", (callTool) => async (params, resultSchema = CallToolResultSchema, options) => {
|
|
8
8
|
try {
|
|
9
9
|
return await callTool(params, resultSchema, options);
|
|
10
10
|
}
|
|
11
11
|
catch (err) {
|
|
12
|
-
console.error("Tool calling error:", err);
|
|
13
12
|
return {
|
|
14
13
|
content: [
|
|
15
14
|
{
|
|
@@ -20,6 +19,6 @@ export function wrapErrorAdapter(client) {
|
|
|
20
19
|
isError: true,
|
|
21
20
|
};
|
|
22
21
|
}
|
|
23
|
-
};
|
|
22
|
+
});
|
|
24
23
|
return client;
|
|
25
24
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
2
|
+
import { type SmitheryUrlOptions } from "../shared/config.js";
|
|
2
3
|
/**
|
|
3
4
|
* Creates a transport to connect to the Smithery server
|
|
4
5
|
* @param baseUrl The URL of the Smithery server (without trailing slash or protocol)
|
|
5
|
-
* @param
|
|
6
|
-
* @param apiKey Optional API key for authentication
|
|
6
|
+
* @param options Optional configuration object
|
|
7
7
|
* @returns Transport
|
|
8
8
|
*/
|
|
9
|
-
export declare function createTransport(baseUrl: string,
|
|
9
|
+
export declare function createTransport(baseUrl: string, options?: SmitheryUrlOptions): StreamableHTTPClientTransport;
|
package/dist/client/transport.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
2
|
-
import { createSmitheryUrl } from "../config.js";
|
|
2
|
+
import { createSmitheryUrl } from "../shared/config.js";
|
|
3
3
|
/**
|
|
4
4
|
* Creates a transport to connect to the Smithery server
|
|
5
5
|
* @param baseUrl The URL of the Smithery server (without trailing slash or protocol)
|
|
6
|
-
* @param
|
|
7
|
-
* @param apiKey Optional API key for authentication
|
|
6
|
+
* @param options Optional configuration object
|
|
8
7
|
* @returns Transport
|
|
9
8
|
*/
|
|
10
|
-
export function createTransport(baseUrl,
|
|
11
|
-
return new StreamableHTTPClientTransport(createSmitheryUrl(
|
|
9
|
+
export function createTransport(baseUrl, options) {
|
|
10
|
+
return new StreamableHTTPClientTransport(createSmitheryUrl(baseUrl, options));
|
|
12
11
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
|
|
2
|
+
export interface SessionStore<T extends Transport> {
|
|
3
|
+
/** return existing transport (or `undefined`) */
|
|
4
|
+
get(id: string): T | undefined;
|
|
5
|
+
/** insert / update */
|
|
6
|
+
set(id: string, t: T): void;
|
|
7
|
+
/** optional - explicit eviction */
|
|
8
|
+
delete?(id: string): void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Minimal Map‑based LRU implementation that fulfils {@link SessionStore}.
|
|
12
|
+
* Keeps at most `max` transports; upon insert, the least‑recently‑used entry
|
|
13
|
+
* (oldest insertion order) is removed and the evicted transport is closed.
|
|
14
|
+
*
|
|
15
|
+
* @param max maximum number of sessions to retain (default = 1000)
|
|
16
|
+
*/
|
|
17
|
+
export declare const createLRUStore: <T extends Transport>(max?: number) => SessionStore<T>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Map‑based LRU implementation that fulfils {@link SessionStore}.
|
|
3
|
+
* Keeps at most `max` transports; upon insert, the least‑recently‑used entry
|
|
4
|
+
* (oldest insertion order) is removed and the evicted transport is closed.
|
|
5
|
+
*
|
|
6
|
+
* @param max maximum number of sessions to retain (default = 1000)
|
|
7
|
+
*/
|
|
8
|
+
export const createLRUStore = (max = 1000) => {
|
|
9
|
+
// ECMA‑262 §23.1.3.13 - the order of keys in a Map object is the order of insertion; operations that remove a key drop it from that order, and set appends when the key is new or has just been removed.
|
|
10
|
+
const cache = new Map();
|
|
11
|
+
return {
|
|
12
|
+
get: (id) => {
|
|
13
|
+
const t = cache.get(id);
|
|
14
|
+
if (!t)
|
|
15
|
+
return undefined;
|
|
16
|
+
// refresh position
|
|
17
|
+
cache.delete(id);
|
|
18
|
+
cache.set(id, t);
|
|
19
|
+
return t;
|
|
20
|
+
},
|
|
21
|
+
set: (id, transport) => {
|
|
22
|
+
if (cache.has(id)) {
|
|
23
|
+
// key already present - refresh position
|
|
24
|
+
cache.delete(id);
|
|
25
|
+
}
|
|
26
|
+
else if (cache.size >= max) {
|
|
27
|
+
// evict oldest entry (first in insertion order)
|
|
28
|
+
const [lruId, lruTransport] = cache.entries().next().value;
|
|
29
|
+
lruTransport.close?.();
|
|
30
|
+
cache.delete(lruId);
|
|
31
|
+
}
|
|
32
|
+
cache.set(id, transport);
|
|
33
|
+
},
|
|
34
|
+
delete: (id) => cache.delete(id),
|
|
35
|
+
};
|
|
36
|
+
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
1
2
|
import type { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
|
+
import { type SessionStore } from "./session.js";
|
|
2
4
|
/**
|
|
3
5
|
* Arguments when we create a new instance of your server
|
|
4
6
|
*/
|
|
@@ -7,12 +9,21 @@ export interface CreateServerArg<T = Record<string, unknown>> {
|
|
|
7
9
|
config: T;
|
|
8
10
|
}
|
|
9
11
|
export type CreateServerFn<T = Record<string, unknown>> = (arg: CreateServerArg<T>) => Server;
|
|
12
|
+
/**
|
|
13
|
+
* Configuration options for the stateful server
|
|
14
|
+
*/
|
|
15
|
+
export interface StatefulServerOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Session store to use for managing active sessions
|
|
18
|
+
*/
|
|
19
|
+
sessionStore?: SessionStore<StreamableHTTPServerTransport>;
|
|
20
|
+
}
|
|
10
21
|
/**
|
|
11
22
|
* Creates a stateful server for handling MCP requests.
|
|
12
23
|
* For every new session, we invoke createMcpServer to create a new instance of the server.
|
|
13
24
|
* @param createMcpServer Function to create an MCP server
|
|
14
25
|
* @returns Express app
|
|
15
26
|
*/
|
|
16
|
-
export declare function createStatefulServer<T = Record<string, unknown>>(createMcpServer: CreateServerFn<T
|
|
27
|
+
export declare function createStatefulServer<T = Record<string, unknown>>(createMcpServer: CreateServerFn<T>, options?: StatefulServerOptions): {
|
|
17
28
|
app: import("express-serve-static-core").Express;
|
|
18
29
|
};
|
package/dist/server/stateful.js
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
1
2
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
2
3
|
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
3
4
|
import express from "express";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
5
|
+
import { parseExpressRequestConfig } from "../shared/config.js";
|
|
6
|
+
import { createLRUStore } from "./session.js";
|
|
6
7
|
/**
|
|
7
8
|
* Creates a stateful server for handling MCP requests.
|
|
8
9
|
* For every new session, we invoke createMcpServer to create a new instance of the server.
|
|
9
10
|
* @param createMcpServer Function to create an MCP server
|
|
10
11
|
* @returns Express app
|
|
11
12
|
*/
|
|
12
|
-
export function createStatefulServer(createMcpServer) {
|
|
13
|
+
export function createStatefulServer(createMcpServer, options) {
|
|
13
14
|
const app = express();
|
|
14
15
|
app.use(express.json());
|
|
15
|
-
|
|
16
|
-
const transports = {};
|
|
16
|
+
const sessionStore = options?.sessionStore ?? createLRUStore();
|
|
17
17
|
// Handle POST requests for client-to-server communication
|
|
18
18
|
app.post("/mcp", async (req, res) => {
|
|
19
19
|
// Check for existing session ID
|
|
20
20
|
const sessionId = req.headers["mcp-session-id"];
|
|
21
21
|
let transport;
|
|
22
|
-
if (sessionId &&
|
|
22
|
+
if (sessionId && sessionStore.get(sessionId)) {
|
|
23
23
|
// Reuse existing transport
|
|
24
|
-
|
|
24
|
+
// biome-ignore lint/style/noNonNullAssertion: Not possible
|
|
25
|
+
transport = sessionStore.get(sessionId);
|
|
25
26
|
}
|
|
26
27
|
else if (!sessionId && isInitializeRequest(req.body)) {
|
|
27
28
|
// New initialization request
|
|
@@ -30,13 +31,13 @@ export function createStatefulServer(createMcpServer) {
|
|
|
30
31
|
sessionIdGenerator: () => newSessionId,
|
|
31
32
|
onsessioninitialized: (sessionId) => {
|
|
32
33
|
// Store the transport by session ID
|
|
33
|
-
|
|
34
|
+
sessionStore.set(sessionId, transport);
|
|
34
35
|
},
|
|
35
36
|
});
|
|
36
37
|
// Clean up transport when closed
|
|
37
38
|
transport.onclose = () => {
|
|
38
39
|
if (transport.sessionId) {
|
|
39
|
-
delete
|
|
40
|
+
sessionStore.delete?.(transport.sessionId);
|
|
40
41
|
}
|
|
41
42
|
};
|
|
42
43
|
let config;
|
|
@@ -81,7 +82,7 @@ export function createStatefulServer(createMcpServer) {
|
|
|
81
82
|
jsonrpc: "2.0",
|
|
82
83
|
error: {
|
|
83
84
|
code: -32000,
|
|
84
|
-
message: "Bad Request: No valid session ID provided",
|
|
85
|
+
message: "Bad Request: No valid session ID provided. Session may have expired.",
|
|
85
86
|
},
|
|
86
87
|
id: null,
|
|
87
88
|
});
|
|
@@ -93,11 +94,12 @@ export function createStatefulServer(createMcpServer) {
|
|
|
93
94
|
// Reusable handler for GET and DELETE requests
|
|
94
95
|
const handleSessionRequest = async (req, res) => {
|
|
95
96
|
const sessionId = req.headers["mcp-session-id"];
|
|
96
|
-
if (!sessionId || !
|
|
97
|
-
res.status(400).send("Invalid or
|
|
97
|
+
if (!sessionId || !sessionStore.get(sessionId)) {
|
|
98
|
+
res.status(400).send("Invalid or expired session ID");
|
|
98
99
|
return;
|
|
99
100
|
}
|
|
100
|
-
|
|
101
|
+
// biome-ignore lint/style/noNonNullAssertion: Not possible
|
|
102
|
+
const transport = sessionStore.get(sessionId);
|
|
101
103
|
await transport.handleRequest(req, res);
|
|
102
104
|
};
|
|
103
105
|
// Handle GET requests for server-to-client notifications via SSE
|
package/dist/server/stateless.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
2
2
|
import express from "express";
|
|
3
|
-
import { parseExpressRequestConfig } from "../config.js";
|
|
3
|
+
import { parseExpressRequestConfig } from "../shared/config.js";
|
|
4
4
|
/**
|
|
5
5
|
* Creates a stateless server for handling MCP requests
|
|
6
6
|
* In stateless mode, each request creates a new server and transport instance
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import type express from "express";
|
|
2
|
+
export interface SmitheryUrlOptions {
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
profile?: string;
|
|
5
|
+
config?: object;
|
|
6
|
+
}
|
|
2
7
|
/**
|
|
3
8
|
* Creates a URL to connect to the Smithery MCP server.
|
|
4
9
|
* @param baseUrl The base URL of the Smithery server
|
|
5
|
-
* @param
|
|
6
|
-
* @param apiKey API key for authentication. Required if using Smithery.
|
|
10
|
+
* @param options Optional configuration object
|
|
7
11
|
* @returns A URL object with properly encoded parameters. Example: https://server.smithery.ai/{namespace}/mcp?config=BASE64_ENCODED_CONFIG&api_key=API_KEY
|
|
8
12
|
*/
|
|
9
|
-
export declare function createSmitheryUrl(baseUrl: string,
|
|
13
|
+
export declare function createSmitheryUrl(baseUrl: string, options?: SmitheryUrlOptions): URL;
|
|
10
14
|
/**
|
|
11
15
|
* Parses the config from an express request by checking the query parameter "config".
|
|
12
16
|
* @param req The express request
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Creates a URL to connect to the Smithery MCP server.
|
|
3
3
|
* @param baseUrl The base URL of the Smithery server
|
|
4
|
-
* @param
|
|
5
|
-
* @param apiKey API key for authentication. Required if using Smithery.
|
|
4
|
+
* @param options Optional configuration object
|
|
6
5
|
* @returns A URL object with properly encoded parameters. Example: https://server.smithery.ai/{namespace}/mcp?config=BASE64_ENCODED_CONFIG&api_key=API_KEY
|
|
7
6
|
*/
|
|
8
|
-
export function createSmitheryUrl(baseUrl,
|
|
7
|
+
export function createSmitheryUrl(baseUrl, options) {
|
|
9
8
|
const url = new URL(`${baseUrl}/mcp`);
|
|
10
|
-
if (config) {
|
|
9
|
+
if (options?.config) {
|
|
11
10
|
const param = typeof window !== "undefined"
|
|
12
|
-
? btoa(JSON.stringify(config))
|
|
13
|
-
: Buffer.from(JSON.stringify(config)).toString("base64");
|
|
11
|
+
? btoa(JSON.stringify(options.config))
|
|
12
|
+
: Buffer.from(JSON.stringify(options.config)).toString("base64");
|
|
14
13
|
url.searchParams.set("config", param);
|
|
15
14
|
}
|
|
16
|
-
if (apiKey) {
|
|
17
|
-
url.searchParams.set("api_key", apiKey);
|
|
15
|
+
if (options?.apiKey) {
|
|
16
|
+
url.searchParams.set("api_key", options.apiKey);
|
|
17
|
+
}
|
|
18
|
+
if (options?.profile) {
|
|
19
|
+
url.searchParams.set("profile", options.profile);
|
|
18
20
|
}
|
|
19
21
|
return url;
|
|
20
22
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Patches a function on an object
|
|
3
|
+
* @param obj
|
|
4
|
+
* @param key
|
|
5
|
+
* @param patcher
|
|
6
|
+
*/
|
|
7
|
+
export declare function patch<T extends {
|
|
8
|
+
[P in K]: (...args: any[]) => any;
|
|
9
|
+
}, K extends keyof T & string>(obj: T, key: K, patcher: (fn: T[K]) => T[K]): void;
|
|
10
|
+
export declare function patch<T extends {
|
|
11
|
+
[P in K]?: (...args: any[]) => any;
|
|
12
|
+
}, K extends keyof T & string>(obj: T, key: K, patcher: (fn?: T[K]) => T[K]): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Patches a function on an object
|
|
3
|
+
* @param obj
|
|
4
|
+
* @param key
|
|
5
|
+
* @param patcher
|
|
6
|
+
*/
|
|
7
|
+
// Unified implementation (not type-checked by callers)
|
|
8
|
+
export function patch(obj, key, patcher) {
|
|
9
|
+
// If the property is actually a function, bind it; otherwise undefined
|
|
10
|
+
const original = typeof obj[key] === "function" ? obj[key].bind(obj) : undefined;
|
|
11
|
+
obj[key] = patcher(original);
|
|
12
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smithery/sdk",
|
|
3
|
-
"version": "1.2
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "SDK to develop with Smithery",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,12 +22,15 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@anthropic-ai/sdk": "^0.32.1",
|
|
24
24
|
"@modelcontextprotocol/sdk": "^1.10.2",
|
|
25
|
+
"ai": "^4.3.15",
|
|
25
26
|
"express": "^5.1.0",
|
|
27
|
+
"json-schema": "^0.4.0",
|
|
26
28
|
"openai": "^4.0.0",
|
|
27
29
|
"uuid": "^11.0.3"
|
|
28
30
|
},
|
|
29
31
|
"devDependencies": {
|
|
30
32
|
"@types/express": "^5.0.1",
|
|
33
|
+
"@types/json-schema": "^7.0.15",
|
|
31
34
|
"@types/node": "^20.0.0",
|
|
32
35
|
"@types/uuid": "^9.0.7",
|
|
33
36
|
"dotenv": "^16.4.7",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|