add-mcp-tool

GitHub

指导在MCP服务器中新增工具,涵盖实现、路由注册、目录同步及状态变更处理。确保路由器与目录一致,遵循内部函数调用规范,并遵守竞技模式的信息限制。

.claude/skills/add-mcp-tool/SKILL.md openfootmanager/openfootmanager

Trigger Scenarios

需要为MCP服务器添加新工具 修复MCP工具路由与目录不同步问题 调整MCP工具以符合竞技模式规则

Install

npx skills add openfootmanager/openfootmanager --skill add-mcp-tool -g -y
More Options

Non-standard path

npx skills add https://github.com/openfootmanager/openfootmanager/tree/develop/.claude/skills/add-mcp-tool -g -y

Use without installing

npx skills use openfootmanager/openfootmanager@add-mcp-tool

指定 Agent (Claude Code)

npx skills add openfootmanager/openfootmanager --skill add-mcp-tool -a claude-code -g -y

安装 repo 全部 skill

npx skills add openfootmanager/openfootmanager --all -g -y

预览 repo 内 skill

npx skills add openfootmanager/openfootmanager --list

SKILL.md

Frontmatter
{
    "name": "add-mcp-tool",
    "description": "Add a tool to the MCP server that lets AI agents play OpenFoot Manager. Follows the six-step checklist in tools.rs — route registration, catalog entry, implementation in the right tools_impl module, game-state-changed emission, competition-mode gating, and the docs\/MCP_SERVER.md tables.",
    "when_to_use": "Adding or changing an MCP tool, exposing an existing Tauri command to agents, or when a tool exists but help_find_tool cannot see it.",
    "allowed-tools": "Read, Edit, Write, Grep, Glob, Bash(cargo build*), Bash(cargo test*), Bash(cargo clippy*)",
    "argument-hint": "[tool name and what it does]"
}

Adding an MCP tool

The MCP server (src-tauri/src/mcp_server/, behind the mcp Cargo feature) lets AI agents play the game over JSON-RPC. It is used for agent competitions — see docs/MCP_SERVER.md.

The authoritative checklist lives in the code, at tool_catalog() in src-tauri/src/mcp_server/tools.rs. Read it; this skill expands on it.

The router and the catalog are two separate lists that must stay in sync. help_find_tool searches only the catalog, so a tool registered in the router but missing from the catalog works if an agent guesses its name and is otherwise invisible. The tools.rs tests every_routed_tool_is_in_the_catalog, every_catalogued_tool_has_a_route, duplicate-name and registration-parser checks enforce this when run with --lib --features mcp; they are not executed by a default-feature test run.


1. Implement it in the right tools_impl/ module

src-tauri/src/mcp_server/tools_impl/ — info.rs, time.rs, squad.rs, training.rs, transfers.rs, contracts.rs, inbox.rs, club.rs, scouting.rs, season.rs, game.rs, live_match.rs, help.rs. Shared helpers (require_game, user_team, …) are in helpers.rs.

Call the same _internal function the Tauri command calls. Never reimplement game logic here. If the behaviour has no _internal split yet, do that first — see /add-tauri-command. Check that the shared function is reachable in default and mcp builds; application code never imports MCP or commands. Apply the root Code quality limits and use /write-tests first.

Return text an agent can actually use. Tools return prose or JSON, not opaque ids: an agent reading info_standings should be able to act on it without a second call. Follow the formatting of the neighbouring tools in the module, and translate error keys through formatting.rs.

Respect competition-mode information limits. Full detail for the agent's own team; OVR, position, age, and condition only for other teams unless the player has been scouted. A new info_* tool that leaks opponent attributes silently breaks competition fairness.

2. Register the route

In build_tool_router() in tools.rs. Three macros cover most cases:

  • real_tool! — no parameters
  • id_tool! — one required string parameter (the schema key and the impl function's second parameter name must match)
  • custom_tool! — custom JSON schema plus custom extraction

Every registration is wrapped in a disabled.contains(…) check, which is how mode restrictions and --mcp-disable-tools work.

3. Add the catalog entry

tool_catalog() in the same file: (name, description, category). Use an existing category string exactly — a typo creates a phantom category in help_list_categories.

The description is what an agent reads when deciding whether to call the tool. Say what it does and when to use it.

4. Emit game-state-changed if it mutates

Any state-mutating tool must emit app.emit("game-state-changed", ()) via ctx.app_handle, so a GUI watching the agent play refreshes. Read-only tools must not.

5. Decide competition-mode visibility

If agents must not have this tool in a competition, add its name to the Competition arm of disabled_tools() in src-tauri/src/mcp_server/config.rs. Currently disabled there: game_new, game_select_team, game_export_world, game_exit, game_load_save — anything that would let an agent change its own starting conditions.

6. Update docs/MCP_SERVER.md

Add the row to the right category table and update the two counts in the header line ("N tools are available across M categories") and the per-category heading ("### Squad (7 tools)"). Stale counts are how this document rots.


Verify

Finish with /preflight for the full default and MCP gate set. These scoped commands use the same lockfile and warning policy; they do not replace the full preflight.

cargo build --locked --manifest-path src-tauri/Cargo.toml --features mcp
cargo clippy --locked --manifest-path src-tauri/Cargo.toml --workspace --all-targets --features mcp -- -D warnings
cargo test --locked --manifest-path src-tauri/Cargo.toml --workspace
cargo test --locked --manifest-path src-tauri/Cargo.toml --lib --features mcp

The mcp feature is not compiled by default, so a normal cargo check will not catch a mistake in this code. Build and test with --features mcp. Add one test per GWT scenario through the shared seam and adapter: wrapper equivalence, errors, competition gating and event emission. For persistence claims, read the saved database through a fresh reader; a returned clone does not prove a write. Use ofm-test-reviewer for regression effectiveness evidence.

End-to-end, against a running instance:

# tools/list — confirm the tool appears (and does NOT in competition mode if gated)
curl -X POST http://localhost:3001/mcp -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

# call it
curl -X POST http://localhost:3001/mcp -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"your_tool","arguments":{}}}'

docs/MCP_SERVER.md §"Quick Start" has the full launch command.


Checklist

  • Implementation in the right tools_impl/ module, calling the shared _internal function
  • Route registered in build_tool_router()
  • Entry added to tool_catalog() with an existing category string
  • game-state-changed emitted if and only if the tool mutates state
  • Competition-mode gating decided; config.rs disabled_tools() updated if needed
  • Information-visibility limits respected for other teams' players
  • docs/MCP_SERVER.md table row added and both tool counts updated
  • Builds and lints clean with --features mcp
  • Verified via tools/list and tools/call against a running instance

Version History

  • c3d8002 Current 2026-10-18 19:49

    更新测试说明:指出缺少自动检查机制的已修正(现通过代码测试强制执行);增加关于使用/write-tests和代码质量限制的指引。

  • 9d401d6 2026-07-30 22:45

Same Skill Collection

.claude/skills/add-domain-field/SKILL.md
.claude/skills/add-tauri-command/SKILL.md
.claude/skills/add-ui-string/SKILL.md
.claude/skills/new-ui-surface/SKILL.md
.claude/skills/preflight/SKILL.md
.claude/skills/refactor-to-rules/SKILL.md
.claude/skills/write-tests/SKILL.md

Metadata

Files
0
Version
c3d8002
Hash
d7dba856
Indexed
2026-07-30 22:45

홈 - 위키
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-10-24 20:27
浙ICP备14020137号-1