# Using it from an MCP client (agents)
> **TL;DR.** The MCP server exposes the same engine to AI agents as nine tools:
> `format_tool`, `upgrade_tool`, `check_tool`, `convert_help_tool`,
> `tokenize_version_tool`, `find_references_tool`, `rename_param_tool`,
> `list_rulesets`, `list_rules`, over a thin FastMCP binding. Tools take the tool
> XML as a string and return JSON; nothing is written to disk. This is vision Goal 1,
> and it ships today.
## The nine tools
| Tool | Input | Returns |
|---|---|---|
| `format_tool` | `xml`, optional `rulesets`/`select`/`ignore` | canonical XML + advisory notes |
| `upgrade_tool` | `xml`, optional `select`/`ignore`, `modernize`, `allow_behavior_change`, `block_consider`, `target_profile` | upgraded XML, steps, `behavior_preserving`, `baseline_profile`/`reached_profile`, `stopped_at`, `blocking_codes`, `auto_fixed_codes`, notes |
| `check_tool` | `xml`, optional `rulesets`/`select`/`ignore` | report-only findings (never mutates) |
| `convert_help_tool` | `xml` | `{converted, formatted, skip_reason}`, opt-in RST→Markdown help conversion; a skip (e.g. "profile below 24.2, run `upgrade` first") is a normal result an agent can act on |
| `tokenize_version_tool` | `xml` | `{tokenized, formatted, skip_reason}`, opt-in @TOOL_VERSION@ extraction (expansion-equality gated); macro-importing tools fail closed (content-based, use the path-based CLI for those) |
| `find_references_tool` | `xml`, `name` | `{name, occurrences: [{section, sourceline, reference}]}`, read-only; this tool's own templated sections (imported-macro references are the path-based CLI) |
| `rename_param_tool` | `xml`, `old`, `new` | `{old, new, changed, renamed, reason, formatted}`, atomic single-document rename; `formatted` is `null` on a bail (the cross-file/imported-macro rename is the path-based CLI) |
| `list_rulesets` | (none) | the baked-in rulesets (name / codes / default / description) |
| `list_rules` | optional `include_upgrade` | every rule (code / family / fixable / rulesets / cite) |
Selection mirrors the CLI and library: `rulesets` is a list whose names ∈
{`cosmetic`, `default`, `iuc`, `strict`} (their union is the base set), plus
`select` / `ignore` code lists (precedence `ignore` ▸ `select` ▸ `rulesets`).
`upgrade_tool` takes no ruleset; it's semantic.
## Shape of a call
An agent passes the XML in and gets structured JSON back, e.g. `check_tool`:
```text
// check_tool(xml="…", rulesets=["strict"])
{
"violations": [
{"code": "GTR001", "sourceline": 1, "xpath": "/tool/command",
"message": "Canonical 4-space indentation; no tabs.", "advisory": false},
{"code": "GTR025", "sourceline": 1, "xpath": "/tool",
"message": "Tool should declare .", "advisory": true}
]
}
```
Each finding carries `advisory` (`false` = a fixable rule, `true` = a report-only
best-practice check).
`format_tool` returns the canonical XML; `upgrade_tool` returns the upgraded XML plus
`behavior_preserving` (`true`/`false`/`null`), `baseline_profile`/`reached_profile`,
`stopped_at`, `blocking_codes`, and `auto_fixed_codes`. The default is
**minimal-bump for agents too**: `profile=` moves only when strictly needed for
validity, modernizing requires passing `modernize=true` explicitly, crossing
the modernize walk's behaviour ceiling additionally requires
`allow_behavior_change=true`, and the walk never passes the deployment ceiling
(the newest profile every major public Galaxy server runs) without an explicit
`target_profile`; an unattended behaviour change, or a profile no server can
install, is worse, not better. The blocking codes map to sections of
[`docs/profile_boundaries.md`](https://github.com/richard-burhans/galaxy-tool-refactor/blob/main/docs/profile_boundaries.md), so an agent can read
exactly what changed and decide deliberately; see [soundness](../soundness.md).
## An example per tool
Calls and responses are real, trimmed; the same demo tool drives them
(`demo --in $input --out $output`, an integer `1.0+galaxy0`
version, an RST ``). `check_tool` is shown above.
Fix & upgrade: format_tool, upgrade_tool
```text
// format_tool(xml="…$input…$output…")
{"formatted": "……",
"advisory": [], "notes": []} // file vars quoted, body CDATA-wrapped, indented
// upgrade_tool(xml="…")
{"formatted": "…", "baseline_profile": "24.2", "reached_profile": "24.2",
"steps_applied": [], "behavior_preserving": true, "stopped_at": null,
"blocking_codes": [], "auto_fixed_codes": [], "notes": []}
```
Opt-in: convert_help_tool, tokenize_version_tool
```text
// convert_help_tool(xml="……")
{"converted": true,
"formatted": "……",
"skip_reason": null} // skip_reason is set (and converted=false) when not render-equivalent
// tokenize_version_tool(xml="…version=\"1.0+galaxy0\"…1.0…")
{"tokenized": true,
"formatted": "…version=\"@TOOL_VERSION@+galaxy@VERSION_SUFFIX@\"…1.0…",
"skip_reason": null}
```
Query & rename: find_references_tool, rename_param_tool
```text
// find_references_tool(xml="…", name="input")
{"name": "input", "occurrences": [{"section": "command", "sourceline": 1, "reference": "$input"}]}
// rename_param_tool(xml="…", old="input", new="reads")
{"old": "input", "new": "reads", "changed": true, "renamed": 2, "reason": null,
"formatted": "…demo --in $reads --out $output…
Introspect: list_rulesets, list_rules
```text
// list_rulesets()
[{"name": "cosmetic", "codes": ["GTR001", "GTR004"], "is_default": false, "description": "…"},
{"name": "default", "codes": ["GTR001", "GTR002", "…"], "is_default": true, "description": "…"}, …]
// list_rules() (optional include_upgrade=true adds the upgrade-only codemods)
[{"code": "GTR001", "summary": "Canonical 4-space indentation; no tabs.", "family": "fmt",
"fixable": true, "rulesets": ["cosmetic", "default", "iuc", "strict"],
"planemo_linters": [], "since": "0.0.1", "cite": "https://…"}, …]
```
## Why it's a thin adapter
The MCP server (`server.py`) is a FastMCP binding over a protocol-agnostic adapter
(`service.py`) that turns the registry facade's structured results into JSON. The
facade does the work; the server just maps errors (`UnknownRuleset`,
`UnknownRuleCode`, syntax errors) to agent-facing messages. Same engine as the CLI.
What's not here yet
Agents *calling* the tools is shipped. Agents *authoring their own rules* (new
codemods/checks discovered and run alongside the baked-in set) is vision **Goal 2**:
open design, not built. See `galaxy-tool-refactor-mcp/docs/vision.md` and the
[leverage map](../leverage.md).