@nuxtjs/mcp-toolkit 0.0.0 → 0.0.1
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/LICENSE +21 -0
- package/README.md +133 -0
- package/dist/module.d.mts +42 -0
- package/dist/module.json +11 -0
- package/dist/module.mjs +116 -0
- package/dist/runtime/server/mcp/config.d.ts +10 -0
- package/dist/runtime/server/mcp/config.js +12 -0
- package/dist/runtime/server/mcp/constants.d.ts +22 -0
- package/dist/runtime/server/mcp/constants.js +10 -0
- package/dist/runtime/server/mcp/definitions/handlers.d.ts +18 -0
- package/dist/runtime/server/mcp/definitions/handlers.js +3 -0
- package/dist/runtime/server/mcp/definitions/index.d.ts +4 -0
- package/dist/runtime/server/mcp/definitions/index.js +4 -0
- package/dist/runtime/server/mcp/definitions/prompts.d.ts +79 -0
- package/dist/runtime/server/mcp/definitions/prompts.js +32 -0
- package/dist/runtime/server/mcp/definitions/resources.d.ts +130 -0
- package/dist/runtime/server/mcp/definitions/resources.js +94 -0
- package/dist/runtime/server/mcp/definitions/tools.d.ts +64 -0
- package/dist/runtime/server/mcp/definitions/tools.js +38 -0
- package/dist/runtime/server/mcp/definitions/utils.d.ts +14 -0
- package/dist/runtime/server/mcp/definitions/utils.js +23 -0
- package/dist/runtime/server/mcp/devtools/index.d.ts +3 -0
- package/dist/runtime/server/mcp/devtools/index.js +342 -0
- package/dist/runtime/server/mcp/handler.d.ts +2 -0
- package/dist/runtime/server/mcp/handler.js +37 -0
- package/dist/runtime/server/mcp/loaders/index.d.ts +28 -0
- package/dist/runtime/server/mcp/loaders/index.js +119 -0
- package/dist/runtime/server/mcp/loaders/utils.d.ts +13 -0
- package/dist/runtime/server/mcp/loaders/utils.js +139 -0
- package/dist/runtime/server/mcp/utils.d.ts +18 -0
- package/dist/runtime/server/mcp/utils.js +42 -0
- package/dist/runtime/server/mcp/validators/index.d.ts +4 -0
- package/dist/runtime/server/mcp/validators/index.js +3 -0
- package/dist/runtime/server/mcp/validators/prompts.d.ts +14 -0
- package/dist/runtime/server/mcp/validators/prompts.js +36 -0
- package/dist/runtime/server/mcp/validators/resources.d.ts +14 -0
- package/dist/runtime/server/mcp/validators/resources.js +43 -0
- package/dist/runtime/server/mcp/validators/tools.d.ts +14 -0
- package/dist/runtime/server/mcp/validators/tools.js +47 -0
- package/dist/runtime/server/types/hooks.d.ts +16 -0
- package/dist/runtime/server/types/index.d.ts +1 -0
- package/dist/runtime/server/types/index.js +1 -0
- package/dist/runtime/server/types.server.d.ts +14 -0
- package/dist/types.d.mts +5 -0
- package/package.json +74 -2
- /package/dist/{.gitkeep → runtime/server/types/hooks.js} +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Vercel
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
# Nuxt MCP Toolkit
|
|
4
|
+
|
|
5
|
+
<!-- automd:badges color="black" license name="@nuxtjs/mcp-toolkit" -->
|
|
6
|
+
|
|
7
|
+
[](https://npmjs.com/package/@nuxtjs/mcp-toolkit)
|
|
8
|
+
[](https://npm.chart.dev/@nuxtjs/mcp-toolkit)
|
|
9
|
+
[](https://github.com/nuxt-modules/mcp-toolkit/blob/main/LICENSE)
|
|
10
|
+
|
|
11
|
+
<!-- /automd -->
|
|
12
|
+
|
|
13
|
+
A Nuxt module to easily create a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server directly in your Nuxt application. Define MCP tools, resources, and prompts with zero configuration - just create files and they're automatically discovered and registered.
|
|
14
|
+
|
|
15
|
+
## ✨ Features
|
|
16
|
+
|
|
17
|
+
<!-- automd:file src="../../.github/snippets/features.md" -->
|
|
18
|
+
|
|
19
|
+
- 🎯 **Zero Configuration** - Automatic discovery of tools, resources, and prompts
|
|
20
|
+
- 📦 **File-based** - Organize definitions in intuitive directory structures
|
|
21
|
+
- 🚀 **Multiple Handlers** - Create multiple MCP endpoints in a single app
|
|
22
|
+
- 🔍 **Built-in Inspector** - Visual debugging tool in Nuxt DevTools
|
|
23
|
+
- 📝 **TypeScript First** - Full type safety with auto-imports
|
|
24
|
+
- 🔒 **Zod Validation** - Built-in input/output validation
|
|
25
|
+
|
|
26
|
+
<!-- /automd -->
|
|
27
|
+
|
|
28
|
+
## 🚀 Installation
|
|
29
|
+
|
|
30
|
+
<!-- automd:file src="../../.github/snippets/installation.md" -->
|
|
31
|
+
|
|
32
|
+
Use `nuxt` to install the module automatically:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx nuxt module add mcp-toolkit
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Or install manually:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# npm
|
|
42
|
+
npm install -D @nuxtjs/mcp-toolkit zod@^3
|
|
43
|
+
|
|
44
|
+
# yarn
|
|
45
|
+
yarn add -D @nuxtjs/mcp-toolkit zod@^3
|
|
46
|
+
|
|
47
|
+
# pnpm
|
|
48
|
+
pnpm add -D @nuxtjs/mcp-toolkit zod@^3
|
|
49
|
+
|
|
50
|
+
# bun
|
|
51
|
+
bun add -D @nuxtjs/mcp-toolkit zod@^3
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
> **Note:** Zod v3 is required. Zod v4 is not yet compatible with the MCP SDK.
|
|
55
|
+
|
|
56
|
+
<!-- /automd -->
|
|
57
|
+
|
|
58
|
+
## 📖 Quick Start
|
|
59
|
+
|
|
60
|
+
Add the module to your `nuxt.config.ts`:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
export default defineNuxtConfig({
|
|
64
|
+
modules: ['@nuxtjs/mcp-toolkit'],
|
|
65
|
+
mcp: {
|
|
66
|
+
name: 'My MCP Server',
|
|
67
|
+
version: '1.0.0',
|
|
68
|
+
},
|
|
69
|
+
})
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Create your first tool in `server/mcp/tools/echo.ts`:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { z } from 'zod'
|
|
76
|
+
|
|
77
|
+
export default defineMcpTool({
|
|
78
|
+
description: 'Echo back a message',
|
|
79
|
+
inputSchema: {
|
|
80
|
+
message: z.string().describe('The message to echo back'),
|
|
81
|
+
},
|
|
82
|
+
handler: async ({ message }) => {
|
|
83
|
+
return {
|
|
84
|
+
content: [{
|
|
85
|
+
type: 'text',
|
|
86
|
+
text: `Echo: ${message}`,
|
|
87
|
+
}],
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
})
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The tool will be automatically discovered and registered. No imports needed - all helpers are auto-imported!
|
|
94
|
+
|
|
95
|
+
## 📚 Documentation
|
|
96
|
+
|
|
97
|
+
📖 **[Full Documentation →](https://mcp-toolkit.nuxt.dev)**
|
|
98
|
+
|
|
99
|
+
## 🤝 Contributing
|
|
100
|
+
|
|
101
|
+
<!-- automd:file src="../../.github/snippets/contributing.md" -->
|
|
102
|
+
|
|
103
|
+
Contributions are welcome! Feel free to open an issue or submit a pull request.
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Install dependencies
|
|
107
|
+
pnpm install
|
|
108
|
+
|
|
109
|
+
# Generate type stubs
|
|
110
|
+
pnpm run dev:prepare
|
|
111
|
+
|
|
112
|
+
# Start the playground
|
|
113
|
+
pnpm run dev
|
|
114
|
+
|
|
115
|
+
# Run tests
|
|
116
|
+
pnpm run test
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
<!-- /automd -->
|
|
120
|
+
|
|
121
|
+
## 📄 License
|
|
122
|
+
|
|
123
|
+
<!-- automd:file src="../../.github/snippets/license.md" -->
|
|
124
|
+
|
|
125
|
+
Published under the [MIT](https://github.com/nuxt-modules/mcp-toolkit/blob/main/LICENSE) license.
|
|
126
|
+
|
|
127
|
+
Made by [@HugoRCD](https://github.com/HugoRCD) and [community](https://github.com/nuxt-modules/mcp-toolkit/graphs/contributors) 💛
|
|
128
|
+
|
|
129
|
+
<a href="https://github.com/nuxt-modules/mcp-toolkit/graphs/contributors">
|
|
130
|
+
<img src="https://contrib.rocks/image?repo=nuxt-modules/mcp-toolkit" />
|
|
131
|
+
</a>
|
|
132
|
+
|
|
133
|
+
<!-- /automd -->
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
+
export * from '../dist/runtime/server/types/index.js';
|
|
3
|
+
|
|
4
|
+
declare const resolve: (...path: string[]) => string;
|
|
5
|
+
|
|
6
|
+
interface ModuleOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Enable or disable the MCP server
|
|
9
|
+
* @default true
|
|
10
|
+
*/
|
|
11
|
+
enabled?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* The route path for the MCP server endpoint
|
|
14
|
+
* @default '/mcp'
|
|
15
|
+
*/
|
|
16
|
+
route?: string;
|
|
17
|
+
/**
|
|
18
|
+
* URL to redirect to when a browser accesses the MCP endpoint
|
|
19
|
+
* @default '/'
|
|
20
|
+
*/
|
|
21
|
+
browserRedirect?: string;
|
|
22
|
+
/**
|
|
23
|
+
* The name of the MCP server
|
|
24
|
+
* @default Site name from site config or 'Docus Documentation'
|
|
25
|
+
*/
|
|
26
|
+
name?: string;
|
|
27
|
+
/**
|
|
28
|
+
* The version of the MCP server
|
|
29
|
+
* @default '1.0.0'
|
|
30
|
+
*/
|
|
31
|
+
version?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Base directory for MCP definitions relative to server directory
|
|
34
|
+
* The module will look for tools, resources, and prompts in subdirectories
|
|
35
|
+
* @default 'mcp'
|
|
36
|
+
*/
|
|
37
|
+
dir?: string;
|
|
38
|
+
}
|
|
39
|
+
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
40
|
+
|
|
41
|
+
export { _default as default, resolve };
|
|
42
|
+
export type { ModuleOptions };
|
package/dist/module.json
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nuxtjs/mcp-toolkit",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"configKey": "mcp",
|
|
5
|
+
"docs": "https://mcp-toolkit.nuxt.dev/getting-started/installation",
|
|
6
|
+
"mcp": "https://mcp-toolkit.nuxt.dev/mcp",
|
|
7
|
+
"builder": {
|
|
8
|
+
"@nuxt/module-builder": "1.0.2",
|
|
9
|
+
"unbuild": "3.6.1"
|
|
10
|
+
}
|
|
11
|
+
}
|
package/dist/module.mjs
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { logger, createResolver, defineNuxtModule, addServerHandler, addServerImports } from '@nuxt/kit';
|
|
2
|
+
import { defu } from 'defu';
|
|
3
|
+
import { loadAllDefinitions } from '../dist/runtime/server/mcp/loaders/index.js';
|
|
4
|
+
import { defaultMcpConfig } from '../dist/runtime/server/mcp/config.js';
|
|
5
|
+
import { ROUTES } from '../dist/runtime/server/mcp/constants.js';
|
|
6
|
+
import { addDevToolsCustomTabs } from '../dist/runtime/server/mcp/devtools/index.js';
|
|
7
|
+
|
|
8
|
+
const name = "@nuxtjs/mcp-toolkit";
|
|
9
|
+
const version = "0.0.1";
|
|
10
|
+
|
|
11
|
+
const log = logger.withTag("@nuxtjs/mcp-toolkit");
|
|
12
|
+
const { resolve } = createResolver(import.meta.url);
|
|
13
|
+
const module$1 = defineNuxtModule({
|
|
14
|
+
meta: {
|
|
15
|
+
name,
|
|
16
|
+
version,
|
|
17
|
+
configKey: "mcp",
|
|
18
|
+
docs: "https://mcp-toolkit.nuxt.dev/getting-started/installation",
|
|
19
|
+
mcp: "https://mcp-toolkit.nuxt.dev/mcp"
|
|
20
|
+
},
|
|
21
|
+
defaults: defaultMcpConfig,
|
|
22
|
+
async setup(options, nuxt) {
|
|
23
|
+
const resolver = createResolver(import.meta.url);
|
|
24
|
+
nuxt.options.runtimeConfig.mcp = defu(
|
|
25
|
+
nuxt.options.runtimeConfig.mcp,
|
|
26
|
+
{
|
|
27
|
+
enabled: options.enabled,
|
|
28
|
+
route: options.route,
|
|
29
|
+
browserRedirect: options.browserRedirect,
|
|
30
|
+
name: options.name,
|
|
31
|
+
version: options.version,
|
|
32
|
+
dir: options.dir
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
if (!options.enabled) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const mcpDir = options.dir ?? defaultMcpConfig.dir;
|
|
39
|
+
const paths = {
|
|
40
|
+
tools: [`${mcpDir}/tools`],
|
|
41
|
+
resources: [`${mcpDir}/resources`],
|
|
42
|
+
prompts: [`${mcpDir}/prompts`],
|
|
43
|
+
handlers: [mcpDir]
|
|
44
|
+
};
|
|
45
|
+
nuxt.hook("modules:done", async () => {
|
|
46
|
+
try {
|
|
47
|
+
await nuxt.callHook("mcp:definitions:paths", paths);
|
|
48
|
+
const result = await loadAllDefinitions(paths);
|
|
49
|
+
if (result.handlers && result.handlers.count > 0) {
|
|
50
|
+
addServerHandler({
|
|
51
|
+
route: ROUTES.CUSTOM_HANDLER,
|
|
52
|
+
handler: resolver.resolve("runtime/server/mcp/handler")
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (result.total === 0) {
|
|
56
|
+
log.warn("No MCP definitions found. Create tools, resources, or prompts in server/mcp/");
|
|
57
|
+
} else {
|
|
58
|
+
const summary = [];
|
|
59
|
+
if (result.tools.count > 0) summary.push(`${result.tools.count} tool${result.tools.count > 1 ? "s" : ""}`);
|
|
60
|
+
if (result.resources.count > 0) summary.push(`${result.resources.count} resource${result.resources.count > 1 ? "s" : ""}`);
|
|
61
|
+
if (result.prompts.count > 0) summary.push(`${result.prompts.count} prompt${result.prompts.count > 1 ? "s" : ""}`);
|
|
62
|
+
if (result.handlers.count > 0) summary.push(`${result.handlers.count} handler${result.handlers.count > 1 ? "s" : ""}`);
|
|
63
|
+
const boxContent = [];
|
|
64
|
+
if (options.name) {
|
|
65
|
+
boxContent.push(`${options.name}`);
|
|
66
|
+
}
|
|
67
|
+
boxContent.push(`Route: ${options.route}`);
|
|
68
|
+
boxContent.push(`Definitions: ${summary.join(", ")}`);
|
|
69
|
+
log.box({
|
|
70
|
+
title: "MCP Server",
|
|
71
|
+
message: boxContent.join("\n")
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
} catch (error) {
|
|
75
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
76
|
+
log.error("Failed to initialize MCP server");
|
|
77
|
+
log.error(`Error: ${errorMessage}`);
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
nuxt.hook("prepare:types", ({ references }) => {
|
|
82
|
+
references.push({
|
|
83
|
+
path: resolver.resolve("runtime/server/types.server.d.ts")
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
nuxt.options.nitro.typescript ??= {};
|
|
87
|
+
nuxt.options.nitro.typescript.tsConfig ??= {};
|
|
88
|
+
nuxt.options.nitro.typescript.tsConfig.include ??= [];
|
|
89
|
+
nuxt.options.nitro.typescript.tsConfig.include.push(resolver.resolve("runtime/server/types.server.d.ts"));
|
|
90
|
+
addServerImports([
|
|
91
|
+
{
|
|
92
|
+
name: "defineMcpTool",
|
|
93
|
+
from: resolver.resolve("runtime/server/mcp/definitions")
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: "defineMcpResource",
|
|
97
|
+
from: resolver.resolve("runtime/server/mcp/definitions")
|
|
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
|
+
]);
|
|
108
|
+
addServerHandler({
|
|
109
|
+
route: options.route,
|
|
110
|
+
handler: resolver.resolve("runtime/server/mcp/handler")
|
|
111
|
+
});
|
|
112
|
+
addDevToolsCustomTabs(nuxt, options);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
export { module$1 as default, resolve };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface McpConfig {
|
|
2
|
+
enabled: boolean;
|
|
3
|
+
route: string;
|
|
4
|
+
browserRedirect: string;
|
|
5
|
+
name: string;
|
|
6
|
+
version: string;
|
|
7
|
+
dir: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const defaultMcpConfig: McpConfig;
|
|
10
|
+
export declare function getMcpConfig(partial?: Partial<McpConfig>): McpConfig;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { defu } from "defu";
|
|
2
|
+
export const defaultMcpConfig = {
|
|
3
|
+
enabled: true,
|
|
4
|
+
route: "/mcp",
|
|
5
|
+
browserRedirect: "/",
|
|
6
|
+
name: "",
|
|
7
|
+
version: "1.0.0",
|
|
8
|
+
dir: "mcp"
|
|
9
|
+
};
|
|
10
|
+
export function getMcpConfig(partial) {
|
|
11
|
+
return defu(partial, defaultMcpConfig);
|
|
12
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants used throughout the MCP module
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Default route paths for MCP endpoints
|
|
6
|
+
*/
|
|
7
|
+
export declare const ROUTES: {
|
|
8
|
+
readonly DEFAULT: "/mcp";
|
|
9
|
+
readonly CUSTOM_HANDLER: "/mcp/:handler";
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Subdirectory names for MCP definitions
|
|
13
|
+
*/
|
|
14
|
+
export declare const SUBDIRECTORIES: {
|
|
15
|
+
readonly TOOLS: "tools";
|
|
16
|
+
readonly RESOURCES: "resources";
|
|
17
|
+
readonly PROMPTS: "prompts";
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Supported file extensions for MCP definition files
|
|
21
|
+
*/
|
|
22
|
+
export declare const FILE_EXTENSIONS: readonly ["ts", "js", "mts", "mjs"];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { McpToolDefinition } from './tools.js';
|
|
2
|
+
import type { McpResourceDefinition } from './resources.js';
|
|
3
|
+
import type { McpPromptDefinition } from './prompts.js';
|
|
4
|
+
export interface McpHandlerOptions {
|
|
5
|
+
name: string;
|
|
6
|
+
version?: string;
|
|
7
|
+
route?: string;
|
|
8
|
+
browserRedirect?: string;
|
|
9
|
+
tools?: Array<McpToolDefinition<any, any>>;
|
|
10
|
+
resources?: McpResourceDefinition[];
|
|
11
|
+
prompts?: McpPromptDefinition[];
|
|
12
|
+
}
|
|
13
|
+
export interface McpHandlerDefinition extends Required<Omit<McpHandlerOptions, 'tools' | 'resources' | 'prompts'>> {
|
|
14
|
+
tools: Array<McpToolDefinition<any, any>>;
|
|
15
|
+
resources: McpResourceDefinition[];
|
|
16
|
+
prompts: McpPromptDefinition[];
|
|
17
|
+
}
|
|
18
|
+
export declare function defineMcpHandler(options: McpHandlerOptions): McpHandlerOptions;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { z, ZodTypeAny, ZodRawShape } from 'zod';
|
|
2
|
+
import type { GetPromptResult, ServerRequest, ServerNotification } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';
|
|
4
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
/**
|
|
6
|
+
* Callback type for MCP prompts, matching the SDK's PromptCallback type
|
|
7
|
+
*/
|
|
8
|
+
export type McpPromptCallback<Args extends ZodRawShape | undefined = undefined> = Args extends ZodRawShape ? (args: z.objectOutputType<Args, ZodTypeAny>, extra: RequestHandlerExtra<ServerRequest, ServerNotification>) => GetPromptResult | Promise<GetPromptResult> : (extra: RequestHandlerExtra<ServerRequest, ServerNotification>) => GetPromptResult | Promise<GetPromptResult>;
|
|
9
|
+
/**
|
|
10
|
+
* Definition of an MCP prompt
|
|
11
|
+
* Uses `inputSchema` for consistency with tools, which is mapped to `argsSchema` when registering with the SDK
|
|
12
|
+
*/
|
|
13
|
+
export interface McpPromptDefinition<Args extends ZodRawShape | undefined = undefined> {
|
|
14
|
+
name?: string;
|
|
15
|
+
title?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
inputSchema?: Args;
|
|
18
|
+
_meta?: Record<string, unknown>;
|
|
19
|
+
handler: McpPromptCallback<Args>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Helper function to register a prompt from a McpPromptDefinition
|
|
23
|
+
*/
|
|
24
|
+
export declare function registerPromptFromDefinition<Args extends ZodRawShape | undefined = undefined>(server: McpServer, prompt: McpPromptDefinition<Args>): import("@modelcontextprotocol/sdk/server/mcp.js").RegisteredPrompt;
|
|
25
|
+
/**
|
|
26
|
+
* Define an MCP prompt that will be automatically registered
|
|
27
|
+
*
|
|
28
|
+
* If `name` or `title` are not provided, they will be automatically generated from the filename
|
|
29
|
+
* (e.g., `list_documentation.ts` → `name: 'list-documentation'`, `title: 'List Documentation'`).
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* // server/mcp/prompts/my-prompt.ts
|
|
34
|
+
* import { z } from 'zod'
|
|
35
|
+
*
|
|
36
|
+
* export default defineMcpPrompt({
|
|
37
|
+
* name: 'summarize',
|
|
38
|
+
* title: 'Text Summarizer',
|
|
39
|
+
* description: 'Summarize any text using an LLM',
|
|
40
|
+
* inputSchema: {
|
|
41
|
+
* text: z.string().describe('The text to summarize'),
|
|
42
|
+
* maxLength: z.string().optional().describe('Maximum length of summary')
|
|
43
|
+
* },
|
|
44
|
+
* handler: async ({ text, maxLength }) => {
|
|
45
|
+
* const summary = await summarizeText(text, maxLength ? parseInt(maxLength) : undefined)
|
|
46
|
+
* return {
|
|
47
|
+
* messages: [{
|
|
48
|
+
* role: 'user',
|
|
49
|
+
* content: {
|
|
50
|
+
* type: 'text',
|
|
51
|
+
* text: summary
|
|
52
|
+
* }
|
|
53
|
+
* }]
|
|
54
|
+
* }
|
|
55
|
+
* }
|
|
56
|
+
* })
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* // Simple prompt without arguments
|
|
62
|
+
* export default defineMcpPrompt({
|
|
63
|
+
* name: 'greeting',
|
|
64
|
+
* description: 'Generate a greeting message',
|
|
65
|
+
* handler: async () => {
|
|
66
|
+
* return {
|
|
67
|
+
* messages: [{
|
|
68
|
+
* role: 'user',
|
|
69
|
+
* content: {
|
|
70
|
+
* type: 'text',
|
|
71
|
+
* text: 'Hello! How can I help you today?'
|
|
72
|
+
* }
|
|
73
|
+
* }]
|
|
74
|
+
* }
|
|
75
|
+
* }
|
|
76
|
+
* })
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export declare function defineMcpPrompt<const Args extends ZodRawShape | undefined = undefined>(definition: McpPromptDefinition<Args>): McpPromptDefinition<Args>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { enrichNameTitle } from "./utils.js";
|
|
2
|
+
export function registerPromptFromDefinition(server, prompt) {
|
|
3
|
+
const { name, title } = enrichNameTitle({
|
|
4
|
+
name: prompt.name,
|
|
5
|
+
title: prompt.title,
|
|
6
|
+
_meta: prompt._meta,
|
|
7
|
+
type: "prompt"
|
|
8
|
+
});
|
|
9
|
+
if (prompt.inputSchema) {
|
|
10
|
+
return server.registerPrompt(
|
|
11
|
+
name,
|
|
12
|
+
{
|
|
13
|
+
title,
|
|
14
|
+
description: prompt.description,
|
|
15
|
+
argsSchema: prompt.inputSchema
|
|
16
|
+
},
|
|
17
|
+
prompt.handler
|
|
18
|
+
);
|
|
19
|
+
} else {
|
|
20
|
+
return server.registerPrompt(
|
|
21
|
+
name,
|
|
22
|
+
{
|
|
23
|
+
title,
|
|
24
|
+
description: prompt.description
|
|
25
|
+
},
|
|
26
|
+
prompt.handler
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export function defineMcpPrompt(definition) {
|
|
31
|
+
return definition;
|
|
32
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import type { McpServer, ResourceTemplate, ReadResourceCallback, ReadResourceTemplateCallback, ResourceMetadata } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
/**
|
|
3
|
+
* Annotations for a resource
|
|
4
|
+
* @see https://modelcontextprotocol.io/specification/2025-06-18/server/resources#annotations
|
|
5
|
+
*/
|
|
6
|
+
export interface McpResourceAnnotations {
|
|
7
|
+
audience?: ('user' | 'assistant')[];
|
|
8
|
+
priority?: number;
|
|
9
|
+
lastModified?: string;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Definition of a standard MCP resource (with URI and handler)
|
|
14
|
+
*/
|
|
15
|
+
export interface StandardMcpResourceDefinition {
|
|
16
|
+
name?: string;
|
|
17
|
+
title?: string;
|
|
18
|
+
uri: string | ResourceTemplate;
|
|
19
|
+
metadata?: ResourceMetadata & {
|
|
20
|
+
annotations?: McpResourceAnnotations;
|
|
21
|
+
};
|
|
22
|
+
_meta?: Record<string, unknown>;
|
|
23
|
+
handler: ReadResourceCallback | ReadResourceTemplateCallback;
|
|
24
|
+
file?: never;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Definition of a file-based MCP resource
|
|
28
|
+
*/
|
|
29
|
+
export interface FileMcpResourceDefinition {
|
|
30
|
+
name?: string;
|
|
31
|
+
title?: string;
|
|
32
|
+
uri?: string;
|
|
33
|
+
metadata?: ResourceMetadata & {
|
|
34
|
+
annotations?: McpResourceAnnotations;
|
|
35
|
+
};
|
|
36
|
+
_meta?: Record<string, unknown>;
|
|
37
|
+
handler?: ReadResourceCallback;
|
|
38
|
+
/**
|
|
39
|
+
* Path to the local file to serve as a resource
|
|
40
|
+
* Relative to the project root
|
|
41
|
+
*/
|
|
42
|
+
file: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Definition of an MCP resource matching the SDK's registerResource signature
|
|
46
|
+
* Supports both static resources (URI string), dynamic resources (ResourceTemplate),
|
|
47
|
+
* and local file resources.
|
|
48
|
+
*/
|
|
49
|
+
export type McpResourceDefinition = StandardMcpResourceDefinition | FileMcpResourceDefinition;
|
|
50
|
+
/**
|
|
51
|
+
* Helper function to register a resource from a McpResourceDefinition
|
|
52
|
+
*/
|
|
53
|
+
export declare function registerResourceFromDefinition(server: McpServer, resource: McpResourceDefinition): import("@modelcontextprotocol/sdk/server/mcp.js").RegisteredResource | import("@modelcontextprotocol/sdk/server/mcp.js").RegisteredResourceTemplate;
|
|
54
|
+
/**
|
|
55
|
+
* Define an MCP resource that will be automatically registered
|
|
56
|
+
*
|
|
57
|
+
* This function matches the structure of server.registerResource() from the MCP SDK.
|
|
58
|
+
*
|
|
59
|
+
* If `name` or `title` are not provided, they will be automatically generated from the filename
|
|
60
|
+
* (e.g., `list_documentation.ts` → `name: 'list-documentation'`, `title: 'List Documentation'`).
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* // server/mcp/resources/my-resource.ts
|
|
65
|
+
* export default defineMcpResource({
|
|
66
|
+
* name: 'readme',
|
|
67
|
+
* title: 'README',
|
|
68
|
+
* uri: 'file:///project/README.md',
|
|
69
|
+
* metadata: {
|
|
70
|
+
* description: 'Project README file',
|
|
71
|
+
* mimeType: 'text/markdown'
|
|
72
|
+
* },
|
|
73
|
+
* handler: async (uri) => {
|
|
74
|
+
* const content = await readFile(uri.pathname, 'utf-8')
|
|
75
|
+
* return {
|
|
76
|
+
* contents: [{
|
|
77
|
+
* uri: uri.toString(),
|
|
78
|
+
* mimeType: 'text/markdown',
|
|
79
|
+
* text: content
|
|
80
|
+
* }]
|
|
81
|
+
* }
|
|
82
|
+
* }
|
|
83
|
+
* })
|
|
84
|
+
* ```
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* // Simpler file-based resource
|
|
89
|
+
* export default defineMcpResource({
|
|
90
|
+
* name: 'readme',
|
|
91
|
+
* file: 'README.md', // Automatically handles reading file and setting URI
|
|
92
|
+
* metadata: {
|
|
93
|
+
* description: 'Project README file'
|
|
94
|
+
* }
|
|
95
|
+
* })
|
|
96
|
+
* ```
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```ts
|
|
100
|
+
* // Dynamic resource with template
|
|
101
|
+
* import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
102
|
+
*
|
|
103
|
+
* export default defineMcpResource({
|
|
104
|
+
* name: 'file',
|
|
105
|
+
* title: 'File Resource',
|
|
106
|
+
* uri: new ResourceTemplate('file:///project/{+path}', {
|
|
107
|
+
* list: async () => {
|
|
108
|
+
* return {
|
|
109
|
+
* resources: [
|
|
110
|
+
* { uri: 'file:///project/README.md', name: 'README.md' },
|
|
111
|
+
* { uri: 'file:///project/src/index.ts', name: 'index.ts' }
|
|
112
|
+
* ]
|
|
113
|
+
* }
|
|
114
|
+
* }
|
|
115
|
+
* }),
|
|
116
|
+
* handler: async (uri, variables) => {
|
|
117
|
+
* const path = variables.path
|
|
118
|
+
* const content = await readFile(path, 'utf-8')
|
|
119
|
+
* return {
|
|
120
|
+
* contents: [{
|
|
121
|
+
* uri: uri.toString(),
|
|
122
|
+
* mimeType: 'text/plain',
|
|
123
|
+
* text: content
|
|
124
|
+
* }]
|
|
125
|
+
* }
|
|
126
|
+
* }
|
|
127
|
+
* })
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
export declare function defineMcpResource(definition: McpResourceDefinition): McpResourceDefinition;
|