mcp-cook
Version:
An MCP service for providing dish information.
116 lines (115 loc) • 4.38 kB
JavaScript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { promises as fs, existsSync } from "fs";
import * as path from "path";
import { z } from "zod";
import { fileURLToPath } from "url";
// Determine the directory of the current module
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Define the path to the dishes directory relative to the built index.js
// This assumes the 'dishes' folder is copied next to the compiled index.js in the build directory
const dishesDir = path.join(__dirname, "dishes");
// Create server instance
const server = new McpServer({
name: "mcp-cook",
version: "0.1.0",
description: "An MCP service for providing dish information.",
});
// Tool to get all dish names
server.tool("get_all_dishes", "获取所有可用菜品的名称列表 (菜单)。", {}, async () => {
try {
// Check if dishes directory exists
if (!existsSync(dishesDir)) {
console.error(`Dishes directory not found at: ${dishesDir}`);
return {
content: [
{
type: "text",
text: `错误:菜品目录未找到。请确保 \'dishes\' 目录已在构建过程中被正确复制。 expected path: ${dishesDir}`,
},
],
};
}
const files = await fs.readdir(dishesDir, { encoding: "utf8" });
const dishNames = files
.filter((file) => file.endsWith(".md"))
.map((file) => path.basename(file, ".md"));
return {
content: [
{
type: "text",
text: `可用菜品 (${dishNames.length} 项):\n${dishNames.join("\n")}`,
},
],
// Optionally return data structure for programmatic use
data: { dishes: dishNames },
};
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
console.error("获取菜品列表时出错:", errorMessage);
return {
content: [
{
type: "text",
text: `获取菜品列表时出错: ${errorMessage}`,
},
],
};
}
});
// Input schema for get_dish_content
// Tool to get the content of a specific dish
server.tool("get_dish_content", "根据提供的菜品名称获取其详细内容。", {
dishName: z.string().describe("要获取内容的菜品名称 (例如 '麻婆豆腐')"),
}, async ({ dishName }) => {
// dishName中可能有中文,需要进行编码, 转为utf-8
// 对菜品名称进行编码,确保中文字符能够正确处理
const filePath = path.join(dishesDir, `${dishName}.md`);
try {
if (!existsSync(filePath)) {
console.error(`Dish file not found: ${filePath}`);
return {
content: [
{
type: "text",
text: `错误:找不到菜品 \'${dishName}\'。请确保名称正确且文件存在于 \'dishes\' 目录中。, expected path: ${filePath}`,
},
],
};
}
const content = await fs.readFile(filePath, "utf-8");
return {
content: [
{
type: "text",
text: content,
},
],
// Optionally return data structure
data: { dishName: dishName, content: content },
};
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
console.error(`获取菜品 \'${dishName}\' 内容时出错:`, errorMessage);
return {
content: [
{
type: "text",
text: `获取菜品 \'${dishName}\' 内容时出错: ${errorMessage}`,
},
],
};
}
});
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
}
main().catch((error) => {
console.error("Fatal error in main():", error);
process.exit(1);
});