Repository navigation
Split IcTools into IcCanisterTools and IcProtocolTools - #157
Merged
aterga merged 34 commits intoAug 27, 2026
Merged
Conversation
Marketplace directories (Anthropic, OpenAI) prohibit connectors that initiate or execute money or crypto transfers on the user's behalf, and this server's purpose is reading, building, and operating canisters — not moving funds. canister_update_call now refuses the update methods that move value or grant spending rights on ICP ledgers, on every canister, before any network work. The disallow list leans on the ICRC standards that ledgers on ICP follow — ICRC-1/ICRC-2 (fungible transfers and approvals), ICRC-4 (batch transfers), ICRC-7/ICRC-37 (NFT transfers and approvals) — plus the ICP ledger's pre-ICRC surface (transfer, send_dfx, notify_dfx), the cycles ledger's withdraw/withdraw_from, and the ERC-20-style names of the older DIP20/EXT token standards (transferFrom, approve). Matching is exact on a normalized name (lowercased, separators stripped), never a substring test, so spelling variants are caught without false positives on names that merely contain a blocked one. The refusal is a recommendation, not a dead end: it tells the agent to send the user to a wallet or frontend they control in their own browser (e.g. https://oisy.com; for governance, the NNS dapp). The tool description states the policy up front — financial transactions are not supported, for marketplace compliance and user safety — and a test pins both the description and the refusal wording. The CMC's notify_create_canister / notify_top_up stay callable: they move no funds out of any account and blocking them would strand the documented recovery path for an interrupted ICP funding flow. The module docs are explicit that a name-based list is a guardrail for the standardized ledger surface, not a hermetic seal over bespoke canisters. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
…tions The marketplace-compliance posture (top-up instructions-only, ledger transfer/approval methods refused) needs the surrounding material to say the same thing: this MCP server is infrastructure tooling and is not intended for financial operations. - README: a 'Not for financial operations' statement up front; the skills enumeration drops DeFi; DEX-app names (MULTI/DEX, ICPSwap) in examples give way to neutral ones (NNS, Oisy), with the known-app registry and its wrong-TLD repair behavior unchanged in code. - Tool descriptions and server instructions: same example cleanup, plus a NOT FOR FINANCIAL OPERATIONS paragraph in the server instructions that tells agents to send users to a wallet they control (oisy.com) for such operations. - Landing page (src/assets/index.html bundle): the wallet-balance chat mock becomes an app-data read, the portfolio/DEX example prompts become neutral app examples, the tool-group copy stops claiming server-side top-ups, and the trust section gains a 'Not for financial operations' card. Only the embedded template changed; decoded-value equality is asserted around the re-encode. - Cargo.toml: drop the cryptography::cryptocurrencies crates.io category — network/api tooling categories remain. - Directory-submission docs: the financial-transactions blockers now record the shipped posture (instructions-only top-up, ledger-method refusals, stated policy) and keep the honest caveats: the icp_create_canister icp path still executes an ICP-to-cycles conversion and needs an explicit decision, and a name-based guard covers the standardized ledger surface, not bespoke canisters. The listing description draft and reviewer instructions match the new behavior. Factual technical references to ledgers (reading a ledger is a public Candid query) and the ckUSDC lookup examples stay: identifying what a canister is remains core, non-financial functionality. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
…view) Address the Copilot review on the ledger-method guard: - The cycles ledger's create_canister / create_canister_from draw cycles from the caller's balance through the exact generic route this guard closes (withdraw was already blocked for that reason), so they join the disallow list. Their refusal redirects to the purpose-built icp_create_canister tool (or the icp CLI) rather than to a wallet — creation stays supported, only the uncontrolled generic route closes. - The absolute 'this server does not move financial assets' wording in the tool description and the refusal message is scoped to 'this tool': precise on this branch standalone (icp_create_canister still funds at creation) and after the companion top-up change merges. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
…iew) Address the reviews on the framing cleanup: - Per author feedback, Oisy (also a DeFi app) stops serving as the neutral usage example: name examples use NNS (the registry app that fits), and URL / bare-host examples use https://opencloud.org — live and IC-served (x-ic-canister-id present), so it passes the IC-evidence gate as documented. Oisy remains only where a wallet is genuinely meant: the refusal recommendation for financial operations. - The absolute 'never moves money or tokens' claims flagged by the review bot become enforcement-scoped statements: README, the landing trust card, and the server instructions now say token transfers, approvals, payments, and trades ARE REFUSED (via the update-call guard and the instructions-only top-up) and disclose that creating and funding the user's own canisters remains available through icp_create_canister. - The OpenAI submission doc presents the shipped changes as mitigations toward a still-pending attestation decision (the icp_create_canister funding path and the bespoke-method limitation are named as the open counterexamples), not as grounds to check the box. The Anthropic doc's 'shipped' section is phrased against the PR set (#153/#154) it describes rather than any single branch's tree. This PR is documentation/framing for the enforcement #153 and #154 ship; merge order remains #153, #154, then this. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
…iew) The review bot's follow-up is right that a method deny-list cannot make the generic update tool UNABLE to move assets — a bespoke method name is out of any list's reach, which the module docs and submission docs already record. The description and refusal therefore stop claiming impossibility: they state the binding policy (moving financial assets through this tool is not supported and must not be attempted under any method name) alongside what is mechanically enforced (the standardized ledger surface is refused on every canister). Whether to go further — dropping the generic update surface or moving to a reviewed allow-list — is the recorded 'directory-safe profile' option and stays a product decision, not something this PR takes on its own. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
…iew)
Second review pass on the framing: every remaining absolute 'X is
refused' claim is reworded to the stable formula the guard actually
supports — financial operations are unsupported BY POLICY, and the
STANDARDIZED ledger surface is refused mechanically. Applied to the
README statement, the server instructions (which now also tell the
model never to attempt a financial operation through any other method
or route), and the landing trust card ('standard ledger transfers and
token approvals are refused by design'). The Anthropic readiness row
for the read-only tool count is marked pending on the top-up PR rather
than verified.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
…e-compliance-vpawel-2-ledger-guard # Conflicts: # crates/imcp2-core/src/tools.rs
…' into claude/icp-marketplace-compliance-vpawel-3-definancialize
The framing PR now contains the enforcement it describes: main (with the merged instructions-only top-up, #153) and the ledger-method guard branch (#154) are merged in, and the PR is retargeted onto #154's branch so it cannot merge ahead of it — the ordering the review kept flagging is now mechanical rather than a note in the description. The Anthropic readiness row flips to verified since #153 is merged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
Per author direction on the PR: no web system can tell from the outside whether a given request moves funds, so the honest claim is intention, not capability. The description now reads 'not intended for moving money, tokens, or other financial assets on the user's behalf' with the ledger-method refusals presented as the reasonable measures taken to refuse asset-moving requests; the refusal message matches, and the description test pins the new header phrase. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
The pasted marketplace copy and the reviewer test instruction now match the settled framing: the connector is not INTENDED for financial transactions, and the STANDARDIZED token-ledger transfer/approval methods are refused as the safety measure — neither line claims the guard catches more than it does. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
Per author feedback: tokens are only valuable if they can be exchanged or used, and the ICP ecosystem's financial platforms (wallets like Oisy, exchanges like ICP Swap) integrate ledgers through the ICRC standards — a token on a bespoke, non-standard ledger can exist, but the ecosystem's platforms cannot hold or trade it, so it carries little exchangeable value. Also syncs the quoted policy wording in the same note with the intent framing the description now uses. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
…e-compliance-vpawel-2-ledger-guard # Conflicts: # crates/imcp2-core/src/tools.rs
…' into claude/icp-marketplace-compliance-vpawel-3-definancialize
Per review: normalization was both too loose and unnecessary. The guard now has two groups. ICRC-standard methods (icrc1_transfer, icrc2_*, the ICRC-4/-7/-37 equivalents) are matched literally on every canister — the standards fix the exact names and Candid method names are case-sensitive, so a differently-spelled name is not the standard method and could never reach it on chain. Abstract names (transfer, send_dfx, notify_dfx, withdraw, withdraw_from, create_canister, create_canister_from) are refused only on the specific system canister where they are financial — the ICP ledger and the cycles ledger by canister id — so an app whose own transfer or withdraw is non-financial keeps working. The legacy DIP20/EXT names on arbitrary canisters (transfer, transferFrom, approve) are deliberately no longer matched: too abstract to block everywhere without breaking non-financial apps, per review, and those standards sit outside the ecosystem's ICRC-integrated platforms; the stated policy covers them. Tests pin literal matching, the per-ledger scoping in both directions, and the unchanged refusal contract; the tool description and README describe the scoped behavior. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
…' into claude/icp-marketplace-compliance-vpawel-3-definancialize
The submission record now matches the restructured guard: ICRC-standard methods refused on every canister, and the ICP/cycles ledgers' own value-moving methods refused on those ledgers, rather than a blanket every-canister claim for the whole set. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
Per review: recommending icp_create_canister inside the refusal reads as this server supporting canister creation on the user's behalf, which is not what the refusal should communicate. The cycles-ledger create_canister / create_canister_from refusal now points the user at running the operation themselves with the icp CLI (with the install pointer), like every other refusal points at a user-controlled venue. README row updated to match; the test now pins that the refusal names the CLI and never the connector tool. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
…' into claude/icp-marketplace-compliance-vpawel-3-definancialize Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
Per review, three changes to how the policy is stated: - The policy paragraph moves out of canister_update_call's description into the server-level get_info instructions (now a SERVER_INSTRUCTIONS const so the test can pin it): a policy block inside the tool's own description reads as a hint that the tool is usable for financial transactions. The description is purely functional again. - The wording drops the marketplace/compliance rationale and the 'reasonable measures' hedge: it now simply states that financial transactions are not supported and asset-moving requests are denied, to protect the user. - The refusal message loses the 'do not route under another method name' sentence, which read as a hint that the guards could be bypassed. README row aligned; tests updated to pin the description staying free of financial language and the instructions carrying the policy. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
…' into claude/icp-marketplace-compliance-vpawel-3-definancialize The two financial-policy paragraphs in the server instructions become one: the plain protective wording from the ledger-guard branch supersedes this branch's earlier paragraph (per review — no marketplace/compliance rationale, no bypass-hinting sentence; the top-up and creation facts it carried are already stated in the canister-management paragraph). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
The policy now lives in the server-level instructions rather than the canister_update_call description (which stays free of financial language), the refusal points a canister-creation spend at the user-run icp CLI, and the public surfaces say financial transactions are not supported. Update the mitigation descriptions in both submission docs to match, and describe the per-ledger scoping in the Anthropic doc's bullet. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
Per maintainer review across the compliance PRs: creating and funding a canister spends the user's ICP or cycles, so the connector must not execute it. icp_create_canister now works exactly like the top-up tool (#153): it returns the icp CLI steps for the user to run themselves — install the CLI, check/mint cycles, icp canister create, and finally add the connector's management principal (printed by icp_cycles_balance) as a controller so icp_install_code and the lifecycle tools can operate the new canister. The executing paths are removed from the binary: the ICP-ledger transfer to the CMC, notify_create_canister, and the cycles-ledger create_canister call, with their wire types and helpers. With this, no tool initiates or executes a transfer of the user's funds: the server-wide 'asset-moving requests are denied' instruction now has no executing counterexample. The compliance refusal for cycles-ledger creation spends may name icp_create_canister again — it prints steps and executes nothing — and the CMC notify_* methods stay callable as the recovery path for a user's own interrupted CLI mint. README and server instructions updated; tests moved to pin the instructions-only contract (annotations, description, echoed amounts, controller handover step). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
…' into claude/icp-marketplace-compliance-vpawel-3-definancialize
…e docs Merge branch 'claude/icp-marketplace-compliance-vpawel-2-ledger-guard' (icp_create_canister is now instructions-only) and apply the review sweep on this branch's surfaces: - NNS is no longer used as an example app or venue anywhere agent-facing or in the README/landing page (per review: it can hold funds). The functional pieces stay — the known-app registry, derivation-origin map, security guardrails, and dashboard status lines. - The README intro now says creation, like top-up, returns icp CLI instructions for the user to run themselves. - Both directory-submission docs state the decided posture plainly: no tool initiates or executes a transfer of the user's funds; the counterexample/options/open-question passages are gone (per review: submissions should be black or white, no grey areas or follow-ups). Example prompts and test cases are financially neutral (opencloud.org, cycles-instructions, plain canister ids); the OpenAI financial negative test case is removed. - OpenAppArgs/FindAppArgs docs lose the MULTI/DEX/Oisy/NNS name examples (also flagged by review-bot); landing page prompt and group-04 copy updated to match the instructions-only behavior. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
Per review: policy language belongs in the server-level instructions, not in per-tool descriptions. The top-up and creation descriptions now state the one functional fact a calling model needs — the tool only prints the icp CLI steps and never executes the operation — without the provided-for-completeness / never-moves-funds disclaimer prose. Tests pin the functional wording and that the descriptions stay free of financial language. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
…' into claude/icp-marketplace-compliance-vpawel-3-definancialize Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
Per review-bot findings on the submission docs: with creation now instructions-only there are 19 read-only-annotated tools, not 18 (both places); the cycles-instructions example prompt names a concrete canister id since icp_top_up_canister requires one; and the README intro clause is scoped to the two instructions-only tools. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
…e-compliance-vpawel-3-definancialize
The one mega-struct carried all 26 tools. Split it along the scope taxonomy the server instructions already teach: IcCanisterTools holds the app- and canister-scoped tools (the …canister…/…_app… names — Candid/OQL reads, update calls, app resolution/discovery, per-app identity), and IcProtocolTools holds the icp_-prefixed protocol/meta tools (dashboard lookups, skills, the OQL guide, and canister creation/management as the management principal). Each half owns only the state it uses (the agent stays on the canister side; the skills catalog on the protocol side). IcTools remains as the composed ServerHandler — same constructor, same get_info/instructions/resources, and a served surface byte-identical to before — dispatching tools/call by router membership and answering tools/list with the concatenated routers (the same pattern imcp2-local's LocalServer wrapper already uses to add its login tools). Tool order in tools/list changes only in that icp_oql_guide now lists with the other icp_ tools. Tests: a new taxonomy test pins the split (icp_ prefix <=> IcProtocolTools, no overlap, nothing dropped); the existing surface tests move to IcTools::all_tools(), and imcp2-local's real-MCP round-trip exercises the composed dispatch end to end. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
… placeholder Per review-bot findings: the open_app / canister_query descriptions and the server instructions still used balance/holdings/positions and a get_balance example as the model-visible illustrations of per-app data — replaced with bookings/appointments/orders/profile. The anthropic doc's section heading still said 'answer pending' above a body that says resolved in code; and the openai doc's negative test case used an angle- bracket placeholder that Markdown parses as a raw HTML tag — it now uses a reserved example.com domain. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
…ze' into claude/icp-marketplace-compliance-vpawel-4-split-tools Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
…e-compliance-vpawel-4-split-tools
aterga
marked this pull request as ready for review
August 27, 2026 14:48
aterga
changed the base branch from
claude/icp-marketplace-compliance-vpawel-3-definancialize
to
main
August 27, 2026 14:48
There was a problem hiding this comment.
Pull request overview
Splits the core MCP tools by scope while preserving the composed IcTools server interface.
Changes:
- Separates canister/app tools from
icp_protocol tools. - Adds manual routing and merged tool listing.
- Re-exports both tool groups.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
crates/imcp2-core/src/tools.rs |
Defines and composes the split tool routers. |
crates/imcp2-core/src/lib.rs |
Documents and re-exports the new types. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
sea-snake
approved these changes
Aug 27, 2026
sea-snake
approved these changes
Aug 27, 2026
Empty commit at the author's request: the org ruleset began applying to this repository after this branch's last push, so its required workflow never ran on the previous head and the check sat at Expected forever. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LvwAVXfx5kLNc4SqKXkavk
This was referenced Aug 27, 2026
Merged
sea-snake
pushed a commit
that referenced
this pull request
Sep 1, 2026
A minor bump rather than a patch, because both the library API and the served tool surface changed incompatibly since 0.2.0. `imcp2` no longer contains the tool surface and the II session engine: they moved to a new sibling crate, `imcp2-core` (#150, #157), which `imcp2` now depends on by version and which publishes alongside it. The re-exports in `src/lib.rs` keep the familiar names resolving (`IiInstance`, `SessionGauges`, `Agent`, `IC_URL`), but the crate an embedder links has changed shape, and `IcTools` is gone — split into `IcCanisterTools` and `IcProtocolTools` (#157). The surface an MCP client sees changed too: only the app/canister tools are served (#158), state-changing calls now reach only applications that publish a service declaration (#166), the ledger transfer/approval methods are refused (#154, #163), `icp_top_up_canister` is instructions-only (#153), and routine replies no longer echo the per-app principal (#177). Under cargo's 0.x rules `0.2` is the compatibility range, so shipping this as 0.2.1 would hand the break to everyone on `imcp2 = "0.2"` — the requirement our own README recommends — the next time they ran `cargo update`. 0.3.0 opens a new range instead; existing users stay on 0.2.x until they choose to move. The README's dependency line follows, as `"0.2"` would no longer resolve to a current release. `imcp2-core` moves in lockstep: publish-crate.yml checks the tag against both manifests, and the workspace pin that binds them (`imcp2-core = { path = …, version = … }`) has to name the same number or the path dependency stops resolving. `imcp2-local` moves with them — it releases on its own `imcp2-local-v*` tags and has never been cut, so there is nothing to keep it behind, and its `--version` output would otherwise report 0.2.0 from a 0.3.0 tree. Claude-Session: https://claude.ai/code/session_01GqhkbpCwxs67F5E2EzyDwh Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to the marketplace-compliance PRs (#153 / #154 / #155, all merged; this PR targets main). The one
IcToolsmega-struct carried all 26 tools; this splits it along the scope taxonomy the server instructions already teach:IcCanisterTools— the app- and canister-scoped tools (the…canister…/…_app…names): Candid/OQL reads, update calls, app resolution/discovery, and the per-app identity tools. Owns the shared agent, the identities, and the session seam.IcProtocolTools— the IC protocol / meta-level tools (theicp_prefix): dashboard name/id lookups, the official IC skills, the OQL dialect guide, and canister creation/management as the standing management principal. Owns the skills catalog, the identities, and the session seam — no agent (none of its tools use one).IcToolsstays as the composedServerHandler: same constructor signature, sameget_info/instructions/resources, and a served surface identical to before. It dispatchestools/callby router membership and answerstools/listwith the concatenated routers — the same patternimcp2-local'sLocalServerwrapper already uses to add its login tools, so downstream embedders (src/lib.rs,imcp2-local) need no changes.The only externally observable difference is
tools/listordering:icp_oql_guidenow lists with the othericp_tools instead of between two canister tools.Related issues
None — code-organization follow-up to the compliance track.
Changes
crates/imcp2-core/src/tools.rs: the three structs; the single#[tool_router] implbecomes two (one per struct, methods otherwise untouched — onlyicp_oql_guidemoves down to the protocol block);IcTools::newbuilds both halves andIcTools::all_tools()is the one source for the merged list; the#[tool_handler]macro is replaced by a manualServerHandlerimpl (list_tools/call_tool/get_tool) mirroringLocalServer's dispatch; the handler's resource methods reach the skills catalog through the protocol half.crates/imcp2-core/src/lib.rs: re-exportsIcCanisterTools/IcProtocolToolsand updates the crate doc.the_split_follows_the_icp_prefix_taxonomypins the membership rule (everyicp_-prefixed tool onIcProtocolTools, everything else onIcCanisterTools, no overlap, nothing dropped); the existing surface tests (annotations, output schemas, description contracts) switch toIcTools::all_tools()and keep guarding the full 26-tool surface;imcp2-local's real-MCP round-trip test exercises the composed dispatch end to end (28-tool merged list, core call forwarded through the wrapper).Testing
cargo build --locked --workspace --all-targetscargo test --locked --workspace --all-targets(all pass; 148 in imcp2-core incl. the new taxonomy test, 20 in imcp2-local incl. the live MCP round-trip)cargo clippy --workspace --all-targets— no new warnings (10 pre-existing, unchanged)npm test --prefix monitoring/mcp-status(dashboard unchanged)Checklist
Generated by Claude Code