@nuxtjs/mcp-toolkit 0.3.0 → 0.4.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.
- package/dist/module.json +1 -1
- package/dist/module.mjs +11 -18
- package/dist/runtime/server/mcp/definitions/cache.d.ts +39 -0
- package/dist/runtime/server/mcp/definitions/cache.js +35 -0
- package/dist/runtime/server/mcp/definitions/index.d.ts +2 -0
- package/dist/runtime/server/mcp/definitions/index.js +2 -0
- package/dist/runtime/server/mcp/definitions/resources.d.ts +19 -0
- package/dist/runtime/server/mcp/definitions/resources.js +9 -0
- package/dist/runtime/server/mcp/definitions/results.d.ts +55 -0
- package/dist/runtime/server/mcp/definitions/results.js +13 -0
- package/dist/runtime/server/mcp/definitions/tools.d.ts +4 -27
- package/dist/runtime/server/mcp/definitions/tools.js +3 -25
- package/package.json +1 -1
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { ROUTES } from '../dist/runtime/server/mcp/constants.js';
|
|
|
6
6
|
import { addDevToolsCustomTabs } from '../dist/runtime/server/mcp/devtools/index.js';
|
|
7
7
|
|
|
8
8
|
const name = "@nuxtjs/mcp-toolkit";
|
|
9
|
-
const version = "0.
|
|
9
|
+
const version = "0.4.0";
|
|
10
10
|
|
|
11
11
|
const log = logger.withTag("@nuxtjs/mcp-toolkit");
|
|
12
12
|
const { resolve } = createResolver(import.meta.url);
|
|
@@ -87,24 +87,17 @@ const module$1 = defineNuxtModule({
|
|
|
87
87
|
nuxt.options.nitro.typescript.tsConfig ??= {};
|
|
88
88
|
nuxt.options.nitro.typescript.tsConfig.include ??= [];
|
|
89
89
|
nuxt.options.nitro.typescript.tsConfig.include.push(resolver.resolve("runtime/server/types.server.d.ts"));
|
|
90
|
+
const mcpDefinitionsPath = resolver.resolve("runtime/server/mcp/definitions");
|
|
90
91
|
addServerImports([
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
name: "defineMcpPrompt",
|
|
101
|
-
from: resolver.resolve("runtime/server/mcp/definitions")
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
name: "defineMcpHandler",
|
|
105
|
-
from: resolver.resolve("runtime/server/mcp/definitions")
|
|
106
|
-
}
|
|
107
|
-
]);
|
|
92
|
+
"defineMcpTool",
|
|
93
|
+
"defineMcpResource",
|
|
94
|
+
"defineMcpPrompt",
|
|
95
|
+
"defineMcpHandler",
|
|
96
|
+
"textResult",
|
|
97
|
+
"jsonResult",
|
|
98
|
+
"errorResult",
|
|
99
|
+
"imageResult"
|
|
100
|
+
].map((name2) => ({ name: name2, from: mcpDefinitionsPath })));
|
|
108
101
|
addServerHandler({
|
|
109
102
|
route: options.route,
|
|
110
103
|
handler: resolver.resolve("runtime/server/mcp/handler")
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache duration strings supported by the `ms` package
|
|
3
|
+
*/
|
|
4
|
+
export type MsCacheDuration = '1s' | '5s' | '10s' | '15s' | '30s' | '45s' | '1m' | '2m' | '5m' | '10m' | '15m' | '30m' | '45m' | '1h' | '2h' | '3h' | '4h' | '6h' | '8h' | '12h' | '24h' | '1d' | '2d' | '3d' | '7d' | '14d' | '30d' | '1w' | '2w' | '4w' | '1 second' | '1 minute' | '1 hour' | '1 day' | '1 week' | '2 seconds' | '5 seconds' | '10 seconds' | '30 seconds' | '2 minutes' | '5 minutes' | '10 minutes' | '15 minutes' | '30 minutes' | '2 hours' | '3 hours' | '6 hours' | '12 hours' | '24 hours' | '2 days' | '3 days' | '7 days' | '14 days' | '30 days' | '2 weeks' | '4 weeks' | (string & Record<never, never>);
|
|
5
|
+
/**
|
|
6
|
+
* Base cache options using Nitro's caching system
|
|
7
|
+
* @see https://nitro.build/guide/cache#options
|
|
8
|
+
*/
|
|
9
|
+
export interface McpCacheOptions<Args = unknown> {
|
|
10
|
+
/** Cache duration as string (e.g. '1h') or milliseconds (required) */
|
|
11
|
+
maxAge: MsCacheDuration | number;
|
|
12
|
+
/** Duration for stale-while-revalidate */
|
|
13
|
+
staleMaxAge?: number;
|
|
14
|
+
/** Cache name (auto-generated by default) */
|
|
15
|
+
name?: string;
|
|
16
|
+
/** Function to generate cache key */
|
|
17
|
+
getKey?: (args: Args) => string;
|
|
18
|
+
/** Cache group (default: 'mcp') */
|
|
19
|
+
group?: string;
|
|
20
|
+
/** Enable stale-while-revalidate behavior */
|
|
21
|
+
swr?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Cache configuration: string duration, milliseconds, or full options
|
|
25
|
+
* @see https://nitro.build/guide/cache#options
|
|
26
|
+
*/
|
|
27
|
+
export type McpCache<Args = unknown> = MsCacheDuration | number | McpCacheOptions<Args>;
|
|
28
|
+
/**
|
|
29
|
+
* Parse cache duration to milliseconds
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseCacheDuration(duration: MsCacheDuration | number): number;
|
|
32
|
+
/**
|
|
33
|
+
* Create cache options from McpCache config
|
|
34
|
+
*/
|
|
35
|
+
export declare function createCacheOptions<Args>(cache: McpCache<Args>, name: string, defaultGetKey?: (args: Args) => string): Record<string, unknown>;
|
|
36
|
+
/**
|
|
37
|
+
* Wrap a function with caching
|
|
38
|
+
*/
|
|
39
|
+
export declare function wrapWithCache<T extends (...args: unknown[]) => unknown>(fn: T, cacheOptions: Record<string, unknown>): T;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { defineCachedFunction } from "nitropack/runtime";
|
|
2
|
+
import ms from "ms";
|
|
3
|
+
export function parseCacheDuration(duration) {
|
|
4
|
+
if (typeof duration === "number") {
|
|
5
|
+
return duration;
|
|
6
|
+
}
|
|
7
|
+
const parsed = ms(duration);
|
|
8
|
+
if (parsed === void 0) {
|
|
9
|
+
throw new Error(`Invalid cache duration: ${duration}`);
|
|
10
|
+
}
|
|
11
|
+
return parsed;
|
|
12
|
+
}
|
|
13
|
+
export function createCacheOptions(cache, name, defaultGetKey) {
|
|
14
|
+
if (typeof cache === "object") {
|
|
15
|
+
return {
|
|
16
|
+
getKey: defaultGetKey,
|
|
17
|
+
...cache,
|
|
18
|
+
maxAge: parseCacheDuration(cache.maxAge),
|
|
19
|
+
name: cache.name ?? name,
|
|
20
|
+
group: cache.group ?? "mcp"
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
maxAge: parseCacheDuration(cache),
|
|
25
|
+
name,
|
|
26
|
+
group: "mcp",
|
|
27
|
+
getKey: defaultGetKey
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function wrapWithCache(fn, cacheOptions) {
|
|
31
|
+
return defineCachedFunction(
|
|
32
|
+
fn,
|
|
33
|
+
cacheOptions
|
|
34
|
+
);
|
|
35
|
+
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { McpServer, ResourceTemplate, ReadResourceCallback, ReadResourceTemplateCallback, ResourceMetadata } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { type McpCacheOptions, type McpCache } from './cache.js';
|
|
3
|
+
export type McpResourceCacheOptions = McpCacheOptions<URL>;
|
|
4
|
+
export type McpResourceCache = McpCache<URL>;
|
|
2
5
|
/**
|
|
3
6
|
* Annotations for a resource
|
|
4
7
|
* @see https://modelcontextprotocol.io/specification/2025-06-18/server/resources#annotations
|
|
@@ -23,6 +26,14 @@ export interface StandardMcpResourceDefinition {
|
|
|
23
26
|
_meta?: Record<string, unknown>;
|
|
24
27
|
handler: ReadResourceCallback | ReadResourceTemplateCallback;
|
|
25
28
|
file?: never;
|
|
29
|
+
/**
|
|
30
|
+
* Cache configuration for the resource response
|
|
31
|
+
* - string: Duration parsed by `ms` (e.g., '1h', '2 days', '30m')
|
|
32
|
+
* - number: Duration in milliseconds
|
|
33
|
+
* - object: Full cache options with getKey, group, swr, etc.
|
|
34
|
+
* @see https://nitro.build/guide/cache#options
|
|
35
|
+
*/
|
|
36
|
+
cache?: McpResourceCache;
|
|
26
37
|
}
|
|
27
38
|
/**
|
|
28
39
|
* Definition of a file-based MCP resource
|
|
@@ -42,6 +53,14 @@ export interface FileMcpResourceDefinition {
|
|
|
42
53
|
* Relative to the project root
|
|
43
54
|
*/
|
|
44
55
|
file: string;
|
|
56
|
+
/**
|
|
57
|
+
* Cache configuration for the resource response
|
|
58
|
+
* - string: Duration parsed by `ms` (e.g., '1h', '2 days', '30m')
|
|
59
|
+
* - number: Duration in milliseconds
|
|
60
|
+
* - object: Full cache options with getKey, group, swr, etc.
|
|
61
|
+
* @see https://nitro.build/guide/cache#options
|
|
62
|
+
*/
|
|
63
|
+
cache?: McpResourceCache;
|
|
45
64
|
}
|
|
46
65
|
/**
|
|
47
66
|
* Definition of an MCP resource matching the SDK's registerResource signature
|
|
@@ -2,6 +2,7 @@ import { readFile } from "node:fs/promises";
|
|
|
2
2
|
import { resolve, extname } from "node:path";
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import { enrichNameTitle } from "./utils.js";
|
|
5
|
+
import { createCacheOptions, wrapWithCache } from "./cache.js";
|
|
5
6
|
function getMimeType(filePath) {
|
|
6
7
|
const ext = extname(filePath).toLowerCase();
|
|
7
8
|
switch (ext) {
|
|
@@ -74,6 +75,14 @@ export function registerResourceFromDefinition(server, resource) {
|
|
|
74
75
|
if (!handler) {
|
|
75
76
|
throw new Error(`Resource ${name} is missing a handler`);
|
|
76
77
|
}
|
|
78
|
+
if (resource.cache !== void 0) {
|
|
79
|
+
const defaultGetKey = (requestUri) => requestUri.pathname.replace(/\//g, "-").replace(/^-/, "");
|
|
80
|
+
const cacheOptions = createCacheOptions(resource.cache, `mcp-resource:${name}`, defaultGetKey);
|
|
81
|
+
handler = wrapWithCache(
|
|
82
|
+
handler,
|
|
83
|
+
cacheOptions
|
|
84
|
+
);
|
|
85
|
+
}
|
|
77
86
|
if (typeof uri === "string") {
|
|
78
87
|
return server.registerResource(
|
|
79
88
|
name,
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Create a text result for an MCP tool response.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* export default defineMcpTool({
|
|
8
|
+
* handler: async () => textResult('Hello world')
|
|
9
|
+
* })
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export declare function textResult(text: string): CallToolResult;
|
|
13
|
+
/**
|
|
14
|
+
* Create a JSON result for an MCP tool response.
|
|
15
|
+
* Automatically stringifies the data.
|
|
16
|
+
*
|
|
17
|
+
* @param data - The data to serialize as JSON
|
|
18
|
+
* @param pretty - Whether to pretty-print the JSON (default: true)
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* export default defineMcpTool({
|
|
23
|
+
* handler: async () => jsonResult({ foo: 'bar', count: 42 })
|
|
24
|
+
* })
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function jsonResult(data: unknown, pretty?: boolean): CallToolResult;
|
|
28
|
+
/**
|
|
29
|
+
* Create an error result for an MCP tool response.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* export default defineMcpTool({
|
|
34
|
+
* handler: async () => {
|
|
35
|
+
* if (!found) return errorResult('Resource not found')
|
|
36
|
+
* return textResult('Success')
|
|
37
|
+
* }
|
|
38
|
+
* })
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function errorResult(message: string): CallToolResult;
|
|
42
|
+
/**
|
|
43
|
+
* Create an image result for an MCP tool response.
|
|
44
|
+
*
|
|
45
|
+
* @param data - Base64-encoded image data
|
|
46
|
+
* @param mimeType - The MIME type of the image (e.g., 'image/png', 'image/jpeg')
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* export default defineMcpTool({
|
|
51
|
+
* handler: async () => imageResult(base64Data, 'image/png')
|
|
52
|
+
* })
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function imageResult(data: string, mimeType: string): CallToolResult;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function textResult(text) {
|
|
2
|
+
return { content: [{ type: "text", text }] };
|
|
3
|
+
}
|
|
4
|
+
export function jsonResult(data, pretty = true) {
|
|
5
|
+
const text = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
|
|
6
|
+
return { content: [{ type: "text", text }] };
|
|
7
|
+
}
|
|
8
|
+
export function errorResult(message) {
|
|
9
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
10
|
+
}
|
|
11
|
+
export function imageResult(data, mimeType) {
|
|
12
|
+
return { content: [{ type: "image", data, mimeType }] };
|
|
13
|
+
}
|
|
@@ -3,33 +3,10 @@ import type { CallToolResult, ServerRequest, ServerNotification, ToolAnnotations
|
|
|
3
3
|
import type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';
|
|
4
4
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
5
|
import type { ShapeOutput } from '@modelcontextprotocol/sdk/server/zod-compat.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export type
|
|
10
|
-
/**
|
|
11
|
-
* Cache options for MCP tools using Nitro's caching system
|
|
12
|
-
* @see https://nitro.build/guide/cache#options
|
|
13
|
-
*/
|
|
14
|
-
export interface McpToolCacheOptions<Args = unknown> {
|
|
15
|
-
/** Cache duration as string (e.g. '1h') or milliseconds (required) */
|
|
16
|
-
maxAge: MsCacheDuration | number;
|
|
17
|
-
/** Duration for stale-while-revalidate */
|
|
18
|
-
staleMaxAge?: number;
|
|
19
|
-
/** Cache name (auto-generated from tool name by default) */
|
|
20
|
-
name?: string;
|
|
21
|
-
/** Function to generate cache key from arguments */
|
|
22
|
-
getKey?: (args: Args) => string;
|
|
23
|
-
/** Cache group (default: 'mcp') */
|
|
24
|
-
group?: string;
|
|
25
|
-
/** Enable stale-while-revalidate behavior */
|
|
26
|
-
swr?: boolean;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Cache configuration: string duration, milliseconds, or full options
|
|
30
|
-
* @see https://nitro.build/guide/cache#options
|
|
31
|
-
*/
|
|
32
|
-
export type McpToolCache<Args = unknown> = MsCacheDuration | number | McpToolCacheOptions<Args>;
|
|
6
|
+
import { type MsCacheDuration, type McpCacheOptions, type McpCache } from './cache.js';
|
|
7
|
+
export type { MsCacheDuration };
|
|
8
|
+
export type McpToolCacheOptions<Args = unknown> = McpCacheOptions<Args>;
|
|
9
|
+
export type McpToolCache<Args = unknown> = McpCache<Args>;
|
|
33
10
|
/**
|
|
34
11
|
* Handler callback type for MCP tools
|
|
35
12
|
*/
|
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
import { defineCachedFunction } from "nitropack/runtime";
|
|
2
1
|
import { enrichNameTitle } from "./utils.js";
|
|
3
|
-
import
|
|
4
|
-
function parseCacheDuration(duration) {
|
|
5
|
-
if (typeof duration === "number") {
|
|
6
|
-
return duration;
|
|
7
|
-
}
|
|
8
|
-
const parsed = ms(duration);
|
|
9
|
-
if (parsed === void 0) {
|
|
10
|
-
throw new Error(`Invalid cache duration: ${duration}`);
|
|
11
|
-
}
|
|
12
|
-
return parsed;
|
|
13
|
-
}
|
|
2
|
+
import { createCacheOptions, wrapWithCache } from "./cache.js";
|
|
14
3
|
export function registerToolFromDefinition(server, tool) {
|
|
15
4
|
const { name, title } = enrichNameTitle({
|
|
16
5
|
name: tool.name,
|
|
@@ -24,19 +13,8 @@ export function registerToolFromDefinition(server, tool) {
|
|
|
24
13
|
const values = Object.values(args);
|
|
25
14
|
return values.map((v) => String(v).replace(/\//g, "-").replace(/^-/, "")).join(":");
|
|
26
15
|
} : void 0;
|
|
27
|
-
const cacheOptions =
|
|
28
|
-
|
|
29
|
-
...tool.cache,
|
|
30
|
-
maxAge: parseCacheDuration(tool.cache.maxAge),
|
|
31
|
-
name: tool.cache.name ?? `mcp-tool:${name}`,
|
|
32
|
-
group: tool.cache.group ?? "mcp"
|
|
33
|
-
} : {
|
|
34
|
-
maxAge: parseCacheDuration(tool.cache),
|
|
35
|
-
name: `mcp-tool:${name}`,
|
|
36
|
-
group: "mcp",
|
|
37
|
-
getKey: defaultGetKey
|
|
38
|
-
};
|
|
39
|
-
handler = defineCachedFunction(
|
|
16
|
+
const cacheOptions = createCacheOptions(tool.cache, `mcp-tool:${name}`, defaultGetKey);
|
|
17
|
+
handler = wrapWithCache(
|
|
40
18
|
tool.handler,
|
|
41
19
|
cacheOptions
|
|
42
20
|
);
|
package/package.json
CHANGED