Repository navigation
Drop five unused direct dependencies - #100
Merged
Merged
Conversation
None of these crates are referenced anywhere in the codebase (verified by grep across src/ and tests/); the default build and the full test suite pass without them: - ed25519-dalek: Ed25519 keygen/signing goes through ic-agent's BasicIdentity::from_raw_key, never this crate. - p256, ic-signature-verification: the server never verifies delegation signatures itself; the replica verifies every hop at redeem. - ic-representation-independent-hash: unreferenced. - schemars 0.8: vestigial. Every JsonSchema derive resolves through `use rmcp::schemars` (rmcp's re-exported 1.x); the top-level 0.8 dep is never bound. rmcp's own schemars re-export is untouched. Removing the declarations drops ic-signature-verification and ic-representation-independent-hash (plus their unique transitive deps ic-canister-sig-creation and ic0) from the default build closure. ed25519-dalek and p256 remain in the tree transitively via ic-agent, and schemars 0.8 remains via the optional pocket-ic (e2e feature) dep, so removing those three declarations is direct-dependency hygiene rather than closure reduction. Cargo.lock updated minimally (removals only, no version bumps). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014T9N8USDfNK5yzznPGg7Ym
There was a problem hiding this comment.
Pull request overview
This PR removes five unused direct Rust dependencies from Cargo.toml and updates Cargo.lock accordingly, reducing direct-dependency surface area while keeping the build graph correct via existing transitive/optional dependencies (e.g., via ic-agent and optional pocket-ic).
Changes:
- Removed unused direct deps from
[dependencies]:ed25519-dalek,p256,ic-signature-verification,ic-representation-independent-hash,schemars = "0.8". - Pruned now-unreachable crates from
Cargo.lock(includingic0andic-canister-sig-creation) and removed the dropped crates from this workspace package’s dependency list in the lockfile.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| Cargo.toml | Drops unused direct dependency declarations while leaving transitive/optional sources intact. |
| Cargo.lock | Removes lock entries that are no longer reachable after dependency cleanup; no version bumps. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
sea-snake
approved these changes
Jul 29, 2026
aterga
pushed a commit
that referenced
this pull request
Aug 20, 2026
Re-verify every claim and file:line reference against the rebased tree and absorb what main already did or changed: - The five vestigial deps (ed25519-dalek, p256, ic-signature-verification, ic-representation-independent-hash, schemars 0.8) were already removed on main (#100) — reframe that stripping work as done. - Account for the new hosted-only surfaces the local split must gate: prometheus + src/metrics.rs (/metrics, #124) and McpConfig's state_dir/require_resource (#144/#127); note the local binary needs no state directory at all. pocket-ic (e2e-only, #76) never enters any closure. - Rewrite §10: production II now serves at /mcp by default (#92), CI probes it (#113), and the PocketIC e2e harness verifies the full connect contract — the remaining unknowns are the local binary's http://127.0.0.1 mixed-content and CORS behavior, and the harness is the plan for testing the local flow. - Prod-instance env overrides are II_URL_PROD/II_CANISTER_ID_PROD (#92); registration chains are also verified client-side against the agent's root key (new_with_root_key); registration_pubkey_b64 is now fallible; AuthStore's dropped fields now include mcp_path and require_resource, and the dropped OAuth side grew RFC 8707/9207 and the bounded DCR store. - Note the crates.io publishing dimension (v0.2.0, tag-guarded trusted publishing, docs/ excluded from the .crate) and re-stamp every stale file:line reference (auth.rs shifted ~500-650 lines; the 13 call-site list and all evidence-index anchors updated). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK
9 tasks done
aterga
added a commit
that referenced
this pull request
Aug 25, 2026
…148) * Add scoping doc for a local-deployment MCP instance Analyze the current beta/prod composition and scope a secondary server instance that bridges the MCP tools to a local dfx replica instead of mainnet. Documents the mainnet assumptions that would break locally (root-key fetch, hard-coded IC_URL, the discovery SSRF/https guard, target_origin canonicalization, and the CMC/ledger management path), a proposed local run-profile design, the security guardrails, a phased work breakdown, and open decisions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Rescope: minimal stdio local binary, no OAuth, prod II Rewrite the scoping doc for the intended model: a separate, minimal run-it-yourself binary that speaks MCP over stdio and talks to mainnet IC + production Internet Identity — not a local dfx replica. It drops the entire OAuth 2.1 authorization-server layer (the local client is co-located, so the stdio process boundary replaces bearer-token auth) while keeping Internet Identity: login runs as a built-in browser handshake and per-app account delegations work as today. Adds a verified dependency-stripping analysis (four unreferenced crates plus a vestigial schemars drop; rmcp swaps to the stdio transport and drops auth), the auth.rs OAuth-drop/II-connect-keep partition, the tool/session singleton seam, a 3-crate workspace layout, the security model, and the production-II verification risks. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Keep the crate named imcp2 in the layout The shared library crate stays imcp2 (its existing embeddable identity) and the hosted binary stays named imcp2, so the Dockerfile, systemd unit, and deploy scripts that build/run an imcp2 binary are unchanged. The hosted server + OAuth layer move behind a default-on `hosted` feature (optional axum/tower-http); the new minimal stdio binary is a separate imcp2-local crate depending on imcp2 with default-features off, so it never compiles the OAuth/HTTP deps. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Add "Working with AI tool clients" section Cover how imcp2-local integrates with Claude (Desktop/Code + the cloud surfaces), Codex, Cursor, Perplexity, and Antigravity, verified against each client's current MCP docs. Key findings: a stdio server is reachable only by clients that spawn a local subprocess (Claude Desktop/Code, Codex CLI/IDE/desktop, Cursor, Antigravity, and the Perplexity macOS app via its PerplexityXPC helper); cloud/remote-only surfaces (claude.ai web/mobile, Perplexity web/Windows, Codex Cloud) can't reach localhost and need the hosted imcp2 server — the reason the OAuth layer stays in imcp2. Host-driven OAuth never applies to stdio, and stderr is invisible in chat on every client, so the II login URL is surfaced in-band via an authenticate tool (lazy, non-blocking) plus a best-effort browser auto-open. Adds a capability matrix, per-client registration snippets, the login invariants, and the Perplexity remote OAuth/discovery caveats; updates the login section and open decisions to match. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Update the scoping doc for the 63-commit rebase onto v0.2.0 Re-verify every claim and file:line reference against the rebased tree and absorb what main already did or changed: - The five vestigial deps (ed25519-dalek, p256, ic-signature-verification, ic-representation-independent-hash, schemars 0.8) were already removed on main (#100) — reframe that stripping work as done. - Account for the new hosted-only surfaces the local split must gate: prometheus + src/metrics.rs (/metrics, #124) and McpConfig's state_dir/require_resource (#144/#127); note the local binary needs no state directory at all. pocket-ic (e2e-only, #76) never enters any closure. - Rewrite §10: production II now serves at /mcp by default (#92), CI probes it (#113), and the PocketIC e2e harness verifies the full connect contract — the remaining unknowns are the local binary's http://127.0.0.1 mixed-content and CORS behavior, and the harness is the plan for testing the local flow. - Prod-instance env overrides are II_URL_PROD/II_CANISTER_ID_PROD (#92); registration chains are also verified client-side against the agent's root key (new_with_root_key); registration_pubkey_b64 is now fallible; AuthStore's dropped fields now include mcp_path and require_resource, and the dropped OAuth side grew RFC 8707/9207 and the bounded DCR store. - Note the crates.io publishing dimension (v0.2.0, tag-guarded trusted publishing, docs/ excluded from the .crate) and re-stamp every stale file:line reference (auth.rs shifted ~500-650 lines; the 13 call-site list and all evidence-index anchors updated). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Restructure the design doc to the standard feature-doc shape Reorganize into Summary -> Problem -> Non-goals -> Approach -> Design components -> Implementation Stages (with the verification plan and open decisions under the stages, and the code-evidence index as an appendix). Content is unchanged apart from the connective text: the same components, client matrix, security model, and file:line evidence, now in the house design-doc structure. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Add a concise high-level companion to the local-deployment design docs/local-deployment.md is the short, stakeholder-facing overview (same Summary -> Problem -> Non-goals -> Approach -> Design components -> Implementation Stages shape, one altitude up: no file:line evidence or dependency minutiae); the full doc keeps the detail and both docs cross-link. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Refer to ICP CLI-spawned local replicas, not dfx Local replicas are spawned by the ICP CLI now; drop the dfx naming from both design docs' non-goals. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Make the local-replica mode a test configuration, not a non-goal Talking to an ICP CLI-spawned local replica is a nice-to-have rather than something we rule out: a test build enables it with an explicit IC-endpoint override plus a loopback-guarded fetch_root_key, and the integration tests run imcp2-local in exactly that configuration (against an ICP CLI-spawned replica or PocketIC carrying a deployed II canister). Chains are already verified against the injected agent's root key, so the flow works on a test network. The shipped binary still targets mainnet + production II only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * State the no-listening-socket claim precisely "The server has no listening socket" overclaimed: it is true of the MCP tool surface (stdio), but the login handshake necessarily binds a transient loopback listener — II navigates the browser to the callback and fetches the #4091 well-known from the callback's origin, both of which require a real HTTP origin (a custom URI scheme has no origin and II offers no device-grant alternative; this is the RFC 8252 loopback redirect). Scope the trust-boundary claim to the tool surface, note that reaching the login listener confers nothing (static pages; /redeem is state-correlated and only accepts a chain targeting the in-process X), and add the rationale to the login component. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Recommend an imcp2-core crate over the hosted feature flag Make the shared components a new imcp2-core library that both binaries build on: imcp2 (unchanged name, lib + hosted binary, OAuth AS, routers, metrics, e2e harness) and imcp2-local depend on it, and imcp2 re-exports core's public items so existing embedders keep compiling. The default-on `hosted` cargo feature is demoted to a rejected alternative: features unify additively, so any crate enabling imcp2/hosted would switch the OAuth/axum closure on for the whole build graph, leaving the minimal-closure claim invocation-dependent; it also needs cfg gates scattered through the code, where the crate boundary states the component split structurally — with the core split the session seam needs no #[cfg] at all (AuthedSession lives in core and the Bearer arm reads http::request::Parts). Cost accepted: imcp2-core becomes a second published crate (family-internal, 0.x, published before imcp2). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Make the session-handling component self-contained in the overview The overview's "session seam" bullet leaned on the full doc's jargon (seam, bearer-token lookup, singleton). State the motivation instead: every tool call acts as the user's II session, the hosted server resolves it per request from the OAuth bearer token, the single-user local server reads the one in-memory session from login, and the tool implementations are identical in both. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Make the design docs self-contained State the final design plainly instead of narrating how it evolved: drop the rejected-alternative paragraphs and every contrast with superseded drafts ("not a cargo feature", "originally proposed", "since this design's first draft", "the original concern is resolved"), recast the dependency profile per crate as final state, and remove the settled layout item from the open decisions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Drop the local-replica bullet from Non-goals The local-replica test configuration is covered where it belongs (the II wiring component and the verification plan), and the mainnet + production II targeting is already stated in the Approach, so the non-goal bullet added nothing but a hedge. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Resolve the login-flow choices like the ICP CLI; add end-user setup UX The login listener is axum and the browser opens via open::that, matching the ICP CLI's web-identity flow (icp identity link web: an axum Router on 127.0.0.1:0 with graceful shutdown; open = "5"), so the two tools behave the same way. Session persistence stays in-memory. With all three choices settled, the open-decisions sections are gone. Add component 9, end-user setup (UX): per-client steps with no JSON or config editing — the double-click .mcpb bundle for Claude Desktop, an Add-to-Cursor install link, one pasted command for Claude Code and Codex, connector UIs for Perplexity (macOS) and Antigravity, an `imcp2-local setup` command that detects installed clients and writes their configs, and the signing/notarization packaging that makes double-click installs work. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Add the upgrade story to the end-user setup UX Client registrations point at a stable install path, so an upgrade is an in-place binary swap picked up on the next server start — nothing to re-register and no state to migrate (sessions are in-memory). Distribution and updates follow the ICP CLI: cargo-dist installers with the axoupdater updater shipped alongside, and channel detection that surfaces the right upgrade command (axoupdater receipt / Homebrew / npm). The Claude Desktop bundle upgrades on its own channel by installing the new .mcpb version. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Add signing and provenance to the end-user setup component Two layers for two verifiers. OS execution gates: macOS Developer ID + notarization (Gatekeeper is the verifier for browser-downloaded files — including binaries spawned as MCP subprocesses — and accepts only Apple-issued signatures; a bare signed+notarized binary passes, no installer artifact needed) and Windows Authenticode via Azure Trusted Signing or an EV cert. Supply-chain provenance: keyless GitHub artifact attestations on every artifact, verifiable with gh attestation verify. The .mcpb's substance is the signed binary inside (the format specifies no bundle-level signing), with directory listing as the trusted distribution path. Notes which channels bypass the gates (installer script, Homebrew, npm), where the steps hook into the cargo-dist pipeline, and what DFINITY must acquire with lead time. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Promote signing and provenance to its own design component Give the signing content top-level visibility as component 10 instead of a block inside the end-user setup component, and mirror it in the overview's component list. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Commit to PocketIC as the integration-test dependency Integration tests run imcp2-local's local-replica test configuration against PocketIC carrying a deployed II canister (the pocket-ic dev dependency, reusing the e2e harness's real-II setup). The endpoint override still lets a developer point a test build at any other local replica, but the test plan names one vehicle. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * Reconcile the dependency and AuthStore claims with the axum decision The login-listener decision (axum, matching the ICP CLI) left three stale claims behind: imcp2-local does depend on axum for its three transient login routes, so say so in the crate-layout bullet, the net dependency list, and the overview, scoping the absence claim to tower-http/prometheus/OAuth and the hosted MCP transport. Also state the AuthStore reality under the crate split: it stays intact in imcp2 (the retained OAuth routes need all of its state), the extracted primitives carry none of it, and the local binary replaces it with a minimal pending-connect state rather than a slimmed copy. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * docs: address second review round on the local-deployment design - Component 6: rmcp's #[tool_router] is type-level per impl block, so construction mode alone cannot hide tools. Specify that the local-only authenticate/auth_status tools live in their own router that only the local binary composes, with a hosted-side tools/list exclusion test. - Component 7: the Singleton session source holds a shared, replaceable slot rather than a fixed String — the II contract requires a fresh session key after Unauthorized, so re-login must be a same-process step with no client restart. - Sessions wording (both docs): replace the misleading "re-login per run" with the actual lifetime — sign in again after a restart, on grant expiry, or on revocation; note the one-hour grant requested today and the user's consent-time choice of effective TTL. - Verification: PocketIC exercises the protocol, not browser policy, so add a real-browser compatibility gate (automated Chromium/Firefox login run plus a manual Safari/enterprise-policy pass) to Stage 2's login exit criterion. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * docs: address third review round on the local-deployment design - Component 6: the login tools cannot be an impl block in imcp2-core — they drive the loopback listener and browser opener, which live in imcp2-local, and core cannot call back into its dependent crate. They now live on a small wrapper handler in imcp2-local that merges tools/list and dispatches tools/call to its own router before forwarding to the inner IcTools handler (RequestContext<RoleServer> is handler-independent). Hosted stays login-free by construction, with the tools/list test kept as a regression guard. - Component 1: the crate split is not visibility-neutral — workspace packages share no crate-private access, so the composition API (IcTools/IcTools::new with SessionSource, the Identities registration/redeem entry points, the iiconnect builders) graduates from pub(crate) to core's deliberate public API, re-exported by imcp2; dropped the "kept verbatim" phrasing. - Component 4/5: dropping the redeem's redirect tail breaks the callback page's only success arm (it treats a JSON redirect as success, error otherwise). Specify the second success arm: the local redeem answers {"done": true} and the shared page renders "Signed in — you can close this tab" in place; hosted keeps answering redirect. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK * docs: address fourth review round on the local-deployment design - Dependency isolation: distinguish direct dependencies and linked code from unavoidable transitives. prometheus and the OAuth modules are structurally absent from imcp2-local's graph (it never depends on imcp2), but tower-http still appears deep in the graph as an rmcp/reqwest internal — the guarantee is that the hosted CORS layer is not a dependency, not that the crate name vanishes. Scope the Stage 1 exit criterion the same way. - Versioning: an "internal" 0.x label on imcp2-core cannot exempt items imcp2 re-exports — those are imcp2 public API and breaking them is a breaking change for imcp2 embedders under imcp2's own semver. State that the label relaxes stability only for core-only surface, with the re-export set curated to the pre-split imcp2 API. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqNkpMQiQHzYxC2djTfvBK --------- 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
Removes five direct dependency declarations from
Cargo.tomlthat are never referenced anywhere in the codebase. Verified by grep acrosssrc/andtests/, and by a clean--lockedbuild + full test run without them.This is the dependency-stripping item from the PR #77 scoping doc (§3), landed as an independent cleanup that stands on its own regardless of the local-binary work.
Related issues
Prompted by the dependency audit in #77 (§3). No issue closed.
Changes
[dependencies]:ed25519-dalek— Ed25519 keygen/signing goes throughic-agent'sBasicIdentity::from_raw_key, never this crate.p256,ic-signature-verification— the server never verifies delegation signatures itself; the replica verifies every hop at redeem.ic-representation-independent-hash— unreferenced.schemars = "0.8"— vestigial: everyJsonSchemaderive resolves throughuse rmcp::schemars(rmcp's re-exported 1.x). rmcp's own schemars re-export is untouched.Cargo.lock: removals only, no version bumps.ic-signature-verification,ic-representation-independent-hash, and their unique transitive deps (ic-canister-sig-creation,ic0) leave the build closure.Note on the tree:
ed25519-dalekandp256remain transitively viaic-agent, andschemars 0.8remains via the optionalpocket-ic(e2efeature) dep. So for those three, dropping the declaration is direct-dependency hygiene (our code never binds them directly) rather than closure reduction; the default build has zeroschemars 0.8nodes.Testing
cargo build --locked --all-targetscargo test --locked --all-targets(151 + 8 tests pass, 0 failed)cargo fmt --all/cargo clippy --all-targets(tree is warning-free)npm test --prefix monitoring/mcp-status(if the dashboard changed)Checklist
🤖 Generated with Claude Code
Generated by Claude Code