Loading...
Loading...
Compare original and translation side by side
/add-mcp-tool [tool-name]/add-mcp-tool [tool-name][tool-name][tool-name]Looking for FastMCP server...
Found: src/server.ts
Is this the correct server file? (yes/no):I couldn't find a FastMCP server. Please provide the path to your server file:正在查找FastMCP服务器...
已找到:src/server.ts
这是正确的服务器文件吗?(是/否):我无法找到FastMCP服务器。请提供您的服务器文件路径:Let's add a new tool to your MCP server.
Tool name (lowercase, use hyphens):
Example: "fetch-data", "create-file", "query-database"
Tool name:Tool description (shown to LLM clients):
Example: "Fetches data from the specified API endpoint"
Description:让我们为您的MCP服务器添加一个新工具。
工具名称(小写,使用连字符):
示例:"fetch-data", "create-file", "query-database"
工具名称:工具描述(将展示给LLM客户端):
示例:"从指定API端点获取数据"
描述:Does this tool require parameters?
1. No parameters
2. Simple parameters (strings, numbers, booleans)
3. Complex parameters (objects, arrays, enums)
Select (1-3):Let's define the parameters one by one.
Parameter 1:
Name:
Type (string/number/boolean/array/object):
Required? (yes/no):
Description:
Add another parameter? (yes/no):Enum values (comma-separated):
Example: "json,xml,csv"
Values:此工具是否需要参数?
1. 无参数
2. 简单参数(字符串、数字、布尔值)
3. 复杂参数(对象、数组、枚举)
请选择(1-3):让我们逐一定义参数。
参数1:
名称:
类型(string/number/boolean/array/object):
是否必填?(是/否):
描述:
是否添加另一个参数?(是/否):枚举值(逗号分隔):
示例:"json,xml,csv"
值:What does this tool return?
1. Simple text response
2. Multiple content items
3. Image content
4. Audio content
5. Resource reference
6. Custom structure
Select (1-6):此工具返回什么类型的内容?
1. 简单文本响应
2. 多个内容项
3. 图片内容
4. 音频内容
5. 资源引用
6. 自定义结构
请选择(1-6):Which features do you need?
[ ] Logging (log.info, log.error, etc.)
[ ] Progress reporting (for long operations)
[ ] Streaming output (for text generation)
[ ] Authorization check (canAccess)
[ ] Error handling with UserError
Select features (comma-separated numbers, or 'none'):您需要哪些功能?
[ ] 日志记录(log.info、log.error等)
[ ] 进度报告(针对长时操作)
[ ] 流式输出(针对文本生成)
[ ] 权限校验(canAccess)
[ ] 基于UserError的错误处理
请选择功能(逗号分隔的数字,或输入'none'):Optional annotations for LLM clients:
Read-only hint (tool doesn't modify state)? (yes/no) [default: no]:
Open-world hint (tool accesses external systems)? (yes/no) [default: no]:
Streaming hint (tool produces streaming output)? (yes/no) [default: no]:为LLM客户端添加可选注解:
是否为只读提示(工具不修改状态)?(是/否)[默认:否]:
是否为开放世界提示(工具访问外部系统)?(是/否)[默认:否]:
是否为流式提示(工具生成流式输出)?(是/否)[默认:否]:server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
execute: async () => {
return "Result here";
},
});server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
execute: async () => {
return "Result here";
},
});server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
{{#each parameters}}
{{name}}: z.{{type}}(){{#if description}}.describe("{{description}}"){{/if}}{{#unless required}}.optional(){{/unless}},
{{/each}}
}),
execute: async (args) => {
const { {{parameterNames}} } = args;
// TODO: Implement tool logic
return "Processed: " + JSON.stringify(args);
},
});server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
{{#each parameters}}
{{name}}: z.{{type}}(){{#if description}}.describe("{{description}}"){{/if}}{{#unless required}}.optional(){{/unless}},
{{/each}}
}),
execute: async (args) => {
const { {{parameterNames}} } = args;
// TODO: Implement tool logic
return "Processed: " + JSON.stringify(args);
},
});server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
url: z.string().describe("URL to fetch"),
}),
execute: async (args, { log }) => {
log.info("Starting operation", { url: args.url });
try {
// TODO: Implement logic
const result = await fetchData(args.url);
log.info("Operation completed successfully");
return result;
} catch (error) {
log.error("Operation failed", { error: String(error) });
throw error;
}
},
});server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
url: z.string().describe("URL to fetch"),
}),
execute: async (args, { log }) => {
log.info("Starting operation", { url: args.url });
try {
// TODO: Implement logic
const result = await fetchData(args.url);
log.info("Operation completed successfully");
return result;
} catch (error) {
log.error("Operation failed", { error: String(error) });
throw error;
}
},
});server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
items: z.array(z.string()).describe("Items to process"),
}),
execute: async (args, { reportProgress }) => {
const total = args.items.length;
const results: string[] = [];
for (let i = 0; i < total; i++) {
await reportProgress({ progress: i, total });
// TODO: Process each item
results.push("Processed: " + args.items[i]);
}
await reportProgress({ progress: total, total });
return results.join("\n");
},
});server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
items: z.array(z.string()).describe("Items to process"),
}),
execute: async (args, { reportProgress }) => {
const total = args.items.length;
const results: string[] = [];
for (let i = 0; i < total; i++) {
await reportProgress({ progress: i, total });
// TODO: Process each item
results.push("Processed: " + args.items[i]);
}
await reportProgress({ progress: total, total });
return results.join("\n");
},
});server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
prompt: z.string().describe("Input prompt"),
}),
annotations: {
streamingHint: true,
},
execute: async (args, { streamContent }) => {
// Stream content progressively
await streamContent({ type: "text", text: "Processing...\n" });
// TODO: Generate content
const chunks = ["First ", "part, ", "second ", "part."];
for (const chunk of chunks) {
await streamContent({ type: "text", text: chunk });
await new Promise(r => setTimeout(r, 100));
}
return; // Return undefined when using streaming
},
});server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
prompt: z.string().describe("Input prompt"),
}),
annotations: {
streamingHint: true,
},
execute: async (args, { streamContent }) => {
// Stream content progressively
await streamContent({ type: "text", text: "Processing...\n" });
// TODO: Generate content
const chunks = ["First ", "part, ", "second ", "part."];
for (const chunk of chunks) {
await streamContent({ type: "text", text: chunk });
await new Promise(r => setTimeout(r, 100));
}
return; // Return undefined when using streaming
},
});server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
canAccess: (auth) => {
// Return true if user is authorized
return auth?.role === "admin";
},
execute: async (args, { session }) => {
// Tool is only executed if canAccess returns true
return "Welcome, " + session.id;
},
});server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
canAccess: (auth) => {
// Return true if user is authorized
return auth?.role === "admin";
},
execute: async (args, { session }) => {
// Tool is only executed if canAccess returns true
return "Welcome, " + session.id;
},
});import { UserError } from "fastmcp";
server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
id: z.string().describe("Resource ID"),
}),
execute: async (args) => {
// Validate input
if (!args.id.match(/^[a-z0-9-]+$/)) {
throw new UserError("Invalid ID format. Use lowercase letters, numbers, and hyphens only.");
}
// Check resource exists
const resource = await findResource(args.id);
if (!resource) {
throw new UserError(`Resource not found: ${args.id}`);
}
return JSON.stringify(resource);
},
});import { UserError } from "fastmcp";
server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
id: z.string().describe("Resource ID"),
}),
execute: async (args) => {
// Validate input
if (!args.id.match(/^[a-z0-9-]+$/)) {
throw new UserError("Invalid ID format. Use lowercase letters, numbers, and hyphens only.");
}
// Check resource exists
const resource = await findResource(args.id);
if (!resource) {
throw new UserError(`Resource not found: ${args.id}`);
}
return JSON.stringify(resource);
},
});import { imageContent } from "fastmcp";
server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
imageId: z.string().describe("Image identifier"),
}),
execute: async (args) => {
// Return image from URL
return imageContent({
url: `https://example.com/images/${args.imageId}.png`,
});
// Or from file path:
// return imageContent({ path: `/path/to/${args.imageId}.png` });
// Or from buffer:
// return imageContent({ buffer: imageBuffer });
},
});import { imageContent } from "fastmcp";
server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
parameters: z.object({
imageId: z.string().describe("Image identifier"),
}),
execute: async (args) => {
// Return image from URL
return imageContent({
url: `https://example.com/images/${args.imageId}.png`,
});
// Or from file path:
// return imageContent({ path: `/path/to/${args.imageId}.png` });
// Or from buffer:
// return imageContent({ buffer: imageBuffer });
},
});server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
execute: async () => {
return {
content: [
{ type: "text", text: "Here's the analysis:" },
{ type: "text", text: "Line 1: Found 5 issues" },
{ type: "text", text: "Line 2: 3 warnings" },
],
};
},
});server.addTool({
name: "{{tool-name}}",
description: "{{description}}",
execute: async () => {
return {
content: [
{ type: "text", text: "Here's the analysis:" },
{ type: "text", text: "Line 1: Found 5 issues" },
{ type: "text", text: "Line 2: 3 warnings" },
],
};
},
});Where should the tool code be added?
1. Inline in server.ts (simple projects)
2. New file in tools/ directory (recommended for organization)
3. Existing tools file (specify which)
Select (1-3):工具代码应放置在何处?
1. 内联到server.ts中(适用于简单项目)
2. tools/目录下的新文件(推荐用于项目组织)
3. 现有工具文件中(指定具体文件)
请选择(1-3):