1. 为什么要在 Electron 里给 Next AI Draw.io 接 MCP Server
Next AI Draw.io 是一个把自然语言转成 draw.io 图表的开源项目,核心链路是「聊天输入 → 模型生成 mxCell XML → 前端渲染到 draw.io 画布」。它同时提供 Web 版和 Electron 桌面版,桌面版通过启动 Next.js standalone 服务器再套一层原生窗口来运行。MCP Server 则是它对外暴露能力的另一条通道,让 Claude Desktop、Cursor 这类支持 MCP 的客户端可以直接调用 display_diagram、edit_diagram 等工具去操作图表。
问题出在模型服务这一层。Next AI Draw.io 默认走的是 Amazon Bedrock,也支持 OpenAI、Anthropic 等 11 种提供商,但每一种都要单独填 apiKey、baseURL、modelId,桌面端还要把这些密钥塞进 OS keychain。对只想在本地跑通 AI 绘图的人来说,配置成本偏高,而且不同提供商之间的参数差异(比如 Anthropic 的 thinkingBudgetTokens、OpenAI 推理模型的 reasoningSummary)很容易配错。
TaoToken 在这里扮演的角色是统一入口:一个 Key、一个 API 通道,同时兼容 OpenAI 和 Anthropic 两种协议风格。你不需要为每个提供商单独申请账号,只要把 baseURL 指向 TaoToken 的 API 地址,模型名按它的命名规则填,Next AI Draw.io 的多提供商抽象层就能直接复用。这篇就聚焦 Electron 桌面端接入 MCP Server 的工程链路,把 settings.json 和 config.toml 里的配置骨架拆开讲,给出可以直接复制的片段和连通性验证动作。
适合谁看:已经在本地跑起 Next AI Draw.io、想换成统一 Key 的人;想用 MCP Server 让 Cursor 或 Claude Desktop 直接画图的人;以及想搞清楚 Electron 主进程、Next.js 服务、MCP Server 三者配置怎么对齐的人。
2. TaoToken 前置:Key、通道与三个配置文件的关系
在动手改配置之前,先把三个东西的位置理清楚,不然后面会反复找不到该改哪个文件。
第一个是 TaoToken 的 API Key。登录后在控制台创建,格式通常是一串以特定前缀开头的字符串。这个 Key 同时能用于 OpenAI 兼容接口和 Anthropic 兼容接口,区别只在请求路径和请求头。创建入口在控制台的 API Keys 页面,建议单独建一个给 Next AI Draw.io 用,方便后面按项目排查额度。
第二个是 API 通道地址。TaoToken 的 API 根地址是https://taotoken.net/api,注意这里不带任何查询参数。OpenAI 兼容的对话补全路径是/v1/chat/completions,Anthropic 兼容的消息路径是/v1/messages。Next AI Draw.io 的lib/ai-providers.ts里用createOpenAI({ apiKey, baseURL })和createAnthropic({ apiKey, baseURL })分别创建实例,所以 baseURL 填到/api这一层就够了,SDK 会自己拼后面的路径。
第三个是三个配置文件的分工,这是最容易搞混的地方:
| 文件 | 位置 | 作用 | 谁读它 |
|---|---|---|---|
| settings.json | Electron userData 目录 | 桌面端持久化提供商、模型、Key 引用 | Electron 主进程 |
| config.toml | MCP Server 工作目录 | MCP Server 启动参数与工具开关 | MCP Server 进程 |
| .env.local | 项目根目录 | Next.js 服务端环境变量兜底 | Next.js API Route |
Electron 版启动时会先拉起 Next.js standalone 服务器,再创建窗口。模型配置的优先级是「客户端 overrides(localStorage)> 环境变量 > 默认值」,而桌面端会把用户在设置面板里填的内容写进 settings.json,同时通过 IPC 把 Key 存进 OS keychain。MCP Server 是独立进程,它不读 settings.json,只认自己的 config.toml 和启动时注入的环境变量。所以你要做的是让这三处的 baseURL 和模型名保持一致,Key 可以复用同一个。
注意:不要把 Key 硬编码进 config.toml 后提交到 Git。MCP Server 支持从环境变量读取,优先用环境变量注入。
3. 可复制配置:settings.json 与 config.toml 骨架
先给 Electron 端的 settings.json。这个文件在 Windows 下位于%APPDATA%/next-ai-draw-io/settings.json,macOS 下位于~/Library/Application Support/next-ai-draw-io/settings.json。如果你还没跑过一次应用,目录可能不存在,先启动一次让它生成,再关掉编辑。
{ "provider": "openai", "modelId": "gpt-4o", "baseURL": "https://taotoken.net/api", "apiKeyRef": "taotoken-default", "useKeychain": true, "mcp": { "enabled": true, "serverCommand": "node", "serverArgs": ["./packages/mcp-server/dist/index.js"], "transport": "stdio" }, "providers": { "openai": { "baseURL": "https://taotoken.net/api", "modelId": "gpt-4o" }, "anthropic": { "baseURL": "https://taotoken.net/api", "modelId": "claude-3-5-sonnet-20241022", "headers": { "anthropic-beta": "prompt-caching-2024-07-31" } } } }几个字段说明一下。provider决定走哪条分支,openai和anthropic都指向同一个 baseURL,区别在 SDK 内部拼的路径。apiKeyRef是 keychain 里的条目名,真正的 Key 不落在这个 JSON 里,而是通过 Electron 的 safeStorage 加密后存进系统钥匙串。mcp.transport用stdio,因为 MCP Server 是本地子进程,走标准输入输出最省事。
再给 MCP Server 的 config.toml。放在你启动 MCP Server 时的工作目录,通常是项目根目录或者packages/mcp-server/下:
[server] name = "next-ai-drawio" version = "0.1.2" transport = "stdio" [model] provider = "openai" base_url = "https://taotoken.net/api" model_id = "gpt-4o" api_key_env = "TAOTOKEN_API_KEY" [tools] display_diagram = true edit_diagram = true append_diagram = true get_shape_library = true [limits] max_xml_size = 1048576 max_file_size = 2097152 max_file_count = 5api_key_env是关键,它告诉 MCP Server 从环境变量TAOTOKEN_API_KEY读 Key,而不是写在文件里。max_xml_size对应源码里validateAndFixXml的 1MB 限制,改大之前先确认 draw.io 渲染端扛得住。
最后是 Next.js 服务端的.env.local,作为兜底:
AI_PROVIDER=openai AI_MODEL=gpt-4o OPENAI_API_KEY=你的TaoTokenKey OPENAI_BASE_URL=https://taotoken.net/api ANTHROPIC_API_KEY=你的TaoTokenKey ANTHROPIC_BASE_URL=https://taotoken.net/api三处 baseURL 完全一致,模型名按你实际要用的填。这样无论请求从 Electron 主进程、Next.js API Route 还是 MCP Server 发出,最终都打到同一个通道。
4. 验证请求:从 curl 到 MCP 工具调用
配置写完不能直接开应用,先分层验证,出问题好定位。
第一步,验证 TaoToken 通道本身通不通。用 curl 打一次 OpenAI 兼容的对话补全:
curl -s https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o", "messages": [{"role": "user", "content": "只回复 ok"}], "max_tokens": 16 }'返回体里choices[0].message.content应该是ok。如果返回 401,检查 Key 有没有带 Bearer 前缀;返回 404,检查 baseURL 是不是多写或少写了/v1。
第二步,验证 Anthropic 兼容路径。Next AI Draw.io 在 Anthropic 分支下会带anthropic-beta头,所以单独测一次:
curl -s https://taotoken.net/api/v1/messages \ -H "x-api-key: $TAOTOKEN_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-3-5-sonnet-20241022", "max_tokens": 16, "messages": [{"role": "user", "content": "只回复 ok"}] }'注意 Anthropic 协议用的是x-api-key头而不是Authorization,这是两条通道最容易配错的地方。
第三步,验证 MCP Server 能起来并列出工具。先导出环境变量再启动:
export TAOTOKEN_API_KEY=你的Key node ./packages/mcp-server/dist/index.jsMCP Server 走 stdio,启动后不会打印欢迎信息,你需要用 MCP 客户端连它。最快的办法是在 Cursor 或 Claude Desktop 的 MCP 配置里加一段:
{ "mcpServers": { "next-ai-drawio": { "command": "node", "args": ["./packages/mcp-server/dist/index.js"], "env": { "TAOTOKEN_API_KEY": "你的Key" } } } }连上后客户端会发ListToolsRequest,你应该能看到 display_diagram、edit_diagram、append_diagram、get_shape_library 四个工具。如果只看到部分,回去检查 config.toml 里[tools]段是不是把某个设成了 false。
第四步,端到端验证。在 Electron 应用里输入「画一个三节点的流程图」,观察两件事:聊天面板是否流式返回文本,画布是否出现 mxCell 渲染的图形。如果文本出来了但画布没动,问题在 XML 处理层,不是模型通道。
5. 本篇常见错排查
报错一:XML was truncated反复出现。这是isMxCellXmlComplete判定当前 XML 不完整,工具返回了 output-error,让模型改用 append_diagram 续写。如果你用的是输出长度受限的模型,很容易触发。解决办法是把max_tokens调大,或者在系统提示词里明确要求「单次生成的 mxCell 不超过 30 个」。别去改isMxCellXmlComplete的正则,那个逻辑是对的,改了反而会让残缺 XML 进画布。
报错二:401 Unauthorized但 curl 能通。大概率是 Electron 的 keychain 里存的还是旧 Key。settings.json 里的apiKeyRef指向的条目没更新,应用读的是钥匙串里的旧值。删掉对应条目重新在设置面板填一次,或者临时把useKeychain设为 false 走环境变量验证。
报错三:MCP Server 连上但工具调用超时。检查 config.toml 的base_url有没有写成带/v1的完整路径。MCP Server 内部用的 SDK 会自己拼/v1/messages或/v1/chat/completions,你多写一层就变成/v1/v1/...,请求直接 404,客户端等不到响应就超时。
报错四:Electron 启动后白屏,控制台报 Next.js 服务器起不来。生产环境下 Electron 会调startNextServer()拉起 standalone 服务器,如果端口被占用或者.next/standalone目录缺失就会失败。先确认npm run build生成过 standalone 产物,再检查 3000 端口有没有被别的进程占着。
报错五:切换 provider 后模型名不生效。配置优先级是客户端 overrides > 环境变量 > 默认值。你在 settings.json 里改了provider为 anthropic,但 localStorage 里还留着之前选的 openai,客户端 overrides 会盖掉文件配置。清一下浏览器 localStorage 里的next-ai-draw-io-*键,或者在设置面板里重新选一次。
报错六:XML too large抛异常。生成的图表节点太多,超过了 1MB 上限。这种图本来也不适合一次性渲染,拆成多个子图,或者让模型用 edit_diagram 增量添加节点,而不是 display_diagram 全量生成。
6. 配置骨架跑通之后
把上面三处配置对齐、四步验证走完,Next AI Draw.io 的 Electron 端和 MCP Server 就都指向了同一个 TaoToken 通道。这时候你可以做两件延伸的事:一是把 MCP Server 挂到长期编码环境里,让 Cursor 在写代码时顺手画架构图;二是把模型换成更适合结构化输出的型号,观察 mxCell 生成的成功率变化。
如果你还没创建 Key,去控制台建一个专用于这个项目的:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=api_keys
想先不写代码、直接在网页里试模型对 draw.io XML 的理解能力,用模型对话页最快:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=model_chat
打算把 MCP Server 长期挂在 Cursor 或 Claude Desktop 里做日常绘图,Coding Plan 的额度模型更适合这种高频调用:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=coding_plan
接入过程中如果遇到 SDK 参数对不上的情况,接入文档里有各协议的请求示例:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=doc
最后留一个我踩过的坑:config.toml 里的api_key_env名字要和你在 MCP 客户端配置里env段写的键名完全一致,大小写敏感。我一开始写成TAOTOKEN_KEY,客户端里写的是TAOTOKEN_API_KEY,MCP Server 读不到值,工具调用全部返回空,排查了半小时才发现是名字对不上。