@yh-ui/ai-sdk 0.1.21
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 +309 -0
- package/dist/agent-enhanced.cjs +292 -0
- package/dist/agent-enhanced.d.ts +143 -0
- package/dist/agent-enhanced.mjs +267 -0
- package/dist/cache-adapter.cjs +99 -0
- package/dist/cache-adapter.d.ts +42 -0
- package/dist/cache-adapter.mjs +95 -0
- package/dist/future.cjs +882 -0
- package/dist/future.d.ts +519 -0
- package/dist/future.mjs +765 -0
- package/dist/index.cjs +913 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.mjs +217 -0
- package/dist/langchain.cjs +363 -0
- package/dist/langchain.d.ts +232 -0
- package/dist/langchain.mjs +319 -0
- package/dist/loaders.cjs +110 -0
- package/dist/loaders.d.ts +58 -0
- package/dist/loaders.mjs +76 -0
- package/dist/mcp-server.cjs +265 -0
- package/dist/mcp-server.d.ts +186 -0
- package/dist/mcp-server.mjs +234 -0
- package/dist/mcp.cjs +370 -0
- package/dist/mcp.d.ts +206 -0
- package/dist/mcp.mjs +354 -0
- package/dist/observability.cjs +150 -0
- package/dist/observability.d.ts +112 -0
- package/dist/observability.mjs +117 -0
- package/dist/rag-production.cjs +95 -0
- package/dist/rag-production.d.ts +43 -0
- package/dist/rag-production.mjs +85 -0
- package/dist/rate-limit.cjs +73 -0
- package/dist/rate-limit.d.ts +55 -0
- package/dist/rate-limit.mjs +51 -0
- package/dist/vector-store.cjs +63 -0
- package/dist/vector-store.d.ts +74 -0
- package/dist/vector-store.mjs +55 -0
- package/dist/vue/index.cjs +1023 -0
- package/dist/vue/index.d.ts +627 -0
- package/dist/vue/index.mjs +913 -0
- package/package.json +87 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* YH-UI AI SDK - 文档加载器
|
|
3
|
+
*
|
|
4
|
+
* 支持 Markdown / 纯文本 / 结构化拆分。
|
|
5
|
+
* PDF、DOCX 通过接口预留,可由可选依赖或用户实现。
|
|
6
|
+
*/
|
|
7
|
+
export interface LoadedDocument {
|
|
8
|
+
content: string;
|
|
9
|
+
metadata?: Record<string, unknown>;
|
|
10
|
+
source?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface DocumentLoaderOptions {
|
|
13
|
+
/** 是否按段落/块拆分 */
|
|
14
|
+
split?: boolean;
|
|
15
|
+
/** 块大小(字符数) */
|
|
16
|
+
chunkSize?: number;
|
|
17
|
+
/** 块重叠(字符数) */
|
|
18
|
+
chunkOverlap?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 文本加载器:直接使用字符串
|
|
22
|
+
*/
|
|
23
|
+
export declare function createTextLoader(content: string, metadata?: Record<string, unknown>): LoadedDocument;
|
|
24
|
+
/**
|
|
25
|
+
* Markdown 加载器:按标题或段落拆分
|
|
26
|
+
*/
|
|
27
|
+
export declare function loadMarkdown(markdown: string, options?: DocumentLoaderOptions): LoadedDocument[];
|
|
28
|
+
/**
|
|
29
|
+
* 通用分块:按固定大小拆分,带重叠
|
|
30
|
+
*/
|
|
31
|
+
export declare function chunkText(text: string, options?: {
|
|
32
|
+
chunkSize?: number;
|
|
33
|
+
chunkOverlap?: number;
|
|
34
|
+
}): LoadedDocument[];
|
|
35
|
+
/**
|
|
36
|
+
* PDF 加载器接口(由用户或可选包实现)
|
|
37
|
+
* 可选依赖:pdf-parse / pdfjs-dist 等
|
|
38
|
+
*/
|
|
39
|
+
export type PDFLoader = (input: string | ArrayBuffer | Buffer) => Promise<LoadedDocument[]>;
|
|
40
|
+
/**
|
|
41
|
+
* DOCX 加载器接口(由用户或可选包实现)
|
|
42
|
+
* 可选依赖:mammoth 等
|
|
43
|
+
*/
|
|
44
|
+
export type DOCXLoader = (input: string | ArrayBuffer | Buffer) => Promise<LoadedDocument[]>;
|
|
45
|
+
/**
|
|
46
|
+
* 创建复合加载器:根据扩展名选择策略
|
|
47
|
+
*/
|
|
48
|
+
export declare function createFileLoader(options: {
|
|
49
|
+
pdf?: PDFLoader;
|
|
50
|
+
docx?: DOCXLoader;
|
|
51
|
+
chunkSize?: number;
|
|
52
|
+
chunkOverlap?: number;
|
|
53
|
+
}): {
|
|
54
|
+
loadFromText(content: string): Promise<LoadedDocument[]>;
|
|
55
|
+
loadFromMarkdown(content: string): Promise<LoadedDocument[]>;
|
|
56
|
+
loadFromPDF(input: string | ArrayBuffer | Buffer): Promise<LoadedDocument[]>;
|
|
57
|
+
loadFromDOCX(input: string | ArrayBuffer | Buffer): Promise<LoadedDocument[]>;
|
|
58
|
+
};
|
package/dist/loaders.mjs
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export function createTextLoader(content, metadata) {
|
|
2
|
+
return { content: content.trim(), metadata };
|
|
3
|
+
}
|
|
4
|
+
export function loadMarkdown(markdown, options = {}) {
|
|
5
|
+
const chunkSize = options.chunkSize ?? 1e3;
|
|
6
|
+
const chunkOverlap = Math.min(options.chunkOverlap ?? 200, Math.floor(chunkSize * 0.5));
|
|
7
|
+
const { split = true } = options;
|
|
8
|
+
if (!split) {
|
|
9
|
+
return [{ content: markdown.trim(), metadata: { type: "markdown" } }];
|
|
10
|
+
}
|
|
11
|
+
const blocks = [];
|
|
12
|
+
const lines = markdown.split(/\r?\n/);
|
|
13
|
+
let current = "";
|
|
14
|
+
for (const line of lines) {
|
|
15
|
+
const isHeading = /^#{1,6}\s/.test(line);
|
|
16
|
+
if (isHeading && current.length >= chunkSize) {
|
|
17
|
+
if (current.trim()) blocks.push(current.trim());
|
|
18
|
+
current = line + "\n";
|
|
19
|
+
} else {
|
|
20
|
+
current += line + "\n";
|
|
21
|
+
if (current.length >= chunkSize) {
|
|
22
|
+
if (current.trim()) blocks.push(current.trim());
|
|
23
|
+
current = current.slice(-chunkOverlap);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (current.trim()) blocks.push(current.trim());
|
|
28
|
+
return blocks.map((content, i) => ({
|
|
29
|
+
content,
|
|
30
|
+
metadata: { type: "markdown", index: i }
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
export function chunkText(text, options = {}) {
|
|
34
|
+
const chunkSize = options.chunkSize ?? 800;
|
|
35
|
+
const chunkOverlap = Math.min(options.chunkOverlap ?? 100, Math.floor(chunkSize * 0.5));
|
|
36
|
+
const chunks = [];
|
|
37
|
+
let start = 0;
|
|
38
|
+
while (start < text.length) {
|
|
39
|
+
const end = Math.min(start + chunkSize, text.length);
|
|
40
|
+
let slice = text.slice(start, end);
|
|
41
|
+
if (end < text.length) {
|
|
42
|
+
const lastSpace = slice.lastIndexOf(" ");
|
|
43
|
+
if (lastSpace > chunkSize / 2) slice = slice.slice(0, lastSpace + 1);
|
|
44
|
+
}
|
|
45
|
+
if (slice.trim()) {
|
|
46
|
+
chunks.push({ content: slice.trim(), metadata: { index: chunks.length } });
|
|
47
|
+
}
|
|
48
|
+
const nextStart = start + slice.length - chunkOverlap;
|
|
49
|
+
start = nextStart > start ? nextStart : start + slice.length;
|
|
50
|
+
if (start >= text.length) break;
|
|
51
|
+
}
|
|
52
|
+
return chunks;
|
|
53
|
+
}
|
|
54
|
+
export function createFileLoader(options) {
|
|
55
|
+
const { pdf, docx, chunkSize = 800, chunkOverlap = 100 } = options;
|
|
56
|
+
return {
|
|
57
|
+
async loadFromText(content) {
|
|
58
|
+
return chunkText(content, { chunkSize, chunkOverlap });
|
|
59
|
+
},
|
|
60
|
+
async loadFromMarkdown(content) {
|
|
61
|
+
return loadMarkdown(content, { chunkSize, chunkOverlap });
|
|
62
|
+
},
|
|
63
|
+
async loadFromPDF(input) {
|
|
64
|
+
if (!pdf)
|
|
65
|
+
throw new Error("PDF loader not configured. Provide options.pdf or install a PDF library.");
|
|
66
|
+
return pdf(input);
|
|
67
|
+
},
|
|
68
|
+
async loadFromDOCX(input) {
|
|
69
|
+
if (!docx)
|
|
70
|
+
throw new Error(
|
|
71
|
+
"DOCX loader not configured. Provide options.docx or install a DOCX library."
|
|
72
|
+
);
|
|
73
|
+
return docx(input);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.MCPServer = void 0;
|
|
7
|
+
exports.createMCPServerHTTPHandler = createMCPServerHTTPHandler;
|
|
8
|
+
exports.useMCPServer = useMCPServer;
|
|
9
|
+
var _vue = require("vue");
|
|
10
|
+
class MCPServer {
|
|
11
|
+
config;
|
|
12
|
+
tools = /* @__PURE__ */new Map();
|
|
13
|
+
requestHandlers = /* @__PURE__ */new Map();
|
|
14
|
+
isRunning = false;
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.config = options.config;
|
|
17
|
+
if (options.tools) {
|
|
18
|
+
for (const tool of options.tools) {
|
|
19
|
+
this.tools.set(tool.name, tool);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
this.registerRequestHandler("initialize", this.handleInitialize.bind(this));
|
|
23
|
+
this.registerRequestHandler("tools/list", this.handleToolsList.bind(this));
|
|
24
|
+
this.registerRequestHandler("tools/call", this.handleToolsCall.bind(this));
|
|
25
|
+
this.registerRequestHandler("ping", this.handlePing.bind(this));
|
|
26
|
+
options.onStart?.(this);
|
|
27
|
+
}
|
|
28
|
+
registerRequestHandler(method, handler) {
|
|
29
|
+
this.requestHandlers.set(method, handler);
|
|
30
|
+
}
|
|
31
|
+
generateId() {
|
|
32
|
+
return Math.random().toString(36).substring(2, 9);
|
|
33
|
+
}
|
|
34
|
+
// ── Request Handlers ─────────────────────────────────────────────────────
|
|
35
|
+
handleInitialize(params) {
|
|
36
|
+
const initParams = params;
|
|
37
|
+
return {
|
|
38
|
+
protocolVersion: initParams?.protocolVersion || "2024-11-05",
|
|
39
|
+
capabilities: {
|
|
40
|
+
tools: {}
|
|
41
|
+
},
|
|
42
|
+
serverInfo: {
|
|
43
|
+
name: this.config.name,
|
|
44
|
+
version: this.config.version
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
handleToolsList() {
|
|
49
|
+
const tools = Array.from(this.tools.values()).map(tool => ({
|
|
50
|
+
name: tool.name,
|
|
51
|
+
description: tool.description,
|
|
52
|
+
inputSchema: tool.inputSchema
|
|
53
|
+
}));
|
|
54
|
+
return {
|
|
55
|
+
tools
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
async handleToolsCall(params) {
|
|
59
|
+
const callParams = params;
|
|
60
|
+
if (!callParams?.name) {
|
|
61
|
+
throw new Error("Missing tool name");
|
|
62
|
+
}
|
|
63
|
+
const tool = this.tools.get(callParams.name);
|
|
64
|
+
if (!tool) {
|
|
65
|
+
throw new Error(`Tool not found: ${callParams.name}`);
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
const result = await tool.execute(callParams.arguments || {});
|
|
69
|
+
return {
|
|
70
|
+
content: result
|
|
71
|
+
};
|
|
72
|
+
} catch (err) {
|
|
73
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
74
|
+
return {
|
|
75
|
+
content: [{
|
|
76
|
+
type: "text",
|
|
77
|
+
text: errorMessage
|
|
78
|
+
}],
|
|
79
|
+
isError: true
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
handlePing() {
|
|
84
|
+
return {
|
|
85
|
+
pong: true
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// ── Public API ───────────────────────────────────────────────────────────
|
|
89
|
+
/** Add a tool to the server */
|
|
90
|
+
addTool(tool) {
|
|
91
|
+
this.tools.set(tool.name, tool);
|
|
92
|
+
}
|
|
93
|
+
/** Remove a tool from the server */
|
|
94
|
+
removeTool(name) {
|
|
95
|
+
return this.tools.delete(name);
|
|
96
|
+
}
|
|
97
|
+
/** Get all tools */
|
|
98
|
+
getTools() {
|
|
99
|
+
return Array.from(this.tools.values());
|
|
100
|
+
}
|
|
101
|
+
/** Check if server is running */
|
|
102
|
+
getRunning() {
|
|
103
|
+
return this.isRunning;
|
|
104
|
+
}
|
|
105
|
+
/** Set running state */
|
|
106
|
+
setRunning(running) {
|
|
107
|
+
this.isRunning = running;
|
|
108
|
+
}
|
|
109
|
+
/** Handle a JSON-RPC request */
|
|
110
|
+
async handleRequest(request) {
|
|
111
|
+
const {
|
|
112
|
+
method,
|
|
113
|
+
params,
|
|
114
|
+
id
|
|
115
|
+
} = request;
|
|
116
|
+
const handler = this.requestHandlers.get(method);
|
|
117
|
+
if (!handler) {
|
|
118
|
+
return {
|
|
119
|
+
jsonrpc: "2.0",
|
|
120
|
+
id,
|
|
121
|
+
error: {
|
|
122
|
+
code: -32601,
|
|
123
|
+
// Method not found
|
|
124
|
+
message: `Method not found: ${method}`
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
const result = await handler(params);
|
|
130
|
+
return {
|
|
131
|
+
jsonrpc: "2.0",
|
|
132
|
+
id,
|
|
133
|
+
result
|
|
134
|
+
};
|
|
135
|
+
} catch (err) {
|
|
136
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
137
|
+
return {
|
|
138
|
+
jsonrpc: "2.0",
|
|
139
|
+
id,
|
|
140
|
+
error: {
|
|
141
|
+
code: -32e3,
|
|
142
|
+
message: errorMessage
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/** Handle a batch of JSON-RPC requests */
|
|
148
|
+
async handleBatch(requests) {
|
|
149
|
+
return Promise.all(requests.map(req => this.handleRequest(req)));
|
|
150
|
+
}
|
|
151
|
+
/** Cleanup */
|
|
152
|
+
destroy() {
|
|
153
|
+
this.tools.clear();
|
|
154
|
+
this.requestHandlers.clear();
|
|
155
|
+
this.isRunning = false;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.MCPServer = MCPServer;
|
|
159
|
+
function useMCPServer(options) {
|
|
160
|
+
const config = {
|
|
161
|
+
name: options.name,
|
|
162
|
+
version: options.version,
|
|
163
|
+
capabilities: {
|
|
164
|
+
tools: true
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const tools = (0, _vue.ref)(options.tools || []);
|
|
168
|
+
const isRunning = (0, _vue.ref)(false);
|
|
169
|
+
const server = new MCPServer({
|
|
170
|
+
config,
|
|
171
|
+
tools: options.tools,
|
|
172
|
+
onStart: () => {
|
|
173
|
+
isRunning.value = true;
|
|
174
|
+
},
|
|
175
|
+
onStop: () => {
|
|
176
|
+
isRunning.value = false;
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
const addTool = tool => {
|
|
180
|
+
server.addTool(tool);
|
|
181
|
+
tools.value = server.getTools();
|
|
182
|
+
options.onToolsChange?.(tools.value);
|
|
183
|
+
};
|
|
184
|
+
const removeTool = name => {
|
|
185
|
+
const result = server.removeTool(name);
|
|
186
|
+
tools.value = server.getTools();
|
|
187
|
+
options.onToolsChange?.(tools.value);
|
|
188
|
+
return result;
|
|
189
|
+
};
|
|
190
|
+
const handleRequest = async request => {
|
|
191
|
+
return server.handleRequest(request);
|
|
192
|
+
};
|
|
193
|
+
const start = () => {
|
|
194
|
+
server.setRunning(true);
|
|
195
|
+
isRunning.value = true;
|
|
196
|
+
};
|
|
197
|
+
const stop = () => {
|
|
198
|
+
server.setRunning(false);
|
|
199
|
+
isRunning.value = false;
|
|
200
|
+
server.destroy();
|
|
201
|
+
};
|
|
202
|
+
(0, _vue.onUnmounted)(() => {
|
|
203
|
+
stop();
|
|
204
|
+
});
|
|
205
|
+
return {
|
|
206
|
+
server,
|
|
207
|
+
config,
|
|
208
|
+
tools,
|
|
209
|
+
isRunning,
|
|
210
|
+
addTool,
|
|
211
|
+
removeTool,
|
|
212
|
+
handleRequest,
|
|
213
|
+
start,
|
|
214
|
+
stop
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function createMCPServerHTTPHandler(options) {
|
|
218
|
+
const {
|
|
219
|
+
server,
|
|
220
|
+
handleRequest
|
|
221
|
+
} = useMCPServer(options);
|
|
222
|
+
return async function (request) {
|
|
223
|
+
if (request.method === "OPTIONS") {
|
|
224
|
+
return new Response(null, {
|
|
225
|
+
headers: {
|
|
226
|
+
"Access-Control-Allow-Origin": "*",
|
|
227
|
+
"Access-Control-Allow-Methods": "GET, POST",
|
|
228
|
+
"Access-Control-Allow-Headers": "Content-Type"
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
try {
|
|
233
|
+
const body = await request.json();
|
|
234
|
+
if (Array.isArray(body)) {
|
|
235
|
+
const responses = await server.handleBatch(body);
|
|
236
|
+
return new Response(JSON.stringify(responses), {
|
|
237
|
+
headers: {
|
|
238
|
+
"Content-Type": "application/json"
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
const response = await handleRequest(body);
|
|
243
|
+
return new Response(JSON.stringify(response), {
|
|
244
|
+
headers: {
|
|
245
|
+
"Content-Type": "application/json"
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
} catch (err) {
|
|
249
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
250
|
+
return new Response(JSON.stringify({
|
|
251
|
+
jsonrpc: "2.0",
|
|
252
|
+
id: null,
|
|
253
|
+
error: {
|
|
254
|
+
code: -32603,
|
|
255
|
+
message: errorMessage
|
|
256
|
+
}
|
|
257
|
+
}), {
|
|
258
|
+
status: 500,
|
|
259
|
+
headers: {
|
|
260
|
+
"Content-Type": "application/json"
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
export interface MCPServerTool {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
inputSchema: Record<string, unknown>;
|
|
5
|
+
/** Execute function - returns content array per MCP spec */
|
|
6
|
+
execute: (args: Record<string, unknown>) => Promise<MCPToolContent[]>;
|
|
7
|
+
}
|
|
8
|
+
export interface MCPToolContent {
|
|
9
|
+
type: 'text' | 'image' | 'resource';
|
|
10
|
+
text?: string;
|
|
11
|
+
data?: string;
|
|
12
|
+
mimeType?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface MCPServerConfig {
|
|
15
|
+
/** Server name */
|
|
16
|
+
name: string;
|
|
17
|
+
/** Server version */
|
|
18
|
+
version: string;
|
|
19
|
+
/** Server capabilities */
|
|
20
|
+
capabilities?: {
|
|
21
|
+
tools?: boolean;
|
|
22
|
+
resources?: boolean;
|
|
23
|
+
prompts?: boolean;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface MCPServerOptions {
|
|
27
|
+
/** Server configuration */
|
|
28
|
+
config: MCPServerConfig;
|
|
29
|
+
/** Tools to expose */
|
|
30
|
+
tools?: MCPServerTool[];
|
|
31
|
+
/** Callback when server starts */
|
|
32
|
+
onStart?: (server: MCPServer) => void;
|
|
33
|
+
/** Callback when server stops */
|
|
34
|
+
onStop?: () => void;
|
|
35
|
+
/** Callback on error */
|
|
36
|
+
onError?: (error: Error) => void;
|
|
37
|
+
}
|
|
38
|
+
export type MCPServerTransport = 'http' | 'stdio';
|
|
39
|
+
export interface MCPHTTPHandler {
|
|
40
|
+
(request: MCPJSONRPCRequest): Promise<MCPJSONRPCResponse>;
|
|
41
|
+
}
|
|
42
|
+
export interface MCPJSONRPCRequest {
|
|
43
|
+
jsonrpc: '2.0';
|
|
44
|
+
id: number | string;
|
|
45
|
+
method: string;
|
|
46
|
+
params?: Record<string, unknown>;
|
|
47
|
+
}
|
|
48
|
+
export interface MCPJSONRPCResponse {
|
|
49
|
+
jsonrpc: '2.0';
|
|
50
|
+
id: number | string;
|
|
51
|
+
result?: unknown;
|
|
52
|
+
error?: {
|
|
53
|
+
code: number;
|
|
54
|
+
message: string;
|
|
55
|
+
data?: unknown;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export interface MCPJSONRPCNotification {
|
|
59
|
+
jsonrpc: '2.0';
|
|
60
|
+
method: string;
|
|
61
|
+
params?: Record<string, unknown>;
|
|
62
|
+
}
|
|
63
|
+
export declare class MCPServer {
|
|
64
|
+
readonly config: MCPServerConfig;
|
|
65
|
+
private tools;
|
|
66
|
+
private requestHandlers;
|
|
67
|
+
private isRunning;
|
|
68
|
+
constructor(options: MCPServerOptions);
|
|
69
|
+
private registerRequestHandler;
|
|
70
|
+
private generateId;
|
|
71
|
+
private handleInitialize;
|
|
72
|
+
private handleToolsList;
|
|
73
|
+
private handleToolsCall;
|
|
74
|
+
private handlePing;
|
|
75
|
+
/** Add a tool to the server */
|
|
76
|
+
addTool(tool: MCPServerTool): void;
|
|
77
|
+
/** Remove a tool from the server */
|
|
78
|
+
removeTool(name: string): boolean;
|
|
79
|
+
/** Get all tools */
|
|
80
|
+
getTools(): MCPServerTool[];
|
|
81
|
+
/** Check if server is running */
|
|
82
|
+
getRunning(): boolean;
|
|
83
|
+
/** Set running state */
|
|
84
|
+
setRunning(running: boolean): void;
|
|
85
|
+
/** Handle a JSON-RPC request */
|
|
86
|
+
handleRequest(request: MCPJSONRPCRequest): Promise<MCPJSONRPCResponse>;
|
|
87
|
+
/** Handle a batch of JSON-RPC requests */
|
|
88
|
+
handleBatch(requests: MCPJSONRPCRequest[]): Promise<MCPJSONRPCResponse[]>;
|
|
89
|
+
/** Cleanup */
|
|
90
|
+
destroy(): void;
|
|
91
|
+
}
|
|
92
|
+
export interface UseMCPServerOptions {
|
|
93
|
+
/** Server name */
|
|
94
|
+
name: string;
|
|
95
|
+
/** Server version */
|
|
96
|
+
version: string;
|
|
97
|
+
/** Initial tools */
|
|
98
|
+
tools?: MCPServerTool[];
|
|
99
|
+
/** Callback when tools change */
|
|
100
|
+
onToolsChange?: (tools: MCPServerTool[]) => void;
|
|
101
|
+
}
|
|
102
|
+
export interface UseMCPServerReturn {
|
|
103
|
+
/** Server instance */
|
|
104
|
+
server: MCPServer;
|
|
105
|
+
/** Server config */
|
|
106
|
+
config: MCPServerConfig;
|
|
107
|
+
/** Tools list (reactive) */
|
|
108
|
+
tools: {
|
|
109
|
+
value: MCPServerTool[];
|
|
110
|
+
};
|
|
111
|
+
/** Running state */
|
|
112
|
+
isRunning: {
|
|
113
|
+
value: boolean;
|
|
114
|
+
};
|
|
115
|
+
/** Add a tool */
|
|
116
|
+
addTool: (tool: MCPServerTool) => void;
|
|
117
|
+
/** Remove a tool */
|
|
118
|
+
removeTool: (name: string) => boolean;
|
|
119
|
+
/** Handle HTTP request */
|
|
120
|
+
handleRequest: (request: MCPJSONRPCRequest) => Promise<MCPJSONRPCResponse>;
|
|
121
|
+
/** Start server */
|
|
122
|
+
start: () => void;
|
|
123
|
+
/** Stop server */
|
|
124
|
+
stop: () => void;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* useMCPServer - MCP Server Hook
|
|
128
|
+
*
|
|
129
|
+
* 将 AI 应用作为 MCP Server 暴露工具
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```ts
|
|
133
|
+
* const { server, addTool, tools } = useMCPServer({
|
|
134
|
+
* name: 'my-ai-server',
|
|
135
|
+
* version: '1.0.0',
|
|
136
|
+
* tools: [
|
|
137
|
+
* {
|
|
138
|
+
* name: 'get_weather',
|
|
139
|
+
* description: 'Get weather for a city',
|
|
140
|
+
* inputSchema: {
|
|
141
|
+
* type: 'object',
|
|
142
|
+
* properties: {
|
|
143
|
+
* city: { type: 'string', description: 'City name' }
|
|
144
|
+
* },
|
|
145
|
+
* required: ['city']
|
|
146
|
+
* },
|
|
147
|
+
* execute: async ({ city }) => {
|
|
148
|
+
* return [{ type: 'text', text: `Weather in ${city}: Sunny, 25°C` }]
|
|
149
|
+
* }
|
|
150
|
+
* }
|
|
151
|
+
* ]
|
|
152
|
+
* })
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
export declare function useMCPServer(options: UseMCPServerOptions): UseMCPServerReturn;
|
|
156
|
+
/**
|
|
157
|
+
* createMCPServerHTTPHandler - 创建 HTTP 处理函数
|
|
158
|
+
*
|
|
159
|
+
* 用于在 Express/Next.js API Route 中暴露 MCP Server
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```ts
|
|
163
|
+
* // Next.js API Route (app/api/mcp/route.ts)
|
|
164
|
+
* import { createMCPServerHTTPHandler } from '@yh-ui/ai-sdk/mcp'
|
|
165
|
+
*
|
|
166
|
+
* const handler = createMCPServerHTTPHandler({
|
|
167
|
+
* name: 'my-ai-server',
|
|
168
|
+
* version: '1.0.0',
|
|
169
|
+
* tools: [
|
|
170
|
+
* {
|
|
171
|
+
* name: 'search',
|
|
172
|
+
* description: 'Search for information',
|
|
173
|
+
* inputSchema: { type: 'object', properties: { query: { type: 'string' } } },
|
|
174
|
+
* execute: async ({ query }) => {
|
|
175
|
+
* // Search logic here
|
|
176
|
+
* return [{ type: 'text', text: `Results for: ${query}` }]
|
|
177
|
+
* }
|
|
178
|
+
* }
|
|
179
|
+
* ]
|
|
180
|
+
* })
|
|
181
|
+
*
|
|
182
|
+
* export const GET = handler
|
|
183
|
+
* export const POST = handler
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
export declare function createMCPServerHTTPHandler(options: UseMCPServerOptions): (request: Request) => Promise<Response>;
|