feat: resources?

This commit is contained in:
2026-03-18 13:25:01 +08:00
parent 8213092bb6
commit 301f499494
3 changed files with 183 additions and 0 deletions
+36
View File
@@ -19,6 +19,11 @@ import {
getSetupDeckDisplayPrompt,
type SetupDeckDisplayOptions
} from '../prompts/setup-deck-display.js';
import {
listResources,
readResource,
type DocResource
} from '../resources/docs.js';
/**
* MCP 服务器命令
@@ -71,6 +76,8 @@ async function mcpServeAction(host: string, options: MCPOptions) {
ListToolsRequestSchema,
ListPromptsRequestSchema,
GetPromptRequestSchema,
ListResourcesRequestSchema,
ReadResourceRequestSchema,
} = await import('@modelcontextprotocol/sdk/types.js');
const server = new Server(
@@ -82,6 +89,7 @@ async function mcpServeAction(host: string, options: MCPOptions) {
capabilities: {
tools: {},
prompts: {},
resources: {},
},
}
);
@@ -411,6 +419,34 @@ async function mcpServeAction(host: string, options: MCPOptions) {
}
});
// 处理 Resources 列表请求
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return {
resources: listResources().map(r => ({
uri: r.uri,
name: r.name,
title: r.title,
description: r.description,
mimeType: r.mimeType,
})),
};
});
// 处理 Resources 读取请求
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
const { uri } = request.params;
const resource = readResource(uri, process.cwd());
if (!resource) {
throw new Error(`Resource not found: ${uri}`);
}
return {
contents: [resource],
};
});
// 启动服务器
if (host === 'stdio') {
const transport = new StdioServerTransport();
+75
View File
@@ -0,0 +1,75 @@
import { readFileSync, existsSync } from 'fs';
import { join } from 'path';
/**
* 文档资源定义
*/
export interface DocResource {
uri: string;
name: string;
title?: string;
description?: string;
mimeType?: string;
}
/**
* 预定义的文档资源列表
*/
export const DOC_RESOURCES: DocResource[] = [
{
uri: 'ttrpg-docs://csv',
name: 'csv.md',
title: 'CSV 编写说明',
description: 'TTRPG Tools CSV 文件格式说明,包括 Front Matter、字段定义、变量语法等',
mimeType: 'text/markdown'
},
{
uri: 'ttrpg-docs://markdown',
name: 'markdown.md',
title: 'Markdown 编写说明',
description: 'TTRPG Tools Markdown 扩展语法和组件用法说明',
mimeType: 'text/markdown'
}
];
/**
* 获取资源列表
*/
export function listResources(): DocResource[] {
return DOC_RESOURCES;
}
/**
* 读取资源内容
* @param uri 资源 URI
* @param cwd 工作目录
* @returns 资源内容
*/
export function readResource(uri: string, cwd: string): {
uri: string;
mimeType: string;
text: string;
} | null {
// 解析 URI
const docName = uri.replace('ttrpg-docs://', '');
const fileName = `${docName}.md`;
const filePath = join(cwd, 'docs', fileName);
// 检查文件是否存在
if (!existsSync(filePath)) {
return null;
}
// 读取文件内容
try {
const content = readFileSync(filePath, 'utf-8');
return {
uri,
mimeType: 'text/markdown',
text: content
};
} catch (error) {
console.warn(`Failed to read resource ${uri}:`, error);
return null;
}
}