UNPKG

ohcard-cloud-mcp

Version:

OH卡心理投射工具MCP服务器 - 云端托管版本,通过图像探索内心世界,获得洞察和启发

397 lines (396 loc) 18.1 kB
#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { RestServerTransport } from "@chatmcp/sdk/server/rest.js"; import { getParamValue } from "@chatmcp/sdk/utils/index.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; // OH卡数据结构 const OH_CARDS = { 1: { image_url: "https://cosmowind.github.io/oh-cards/images/card_01.png" }, 2: { image_url: "https://cosmowind.github.io/oh-cards/images/card_02.png" }, 3: { image_url: "https://cosmowind.github.io/oh-cards/images/card_03.png" }, 4: { image_url: "https://cosmowind.github.io/oh-cards/images/card_04.png" }, 5: { image_url: "https://cosmowind.github.io/oh-cards/images/card_05.png" }, 6: { image_url: "https://cosmowind.github.io/oh-cards/images/card_06.png" }, 7: { image_url: "https://cosmowind.github.io/oh-cards/images/card_07.png" }, 8: { image_url: "https://cosmowind.github.io/oh-cards/images/card_08.png" }, 9: { image_url: "https://cosmowind.github.io/oh-cards/images/card_09.png" } }; // 引导问题库 const GUIDANCE_QUESTIONS = { "观察感受": [ "看到了什么?感受如何?", "抽到的卡牌与你最近发生的事或感受相关吗?", "你说卡牌中的两个主角,他们是什么关系?", "这张卡牌给你的第一印象是什么?", "卡牌中最吸引你注意力的是什么?" ], "深入探索": [ "我很好奇,你为什么会这样描述它?", "你注意到的这个细节,你觉得它是什么?从哪里来的?", "你觉得这个人在做什么?ta做这件事有什么感受?", "如果你能听到卡牌中的声音,会是什么?", "这个画面让你想起了什么回忆或经历?" ], "情境代入": [ "卡中人物处在什么环境中?环境对ta有什么影响?", "你在这个卡牌中吗?你是里面的谁?在做什么?感受如何?", "你的故事里,主角遭遇的事情,ta可以怎么解决?", "如果你是卡牌中的主角,你会选择什么行动?", "这个场景如果发生在你的生活中,会是什么样子?" ], "内心连接": [ "这张卡牌反映了你内心的哪个部分?", "卡牌中的情境与你当前的处境有什么相似之处?", "从这张卡牌中,你看到了什么解决问题的可能性?", "这张卡牌想告诉你什么重要的信息?", "如果这张卡牌是一面镜子,它照出了你的什么?" ], "启发行动": [ "这张卡牌给了你什么启发来处理你的困惑?", "根据卡牌的提示,你可以采取什么具体行动?", "这张卡牌如何帮助你看待当前的挑战?", "从卡牌中得到的洞察,你准备如何应用到生活中?", "这次抽卡体验让你对自己有了什么新的认识?" ] }; // 获取参数 const mode = getParamValue("mode") || "stdio"; const port = parseInt(getParamValue("port") || "9593"); const endpoint = getParamValue("endpoint") || "/rest"; // 创建服务器实例 const server = new Server({ name: "ohcard-cloud-mcp", version: "1.0.0", }, { capabilities: { tools: {}, }, }); // 定义工具 const WHAT_IS_OH_CARDS_TOOL = { name: "what_is_oh_cards", description: "介绍什么是OH卡", inputSchema: { type: "object", properties: {}, }, }; const GET_OH_CARD_PROCESS_TOOL = { name: "get_oh_card_process", description: "获取OH卡抽取流程", inputSchema: { type: "object", properties: {}, }, }; const DRAW_OH_CARD_TOOL = { name: "draw_oh_card", description: "抽取一张OH卡", inputSchema: { type: "object", properties: { intention: { type: "string", description: "用户的意图或想要探索的问题(可选)", }, }, }, }; const GET_GUIDANCE_QUESTIONS_TOOL = { name: "get_guidance_questions", description: "获取引导问题来帮助用户探索卡牌", inputSchema: { type: "object", properties: { question_type: { type: "string", description: "问题类型", enum: ["观察感受", "深入探索", "情境代入", "内心连接", "启发行动", "random"], }, }, }, }; const GET_ALL_QUESTION_TYPES_TOOL = { name: "get_all_question_types", description: "获取所有引导问题类型", inputSchema: { type: "object", properties: {}, }, }; const GET_ALL_CARDS_PREVIEW_TOOL = { name: "get_all_cards_preview", description: "获取所有OH卡的预览信息", inputSchema: { type: "object", properties: {}, }, }; // 注册工具列表处理器 server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ WHAT_IS_OH_CARDS_TOOL, GET_OH_CARD_PROCESS_TOOL, DRAW_OH_CARD_TOOL, GET_GUIDANCE_QUESTIONS_TOOL, GET_ALL_QUESTION_TYPES_TOOL, GET_ALL_CARDS_PREVIEW_TOOL, ], }; }); // 注册工具调用处理器 server.setRequestHandler(CallToolRequestSchema, async (request) => { try { const { name, arguments: args } = request.params; switch (name) { case "what_is_oh_cards": { const info = { title: "什么是OH卡?", description: "OH卡(Open Heart Cards)是一套心理投射工具,通过图像来帮助人们探索内心世界、获得洞察和启发。", features: [ "🎯 投射工具:通过图像投射内心状态", "🌟 自我探索:深入了解内在需求和感受", "💡 启发思考:从新角度看待问题和挑战", "🌈 情感表达:帮助表达难以言喻的感受", "🔮 直觉连接:激活内在智慧和直觉" ], principle: "OH卡的核心原理是'投射'——我们看到的不仅仅是图像本身,更是我们内心世界的反映。每个人对同一张卡的解读都是独特的,这正是它的魅力所在。", benefits: [ "获得新的视角和洞察", "释放内在智慧", "促进自我觉察", "激发创造性思维", "找到解决问题的灵感" ] }; return { content: [{ type: "text", text: JSON.stringify(info, null, 2) }], isError: false, }; } case "get_oh_card_process": { const process = { title: "OH卡抽取流程", subtitle: "跟随这5个步骤,开启一段内心探索之旅", steps: [ { step: 1, name: "确定心中的卡点", description: "思考你最近遇到的困惑或问题", guidance: "静下心来,想想最近让你困扰、迷茫或想要深入了解的事情。可以是情感问题、人际关系、工作选择、人生方向等任何让你感到需要指引的话题。", action: "在心中明确你想要探索的问题" }, { step: 2, name: "凝聚宇宙能量", description: "抽取你的OH卡", guidance: "带着你的问题,深呼吸几次,让自己的意识与宇宙能量连接。当你感到准备好时,抽取你的OH卡。相信直觉的指引,第一张抽到的卡就是为你而来的。", action: "使用'draw_oh_card'功能抽取你的专属卡牌" }, { step: 3, name: "问题引导", description: "让自己代入图片中", guidance: "仔细观察你的卡牌,让图像自然地与你的内心产生共鸣。不要急于分析,先感受图像给你带来的第一印象和情感反应。", action: "使用'get_guidance_questions'获取引导问题,帮助你深入探索" }, { step: 4, name: "寻找启发", description: "从图片与问题中找到解决卡点的启发", guidance: "通过回答引导问题,将卡牌的意象与你的真实处境连接起来。探索图像中的象征意义,寻找它对你问题的启示和指引。", action: "深入思考并回答引导问题,发现内在智慧" }, { step: 5, name: "完成体验", description: "拿走你的纪念卡", guidance: "总结这次抽卡体验给你的启发和洞察。记录下重要的感悟,并思考如何将这些洞察应用到你的实际生活中。", action: "保存卡牌信息作为纪念,让这份智慧伴随你前行" } ], tips: [ "💫 保持开放的心态,相信直觉的指引", "🌟 没有标准答案,你的感受最重要", "💭 慢慢来,给自己充分的时间感受", "📝 记录下重要的洞察和启发", "🔄 必要时可以重新抽卡,直到找到共鸣" ] }; return { content: [{ type: "text", text: JSON.stringify(process, null, 2) }], isError: false, }; } case "draw_oh_card": { const intention = args?.intention || ""; const cardId = Math.floor(Math.random() * 9) + 1; const card = OH_CARDS[cardId]; const result = { card_id: cardId, image_url: card.image_url, draw_time: "刚刚", message: `你的OH卡已经抽取完成!请点击查看图片:${card.image_url}`, guidance: "仔细观察这张卡牌,让图像与你的内心产生共鸣。你可以使用'get_guidance_questions'功能获取引导问题来深入探索。" }; if (intention) { result.user_intention = intention; result.connection_hint = `这张卡牌出现在你关于'${intention}'的询问中,请仔细观察图像,它可能包含了你需要的答案。`; } return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }], isError: false, }; } case "get_guidance_questions": { let questionType = args?.question_type || "random"; if (questionType === "random" || !(questionType in GUIDANCE_QUESTIONS)) { const types = Object.keys(GUIDANCE_QUESTIONS); questionType = types[Math.floor(Math.random() * types.length)]; } const questions = GUIDANCE_QUESTIONS[questionType]; const selectedQuestions = questions.sort(() => 0.5 - Math.random()).slice(0, 3); const typeDescriptions = { "观察感受": "帮助你观察卡牌并感受第一印象", "深入探索": "引导你深入挖掘卡牌的细节和含义", "情境代入": "让你融入卡牌情境,获得身临其境的体验", "内心连接": "建立卡牌与你内心世界的联系", "启发行动": "从卡牌中获得实际的生活指导" }; const guidance = { question_type: questionType, questions: selectedQuestions, usage_tip: "选择一个最吸引你的问题开始,慢慢地、深入地思考。不要急于回答所有问题,重要的是质量而非数量。", type_description: typeDescriptions[questionType] || "综合性问题", next_steps: [ "深入思考选中的问题", "可以使用'get_guidance_questions'获取其他类型的问题", "完成探索后可以记录你的感悟和洞察" ] }; return { content: [{ type: "text", text: JSON.stringify(guidance, null, 2) }], isError: false, }; } case "get_all_question_types": { const typesInfo = { title: "引导问题类型", description: "不同类型的问题帮助你从不同角度探索卡牌", types: [ { type: "观察感受", description: "帮助你观察卡牌并感受第一印象", purpose: "建立与卡牌的初始连接", example: "看到了什么?感受如何?" }, { type: "深入探索", description: "引导你深入挖掘卡牌的细节和含义", purpose: "发现更多隐藏的信息和象征", example: "你注意到的这个细节,你觉得它是什么?" }, { type: "情境代入", description: "让你融入卡牌情境,获得身临其境的体验", purpose: "通过角色扮演获得更深层的理解", example: "你在这个卡牌中吗?你是里面的谁?" }, { type: "内心连接", description: "建立卡牌与你内心世界的联系", purpose: "将卡牌与个人经历和感受连接", example: "这张卡牌反映了你内心的哪个部分?" }, { type: "启发行动", description: "从卡牌中获得实际的生活指导", purpose: "将洞察转化为具体的行动方案", example: "根据卡牌的提示,你可以采取什么具体行动?" } ], usage_tip: "建议按顺序进行:观察感受 → 深入探索 → 情境代入 → 内心连接 → 启发行动,这样能获得最完整的探索体验。" }; return { content: [{ type: "text", text: JSON.stringify(typesInfo, null, 2) }], isError: false, }; } case "get_all_cards_preview": { const cardsPreview = Object.entries(OH_CARDS).map(([cardId, cardData]) => ({ card_id: parseInt(cardId), image_url: cardData.image_url })); const previewInfo = { total_cards: cardsPreview.length, cards: cardsPreview, message: "这里是所有OH卡的图片链接。点击任意链接查看卡牌图片,但建议通过抽卡功能来获得更好的探索体验!" }; return { content: [{ type: "text", text: JSON.stringify(previewInfo, null, 2) }], isError: false, }; } default: throw new Error(`Unknown tool: ${name}`); } } catch (error) { return { content: [ { type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}`, }, ], isError: true, }; } }); /** * 启动服务器 */ async function runServer() { try { if (mode === "rest") { const transport = new RestServerTransport({ port, endpoint, }); await server.connect(transport); await transport.startServer(); console.error(`OH卡MCP服务器正在运行在REST模式,端口: ${port}, 端点: ${endpoint}`); } else { const transport = new StdioServerTransport(); await server.connect(transport); console.error("OH卡MCP服务器正在运行在stdio模式,提供OH卡抽取、引导问题等工具"); } } catch (error) { console.error("启动服务器时发生致命错误:", error); process.exit(1); } } // 启动服务器 runServer();