使用说明
FogBugz MCP服务器
一个模型上下文协议(MCP)服务器,允许 法典 与...互动 FogBugz 通过官方的XML API。服务器公开了用于搜索、审计和更新案例的精心策划的工具,这样代理就可以在FogBugz处理工作流程时留在Codex内部。
🧭 概述
服务器通过MCP stdio传输运行 @modelcontextprotocol/sdk。每个工具调用都经过框架、模式验证和记录,因此您可以在保持MCP客户端稳定的同时对FogBugz状态进行推理。该项目附带:
- 标准工具名称(
search_cases,case_events,view_case等等)映射到FogBugz XML命令。 - 降价帮助资源(
help)《食品法典》需要复习时可以阅读。 - 对出站FogBugz流量进行结构化日志记录,以简化调试。
⚙️ 设置
先决条件
- Node.js 20.x或更新版本 (ESM+undici是必需的)。
- npm(与Node一起提供)和
git. - 一个FogBugz帐户,可以访问您计划接触的项目。
- Codex已配置为从以下位置加载MCP服务器
~/.config/codex/config.toml.
1.推荐:通过 npx (不需要克隆)
这是Codex最简单的设置和推荐的方法。你做 不 需要在本地克隆仓库。
如果您更喜欢本地克隆进行开发,请参阅下面的“本地开发设置”部分。
2.选择要嵌入MCP配置中的值
Codex可以通过以下方式将环境变量直接传递给MCP过程 env = { ... } 在中定义的块 config.toml,所以你不需要 export 它们在你的壳里。确定以下值(但不要将其放在git/notes中):
| 变量 | 必填 | 描述 |
|---|---|---|
FOGBUGZ_BASE |
✅ | 完整的FogBugz API端点,例如。 https://example.fogbugz.com/api.asp. |
FOGBUGZ_TOKEN |
✅ | 具有读取/更新目标项目权限的个人API令牌。 |
FOGBUGZ_MCP_LOG_FILE |
可选 | JSON日志的文件路径(例如。 /tmp/fogbugz-mcp.log). |
FOGBUGZ_MCP_DEBUG |
可选 | 设置为 1 用于详细的请求/响应日志记录。 |
因为这些值最终会 config.toml,将该文件保存在版本控制之外(默认情况下,Codex将其存储在您的主目录下)。如果同步点文件,请先屏蔽或模板化令牌。
3.生成FogBugz令牌(每个用户一次)
- 在浏览器中登录FogBugz。
- 点击您的头像➜ 用户选项 (或 个人资料 取决于你的皮肤)。
- 打开 API令牌 然后单击 创建API令牌.
- 给令牌一个描述性标签(例如“Codex MCP”),并复制生成的值。
- 安全存储(密码管理器、操作系统钥匙链)并设置
FOGBUGZ_TOKEN在您的环境中。
为什么这么大惊小怪?FogBugz令牌授予与您的帐户相同的权限——将其视为密码,在有人离开团队时轮换使用,并且永远不要将其粘贴到支持票或提交历史记录中。
4.将服务器连接到Codex(推荐 npx 配置)
编辑 ~/.config/codex/config.toml (如果文件不存在,则创建该文件)并添加:
[mcp_servers.fogbugz]
type = "stdio"
command = "npx"
args = ["--yes", "-p", "github:dpupek/fogbugz-mcp", "fogbugz-mcp"]
startup_timeout_sec = 15
shutdown_timeout_sec = 5
tool_timeout_sec = 60
description = "FogBugz MCP server (search/view/create/edit/comment/attach/children/events)"
env = { "FOGBUGZ_BASE" = "https://example.fogbugz.com/api.asp", "FOGBUGZ_TOKEN" = "paste-your-token-here", "FOGBUGZ_MCP_LOG_FILE" = "/tmp/fogbugz-mcp.log", "FOGBUGZ_MCP_DEBUG" = "1"}
- 这将直接从GitHub安装并运行CLI;不需要本地路径。
- 要固定到标签(建议用于稳定性),请在repo后添加后缀
#<tag>例如:github:dpupek/fogbugz-mcp#v1.0.0github:dpupek/fogbugz-mcp#latest-release
- Codex在启动服务器时注入这些env变量,因此不需要全局导出它们;把这个街区当作私人秘密商店。
- 如果Codex报告握手超时,请提高
startup_timeout_sec稍微给Node更多的启动时间。 - env属性不能有换行符。
本地开发设置(可选)
如果你想在本地破解服务器:
macOS/Linux
mkdir -p ~/dev && cd ~/dev
git clone https://github.com/dpupek/fogbugz-mcp.git
cd fogbugz-mcp
npm install
chmod +x index.js
Windows(PowerShell)
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\dev" | Out-Null
Set-Location "$env:USERPROFILE\dev"
git clone https://github.com/dpupek/fogbugz-mcp.git
Set-Location fogbugz-mcp
npm install
Windows不需要 chmod +x。如果您使用WSL,请按照Linux步骤进行操作。
从本地克隆运行时,请使用:
command = "node"
args = ["/home/<you>/dev/fogbugz-mcp/index.js"]
5.烟雾测试运输
您可以在没有Codex的情况下对MCP握手进行健全性检查:
printf 'Content-Length: 57\r\n\r\n{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node index.js
您应该看到一个包含工具注册表的换行框架JSON响应。确认 help, search_cases,以及 case_events 出现。
🔎 FogBugz查询语法入门
大多数工具都依赖于FogBugz的搜索语法。亮点:
ixBug:207291按ID查找单个案例。assignedto:"Tier 2" status:active按所有者和状态筛选(空格用引号括起来)。project:"NexPort Solutions" opened:"this week"将项目筛选器与日期快捷方式混合使用。parent:207291或children:207291检索层次关系。outline:207291返回完整的后代树(whatcase_outline在引擎盖下使用)。- 使用
cols=请求额外的XML列(逗号分隔)。MCP服务器自动为每个工具添加安全默认值。 有关完整语法,请参阅FogBugz的“搜索语法”指南或运行fogbugz.help来自Codex的快速提醒。
🧰 MCP工具目录
| 工具 | 目的 | 关键论点和注释 |
|---|---|---|
help |
返回服务器附带的markdown帮助/食谱。 | 没有争论。当Codex需要入门文本时很有用。 |
version |
返回MCP服务器名称+版本。 | 没有争论。 |
health |
检查配置和FogBugz API连接。 | 没有争论。 |
search_cases |
运行任意FogBugz搜索。 | q (必填)加可选 cols。用于轻量级列表。 |
case_events |
与 search_cases 但迫使 events 列,这样您就可以获得完整的事件日志(可能非常大)。 |
审核对话或历史记录时非常理想。 |
view_case |
按ID提取一个案例,可选列;汽车包括 ixBug. |
论点: ixBug,可选 cols,可选 includeAttachments (添加 events 并用当前令牌重写附件URL)。 |
create_case |
创建一个新的FogBugz案例。支持父级/里程碑/类别和自定义 userStory 文本。 |
必填: title, ixProject.可选: event, ixArea, ixPersonAssignedTo, ixBugParent, ixFixFor, category, userStory, textType (plain, html, markdown). |
edit_case |
更新现有案例。您可以更改标题, userStory,或通过任何FogBugz XML字段 fields 地图。 |
必填: ixBug.可选: event, fields, title, userStory, textType (plain, html, markdown). |
add_comment |
在案例中添加评论/事件。 | ixBug, text,可选 textType (plain, html, markdown). |
add_comment_with_attachment |
在一次通话中添加评论并上传单个附件。 | ixBug, text, filename, contentBase64,可选 textType (plain, html, markdown). |
attach_file |
使用base64内容上传附件。 | ixBug, filename, contentBase64. |
list_children |
返回父案例及其子案例(ID、标题、受让人、时间戳)。 | ixBug (家长)。通过强制响应列来处理空ID。 |
case_outline |
使用FogBugz构建整个后代树 outline:<ixBug> 搜索。 |
ixBug (必填)加可选 cols.退货 outline (根)和 forest (所有顶级分支机构)。 |
resolve_case |
通过可选的结束语或字段编辑来解决案例。 | ixBug,可选 comment, fields, textType (plain, html, markdown). |
reactivate_case |
重新打开一个带有可选注释/字段有效载荷的案例。 | 与架构相同 resolve_case. |
list_categories |
枚举每个FogBugz类别和元数据(sCategory、工作流标志等)。 |
无争议;便于验证 category 你通过 create_case. |
list_areas |
列出未删除的区域(可选择按项目筛选)。 | ixProject 可选。在创建案例或编辑区域之前很有用。 |
list_status |
列出FogBugz状态(可选按类别/已解析状态过滤)。 | 可选: ixCategory, fResolved. |
view_status |
查看特定的FogBugz状态。 | 提供 ixStatus,或 sStatus + ixCategory. |
list_milestones |
列出里程碑(FixFors),可选择按项目筛选。 | 可选: ixProject. |
view_milestone |
查看特定里程碑(FixFor)。 | 必填: ixFixFor. |
create_milestone |
创建新的里程碑(FixFor)。 | 必填: ixProject, sFixFor.可选: dtStart, dtEnd. |
edit_milestone |
编辑现有里程碑(FixFor)。 | 必填: ixFixFor.可选: ixProject, sFixFor, dtStart, dtEnd, fAssignable, fDeleted, confirmDelete (删除时需要)。 |
add_milestone_dependency |
在里程碑之间添加依赖关系(FixFors)。 | 必填: ixFixFor, ixFixForDependsOn. |
remove_milestone_dependency |
删除里程碑之间的依赖关系(FixFors)。 | 必填: ixFixFor, ixFixForDependsOn. |
create_area |
在项目中创建新区域。 | 必填: ixProject, sArea.可选: ixPersonPrimaryContact. |
edit_area |
编辑现有区域。 | 必填: ixArea.可选: sArea, ixProject, ixPersonPrimaryContact. |
list_custom_fields |
返回为特定情况配置的自定义字段名称。 | ixBug 必修的。帮助发现字段键,如 plugin_customfields_at_fogcreek_com_*. |
list_columns |
返回案例列元数据(id, name, type, source)用于建筑 cols 安全。 |
可选: ixBug (发现案例范围的自定义字段), includeCustom (默认值 true), forceFallback (默认值 false).使用元数据API(如果可用),否则使用精心策划的回退。 |
case_link |
构建人类可以点击的FogBugz网络URL。 | ixBug 必修的;使用您的 FOGBUGZ_BASE 减 /api.asp 形成 https://.../f/cases/<ixBug>/. |
search_users |
通过缓存搜索人员 listPeople 内存中的结果包含匹配项。 |
可选: query (姓名/电子邮件子字符串), forceRefresh 绕过5分钟缓存。 |
示例 list_columns 响应:
{
"strategy": "fallback",
"coverage": "partial",
"ixBug": 207291,
"columns": [
{ "id": "ixBug", "name": "Case ID", "type": "ix", "source": "core" },
{ "id": "sTitle", "name": "Title", "type": "s", "source": "core" },
{
"id": "plugin_customfields_at_fogcreek_com_storypoints",
"name": "Story Points",
"type": "plugin_customfield",
"source": "custom"
}
],
"counts": { "total": 3, "core": 2, "custom": 1 },
"warnings": [
"Falling back to curated core columns because metadata commands were unavailable."
]
}
MCP呼叫有效载荷示例:
{
"name": "create_case",
"arguments": {
"title": "Transcript report totals look wrong",
"ixProject": 27,
"ixBugParent": 207291,
"category": "Engineering Task",
"userStory": "As a registrar..."
}
}
HTML富文本注释示例:
{
"name": "add_comment",
"arguments": {
"ixBug": 207291,
"textType": "html",
"text": "<p>Update:</p><ul><li>Item 1</li><li>Item 2</li></ul>"
}
}
Markdown富文本评论示例:
{
"name": "add_comment",
"arguments": {
"ixBug": 207291,
"textType": "markdown",
"text": "## Update\\n- Item 1\\n- Item 2"
}
}
userStory 映射到FogBugz自定义字段 plugin_customfields_at_fogcreek_com_userxstoryh815,因此您不需要记住原始XML名称。
🧪 工作流片段
- 搜索然后检查: 呼叫
search_cases随着q="ixBug:207291",拿到身份证,然后打电话view_case用于富集柱。 - 查询前发现列: 呼叫
list_columns第一(可选配ixBug)在组装之前获取有效的字段标识符和FogBugz-ish类型cols. - 完整审计跟踪: 使用
case_events随着cols="sTitle,events"将每个更改与事件代码一起流式传输(代码图例请参见FogBugz文档)。 - 创建+评论: 之后
create_case返回新ixBug,立即致电add_comment在Codex仍在记忆中时捕捉额外的上下文。 - 富文本HTML注释: 使用
add_comment随着textType="html"HTML在text(FogBugz将在以下情况下渲染它fRichText=1已设置)。 - 富格文本Markdown注释: 使用
add_comment随着textType="markdown"并在text(服务器在发送之前将其转换为HTML)。 - 层次结构审查:
list_children返回父回声和每个子回声ixBug,sTitle,sStatus,ixPersonAssignedTo,以及dtLastUpdated. - 史诗般的轮廓: 使用
case_outline拉动整个子代树(父级➜ 孩子➜ 在计划或批量编辑之前。
🩺 故障排除
| 症状 | 可能原因 | 修复 |
|---|---|---|
tools/list 返回零工具 |
缺少环境变量或注册前启动失败。 | 检查 /tmp/fogbugz-mcp.log 并确保 FOGBUGZ_BASE/FOGBUGZ_TOKEN 在Codex发布之前出口。 |
Unexpected response type 或 Transport closed 调用工具时 |
MCP帧不匹配,这是由崩溃或格式错误的FogBugz响应引起的。 | 检查故障工具的日志文件;手动运行它 node index.js 然后重新尝试 FOGBUGZ_MCP_DEBUG=1. |
| 持续心跳但Codex超时 | 服务器从未收到 initialize 因为Codex无法从stdio读取。 |
确认stdin/stdout未被重定向,并且没有其他进程绑定到同一命令。 |
Invalid 'tools[n].name' 错误 |
工具名称包含点/别名。 | 坚持使用上面列出的规范名称;别名已被删除。 |
附件或 case_events 截断 |
大型有效载荷可能会达到FogBugz或Codex的限制。 | 缩小你的 q 过滤,请求更少的列,或避免事件繁重的情况,除非需要。 |
🔒 安全说明
- 令牌继承您的FogBugz权限。将它们存储在env变量或操作系统密钥链中,而不是git、Codex转录本或屏幕截图中。
- 在离开共享计算机后立即定期旋转令牌。
- 日志文件可以捕获请求URL(如果您错误配置了基本URL,则包括令牌)。将它们保存在受信任的磁盘上,并在共享前进行编辑。
- 如果您必须共享日志,请删除案例内容以避免泄露客户数据。
📜 许可证
MIT(或内部使用)。如果公开分发,请更新。
👤 维护者
Daniel Pupek-股份有限公司高级系统技术首席系统和软件架构师。
