Skip to content

Make app-feature discovery findable from tool descriptions - #71

Merged
aterga merged 1 commit into
mainfrom
claude/app-discovery-tool-hints
Jul 21, 2026
Merged

Make app-feature discovery findable from tool descriptions#71
aterga merged 1 commit into
mainfrom
claude/app-discovery-tool-hints

Conversation

@aterga

@aterga aterga commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

A descriptions-only change so that "how to answer a question about an app" is discoverable from the per-tool descriptions, not only from the server instructions block.

Motivated by a user report: from the claude.ai Chat connector surface, "what's my balance on <app>" failed — the model enumerated the tools, found no literal "balance"/"get_X" tool, and gave up — while the Code surface answered it fine. The difference is that Claude Code ingests and follows the server instructions ("START WITH open_app", "'my/our …' is an authenticated read"), whereas a client that surfaces tools via lazy search reads each tool's description but not that instructions block, so it never learned to route through open_app and compose the read.

This moves the routing know-how into the descriptions themselves. No behavior change, and deliberately not app-specific (no "Oisy", no "balance"-only wording).

Related issues

None — external user report; no GitHub issue open.

Changes

  • open_app: leads with a generic decision chain — (1) is the request about a specific app's functionality or the user's data in one app, rather than the IC protocol itself? (2) is that app on the Internet Computer (this tool / icp_find_app_by_name is how you find out; an unrecognized app name or a URL with no IC evidence is refused, not guessed)? (3) if so, start here: one call resolves the app and discovers its service. It also states that an app feature is almost never a single named tool — you compose it from what open_app returns (discovered canisters + oql/api_doc_available flags), reading via canister_query (incl. OQL) or acting via canister_update_call.
  • canister_query: a one-line nudge to start from open_app when the request is app- or user-data-scoped, rather than reaching for a raw read first.

Rebased onto main after #70 split call_canister into canister_query / canister_update_call; the references use the new tool names (this replaces the earlier draft, which nudged call_canister).

Testing

  • cargo build --locked --all-targets (via the test build)
  • cargo test --locked — 128 passing (descriptions are string literals)
  • cargo clippy --all-targets — descriptions-only; introduces no new warnings
  • npm test --prefix monitoring/mcp-status — not applicable (no dashboard change)

Checklist

  • I have read the Contributing guidelines.
  • Docs (README / comments) updated for any user-visible change — this change is the description update; README is unaffected.
  • No secrets, credentials, or internal-only information are included.

🤖 Generated with Claude Code

https://claude.ai/code/session_014T9N8USDfNK5yzznPGg7Ym

@aterga
aterga requested a review from Copilot July 21, 2026 14:25
@aterga
aterga marked this pull request as ready for review July 21, 2026 14:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates MCP tool descriptions so clients that only surface tool descriptions (and not the server-level instructions) can still discover the intended routing for “app-specific / my data” questions: start with open_app, then compose reads/actions from discovered canisters and capability flags.

Changes:

  • Expanded open_app’s description to include a step-by-step routing decision chain and emphasize composition over “single feature tools”.
  • Added an upfront nudge in call_canister’s description to start with open_app for app- and user-data-scoped requests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main.rs Outdated
Copilot AI review requested due to automatic review settings July 21, 2026 14:31
@aterga
aterga force-pushed the claude/app-discovery-tool-hints branch from 3125fa5 to de7f2f8 Compare July 21, 2026 14:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/main.rs:925

  • Grammar: "the user's own data in one" reads like a typo; it likely meant "in it" (referring to the app).
        description = "ROUTING. Run this chain before answering anything that names, or implies, a specific app or the user's own data in one (a balance, holdings, bookings, positions, profile, or \"what can it do\"): (1) Is the request about a specific APP's functionality or the user's data in it, rather than the IC protocol itself? (2) Is that app on the Internet Computer? If unsure, THIS tool (or icp_find_app_by_name) is how you find out: a known or verifiable app resolves, while an unknown or non-IC target is REFUSED, never guessed. (3) If so, START HERE: one open_app call resolves the app AND discovers its service. An app feature is almost never a single named tool (there is no \"get_balance\"); you COMPOSE it from what open_app returns, reading the discovered canisters and their `oql`/`api_doc_available` flags to see how to READ (canister_query, including OQL) or ACT (canister_update_call). So never conclude \"there's no tool for that\" from the flat tool list without opening the app first. Open an Internet Computer app in ONE call, given its NAME or its URL — the recommended entry point when a user names an app. It resolves the app's Internet Identity derivation origin (like resolve_app) AND discovers the canisters behind it (like discover_app_canisters) together, so you don't chain those yourself. Pass a NAME (e.g. \"MULTI/DEX\", \"Oisy\", \"NNS\") or a URL (e.g. \"https://oisy.com\"): a name or bare host is matched to the built-in known-app registry FIRST (so even a wrong-TLD guess like \"multidex.com\" repairs to the canonical URL), and an explicit https:// URL is resolved as given. NEVER fabricate a domain from a name — an unknown bare name is refused with instructions to find the real URL (web search / ask the user), and a URL with no Internet-Computer evidence is refused, both instead of guessing a wrong identity. Returns `app_url` (the one used), `derivation_origin` (+ its source) to act with, `alternative_origins`, and the discovered `canisters` (with provenance/labels AND per-canister `oql`/`api_doc_available` capability flags, from a one-shot Candid probe of the app's own canisters). A canister flagged `oql` holds the app's data, GATED BY THE CALLER's principal: to read the USER's own data (\"my …\", \"our …\") pass the returned `derivation_origin` to get_canister_oql_schema (for the entity/field names) and to canister_query (with the `oql` argument, to run the query). Those OQL reads REQUIRE `derivation_origin` — not `app_url` — and reject an anonymous read for now. No authenticated session required for open_app itself (no principal is derived here). Narrower tools remain for single steps: icp_find_app_by_name (name→URL only), resolve_app (origin only), discover_app_canisters (canisters only).",

Comment thread src/main.rs
Copilot AI review requested due to automatic review settings July 21, 2026 14:46
@aterga
aterga force-pushed the claude/app-discovery-tool-hints branch from de7f2f8 to 3a45a90 Compare July 21, 2026 14:46

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment thread src/main.rs Outdated
A client that reads per-tool descriptions but not the server instructions
block (e.g. surfacing tools via lazy search) could see the low-level
primitives, find no literal "balance"/"get_X" tool, and conclude the
capability is missing, giving up instead of composing it.

Move the routing know-how into the descriptions themselves:

- open_app: lead with a generic decision chain (is the request about a
  specific app or the user's data in it? is it an ICP app? then open_app
  to resolve + discover the service), and state that an app feature is
  composed from what open_app returns (canister_query incl. OQL for
  reads, canister_update_call for acts), not a single named tool.
- canister_query: a one-line nudge to start from open_app when the
  request is app- or user-data-scoped, rather than reaching for a raw
  read.

Rebased onto main after #70 split call_canister into canister_query /
canister_update_call; references updated to the new tool names.
Descriptions only; no behavior change. Not app-specific.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014T9N8USDfNK5yzznPGg7Ym
Copilot AI review requested due to automatic review settings July 21, 2026 14:54
@aterga
aterga force-pushed the claude/app-discovery-tool-hints branch from 3a45a90 to c72ed7c Compare July 21, 2026 14:54

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@aterga
aterga merged commit a96929d into main Jul 21, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants