feat: resources?

This commit is contained in:
hypercross 2026-03-18 13:24:57 +08:00
parent 8213092bb6
commit 301f499494
3 changed files with 183 additions and 0 deletions

View File

@ -289,6 +289,78 @@ label,name,type,cost,description
- 其他列:由 frontmatter 中的 `fields` 定义
- `body`: 卡牌 body 内容(可选,支持 `{{字段名}}` 语法)
## MCP Resources
MCP 服务器提供以下 Resources包含 TTRPG Tools 的文档和参考材料:
### `ttrpg-docs://csv` - CSV 编写说明
**名称:** csv.md
**标题:** CSV 编写说明
**描述:** TTRPG Tools CSV 文件格式说明,包括 Front Matter、字段定义、变量语法等
**内容包含:**
- YAML Front Matter 结构fields、deck、自定义属性
- 数据类型word、paragraph、number、symbol、symbol_list
- 字段功能identify、compare、flavor、rule
- CSV 数据格式和特殊字符处理
- 变量语法(`{{prop}}`
- 分组支持
- 完整示例魔法物品、随机遭遇表、NPC 名录)
### `ttrpg-docs://markdown` - Markdown 编写说明
**名称:** markdown.md
**标题:** Markdown 编写说明
**描述:** TTRPG Tools Markdown 扩展语法和组件用法说明
**内容包含:**
- 基础语法GFM、marked-alert、marked-directive
- 指令语法格式
- 图标语法(`:[icon-name]`
- 组件库:
- `:md-dice` - 骰子组件
- `:md-link` - 链接组件
- `:md-bg` - 背景组件
- `:md-pins` - 标记组件
- `:md-table` - 表格组件
- `:md-deck` - 卡牌组件
- `:md-yarn-spinner` - 叙事线组件
- `:md-token` - 代币组件
- `:md-commander` - 命令追踪器
- YAML 标签
- Mermaid 图表
- 警告/提示块
- 文件引用规则
- 样式定制
### 使用示例
**列出所有 Resources**
```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "resources/list"
}
```
**读取 Resource**
```json
{
"jsonrpc": "2.0",
"id": 2,
"method": "resources/read",
"params": {
"uri": "ttrpg-docs://csv"
}
}
```
---
## MCP Prompts
MCP 服务器提供以下 Prompts用于引导用户完成卡牌设计工作流

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
src/cli/resources/docs.ts Normal file
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;
}
}