feat(mcp): 增强文件工具支持文本内容读取

- get_file_detail: 添加 with_content 参数提取文本
  - 新增 fetch_file_content 工具通过路径获取内容
This commit is contained in:
kuaifan 2026-01-16 01:39:31 +00:00
parent 23b06327d6
commit 12d6bbea19

94
electron/lib/mcp.js vendored
View File

@ -27,9 +27,10 @@
* - update_project - 修改项目信息名称描述等 * - update_project - 修改项目信息名称描述等
* *
* === 文件管理个人文件系统 === * === 文件管理个人文件系统 ===
* - list_files - 浏览个人文件系统获取指定文件夹下的文件和子文件夹列表 * - list_files - 浏览个人文件系统获取指定文件夹下的文件和子文件夹列表
* - search_files - 搜索用户文件系统中的文件自己创建的和共享给自己的 * - search_files - 搜索用户文件系统中的文件自己创建的和共享给自己的
* - get_file_detail - 获取文件详情支持通过文件ID或分享码访问返回 content_url 可配合 WebFetch 读取 * - get_file_detail - 获取文件详情可选提取文本内容
* - fetch_file_content - 通过文件路径获取文本内容
* *
* === 工作报告 === * === 工作报告 ===
* - list_received_reports - 获取我接收的汇报列表支持按类型/状态/部门/时间筛选 * - list_received_reports - 获取我接收的汇报列表支持按类型/状态/部门/时间筛选
@ -74,7 +75,8 @@
* - "查看我的文件列表" * - "查看我的文件列表"
* - "搜索包含'设计稿'的文件" * - "搜索包含'设计稿'的文件"
* - "显示文件123的详细信息" * - "显示文件123的详细信息"
* - "帮我分析这个文档的内容" * - "帮我阅读这个Word文档的内容"
* - "分析这份PDF报告的要点"
* *
* 工作报告 * 工作报告
* - "查看未读的工作汇报" * - "查看未读的工作汇报"
@ -1902,16 +1904,38 @@ class DooTaskMCP {
// 文件管理:获取文件详情 // 文件管理:获取文件详情
this.mcp.addTool({ this.mcp.addTool({
name: 'get_file_detail', name: 'get_file_detail',
description: '获取文件详情,包括类型、大小、共享状态等。支持文件ID或分享码。', description: '获取文件详情,包括类型、大小、正文内容、共享状态等。',
parameters: z.object({ parameters: z.object({
file_id: z.union([z.number(), z.string()]) file_id: z.union([z.number(), z.string()])
.describe('文件ID数字或分享码字符串'), .describe('文件ID 或分享码'),
with_content: z.boolean()
.optional()
.describe('是否提取文本内容'),
text_offset: z.number()
.optional()
.describe('文本起始位置'),
text_limit: z.number()
.optional()
.describe('获取长度默认50000最大200000'),
}), }),
execute: async (params) => { execute: async (params) => {
const result = await this.request('GET', 'file/one', { const requestData = {
id: params.file_id, id: params.file_id,
with_url: 'yes', with_url: 'yes',
}); };
// 如果需要提取文本内容
if (params.with_content) {
requestData.with_text = 'yes';
if (params.text_offset !== undefined) {
requestData.text_offset = params.text_offset;
}
if (params.text_limit !== undefined) {
requestData.text_limit = Math.min(params.text_limit, 200000);
}
}
const result = await this.request('GET', 'file/one', requestData);
if (result.error) { if (result.error) {
throw new Error(result.error); throw new Error(result.error);
@ -1934,6 +1958,19 @@ class DooTaskMCP {
updated_at: file.updated_at, updated_at: file.updated_at,
}; };
// 如果有文本内容
if (file.text_content) {
if (file.text_content.error) {
fileDetail.text_error = file.text_content.error;
} else {
fileDetail.text_content = file.text_content.content;
fileDetail.text_total_length = file.text_content.total_length;
fileDetail.text_offset = file.text_content.offset;
fileDetail.text_limit = file.text_content.limit;
fileDetail.text_has_more = file.text_content.has_more;
}
}
return { return {
content: [{ content: [{
type: 'text', type: 'text',
@ -1943,6 +1980,47 @@ class DooTaskMCP {
} }
}); });
// 文件管理:通过路径获取文件内容
this.mcp.addTool({
name: 'fetch_file_content',
description: '通过文件路径获取文本内容。',
parameters: z.object({
path: z.string()
.describe('系统内文件路径或URL'),
offset: z.number()
.optional()
.describe('起始位置'),
limit: z.number()
.optional()
.describe('获取长度默认50000最大200000'),
}),
execute: async (params) => {
const requestData = {
path: params.path,
};
if (params.offset !== undefined) {
requestData.offset = params.offset;
}
if (params.limit !== undefined) {
requestData.limit = Math.min(params.limit, 200000);
}
const result = await this.request('GET', 'file/fetch', requestData);
if (result.error) {
throw new Error(result.error);
}
return {
content: [{
type: 'text',
text: JSON.stringify(result.data, null, 2)
}]
};
}
});
// 智能搜索:统一搜索工具 // 智能搜索:统一搜索工具
this.mcp.addTool({ this.mcp.addTool({
name: 'intelligent_search', name: 'intelligent_search',