fix: mcp serve
This commit is contained in:
parent
5389345a00
commit
e5ce8c20b5
|
|
@ -24,7 +24,7 @@ import {
|
|||
readResource,
|
||||
type DocResource
|
||||
} from '../resources/docs.js';
|
||||
import { serveCommand } from './serve.js';
|
||||
import { createContentServer, type ContentServer } from './serve.js';
|
||||
|
||||
/**
|
||||
* MCP 服务器命令
|
||||
|
|
@ -69,12 +69,8 @@ async function mcpServeAction(host: string, options: MCPOptions) {
|
|||
process.chdir(cwd);
|
||||
console.error(`MCP 服务器工作目录:${cwd}`);
|
||||
|
||||
// 启动 serve 服务器(在后台运行)
|
||||
console.error('启动预览服务器...');
|
||||
serveCommand(cwd, { port: '3000' });
|
||||
|
||||
// 等待服务器启动
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
// 启动内容服务器(预览服务器)
|
||||
const contentServer: ContentServer = createContentServer(cwd, 3000);
|
||||
|
||||
// 动态导入 MCP SDK
|
||||
const { Server } = await import('@modelcontextprotocol/sdk/server/index.js');
|
||||
|
|
@ -328,7 +324,7 @@ async function mcpServeAction(host: string, options: MCPOptions) {
|
|||
}
|
||||
|
||||
case 'deck_card_crud': {
|
||||
const params = args as unknown as CardCrudParams;
|
||||
let params = args as unknown as CardCrudParams;
|
||||
|
||||
if (!params.csv_file || !params.action) {
|
||||
return {
|
||||
|
|
@ -337,6 +333,15 @@ async function mcpServeAction(host: string, options: MCPOptions) {
|
|||
};
|
||||
}
|
||||
|
||||
// 解析 cards 参数(可能是 JSON 字符串)
|
||||
if (params.cards && typeof params.cards === 'string') {
|
||||
try {
|
||||
params.cards = JSON.parse(params.cards);
|
||||
} catch (e) {
|
||||
// 如果不是 JSON,保持原样
|
||||
}
|
||||
}
|
||||
|
||||
const result = cardCrud(params);
|
||||
|
||||
return {
|
||||
|
|
@ -465,6 +470,19 @@ async function mcpServeAction(host: string, options: MCPOptions) {
|
|||
const transport = new StdioServerTransport();
|
||||
await server.connect(transport);
|
||||
console.error('TTRPG 卡牌生成 MCP 服务器已启动(stdio)');
|
||||
|
||||
// 监听进程退出事件,关闭服务器
|
||||
process.on('SIGINT', () => {
|
||||
console.error('\n正在关闭服务器...');
|
||||
contentServer.close();
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
process.on('SIGTERM', () => {
|
||||
console.error('\n正在关闭服务器...');
|
||||
contentServer.close();
|
||||
process.exit(0);
|
||||
});
|
||||
} else {
|
||||
// TODO: 支持 HTTP 传输
|
||||
console.error('HTTP 传输模式尚未实现,请使用 stdio 模式');
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ function getMimeType(filePath: string): string {
|
|||
/**
|
||||
* 扫描目录内的 .md 文件,生成索引
|
||||
*/
|
||||
function scanDirectory(dir: string): ContentIndex {
|
||||
export function scanDirectory(dir: string): ContentIndex {
|
||||
const index: ContentIndex = {};
|
||||
|
||||
function scan(currentPath: string, relativePath: string) {
|
||||
|
|
@ -176,10 +176,35 @@ function createRequestHandler(
|
|||
}
|
||||
|
||||
/**
|
||||
* 启动开发服务器
|
||||
* 内容服务器接口
|
||||
*/
|
||||
export const serveCommand: ServeCommandHandler = async (dir, options) => {
|
||||
const contentDir = resolve(dir);
|
||||
export interface ContentServer {
|
||||
/**
|
||||
* HTTP 服务器实例
|
||||
*/
|
||||
server: Server;
|
||||
/**
|
||||
* 文件监听器
|
||||
*/
|
||||
watcher: ReturnType<typeof watch>;
|
||||
/**
|
||||
* 内容索引
|
||||
*/
|
||||
index: ContentIndex;
|
||||
/**
|
||||
* 关闭服务器
|
||||
*/
|
||||
close(): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建内容服务器
|
||||
*/
|
||||
export function createContentServer(
|
||||
contentDir: string,
|
||||
port: number,
|
||||
distPath: string = distDir,
|
||||
): ContentServer {
|
||||
let contentIndex: ContentIndex = {};
|
||||
|
||||
// 扫描内容目录生成索引
|
||||
|
|
@ -231,19 +256,38 @@ export const serveCommand: ServeCommandHandler = async (dir, options) => {
|
|||
// 创建请求处理器
|
||||
const handleRequest = createRequestHandler(
|
||||
contentDir,
|
||||
distDir,
|
||||
distPath,
|
||||
() => contentIndex,
|
||||
);
|
||||
|
||||
// 创建 HTTP 服务器
|
||||
const server = createServer(handleRequest);
|
||||
|
||||
const port = parseInt(options.port, 10);
|
||||
|
||||
server.listen(port, () => {
|
||||
console.log(`\n开发服务器已启动:http://localhost:${port}`);
|
||||
console.log(`内容目录:${contentDir}`);
|
||||
console.log(`静态资源目录:${distDir}`);
|
||||
console.log(`静态资源目录:${distPath}`);
|
||||
console.log(`索引文件:http://localhost:${port}/__CONTENT_INDEX.json\n`);
|
||||
});
|
||||
|
||||
return {
|
||||
server,
|
||||
watcher,
|
||||
index: contentIndex,
|
||||
close() {
|
||||
console.log("关闭内容服务器...");
|
||||
server.close();
|
||||
watcher.close();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动开发服务器
|
||||
*/
|
||||
export const serveCommand: ServeCommandHandler = async (dir, options) => {
|
||||
const contentDir = resolve(dir);
|
||||
const port = parseInt(options.port, 10);
|
||||
|
||||
createContentServer(contentDir, port);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue