Teach agents to write agent-friendly tools: a "Designing tools for agents" section in the skill and docs
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 68/100
- Issue type
- Documentation
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- kotlin, react-native, swift, typescript
- Domain
- developer-experience, documentation
Research direction
Start with skills/appduct/SKILL.md and docs/TOOLS.md, then inspect the playground tools and the React Native, iOS, and Android READMEs named in the issue. Run appduct tools to review the listing as a calling agent, update the documented examples and playground descriptions or annotations, and finish by running the markdown link check from docs/CI.md.
Written by the indexing model from the issue text.
Description
Why
Increasingly, the one registering Appduct tools in an app is itself an agent (the README already says "asking an agent to add Appduct to your app or write its tools? Install the skill"). The skill and docs/TOOLS.md explain the mechanics thoroughly: schema forms, object-rooted roots, timeoutMs, per-mount registration. They say nothing about what makes a tool good for the agent that will call it, so an agent asked to "expose the checkout flow" will happily produce doCheckout(json: object) with no annotations, no output schema and a one-word description. Everything downstream (tools/list in an MCP client, the signature listing from #67, the policy engine keyed on destructiveHint) then degrades.
Tool quality is what a calling agent actually experiences. This is documentation only, and it multiplies the value of every other agent-facing feature.
Proposal
Add a "Designing tools for agents" section to skills/appduct/SKILL.md (the copy an agent reads), with a matching section in docs/TOOLS.md and a pointer from the React Native, iOS and Android READMEs. Each rule gets a one-line reason and a before/after example:
- Name by intent, not implementation.
seed_cart,go_to_checkout,set_feature_flag; neverdispatch_actionorrun_effect. - Always set
annotations.readOnlyHinton every observer;destructiveHinton anything that deletes, logs out, resets or pays. The daemon's policy engine and the MCP client's permission UI key on these. - Pair every mutation with an observer. An agent cannot verify
seed_cartwithoutget_cart. Return the resulting state from the mutation itself where it is cheap ({ cartId, items }), so the common case is one call. - Declare an
outputSchema. It is what makes the resultstructuredContentover MCP and lets the signature listing show-> { ... }. Wrap non-object results in an object. - Describe preconditions and side effects. "Requires a signed-in user. Navigates to the Cart tab." The first line is what the listing shows; keep it one sentence.
- Describe every parameter (
.describe()in zod,descriptionin raw JSON Schema), with units and allowed values; prefer enums over free strings. - Make setup tools idempotent (
login(userId)is a no-op when already signed in as that user) and say so withidempotentHint. - Prefer a few coarse tools over many fine ones.
complete_onboarding()beatsdismiss_step_1..7. An agent loses more to a long tool list than to a slightly wider tool. - Declare
timeoutMson anything that touches the network; the default is 10 s. - Do not register tools that need UI cooperation to finish (a tool that opens a modal and resolves when the user taps). Return once the state change is done, or post an
app_eventfor the rest. - Keep both schemas object-rooted (already documented; link to it).
- Name a screen or feature in the description so
--filter(#67) finds the tool, and use groups once they exist (#70). - For the native SDKs: the same rules, phrased for
AppductToolDescriptor/registerToolin Swift and Kotlin.
Also add one line to the skill's setup flow: after registering tools, run appduct tools and read the listing back as the calling agent will see it; fix any ..., missing -> { }, or description that does not say what the tool needs.
Acceptance criteria
- The skill and
docs/TOOLS.mdcarry the section; each rule has an example; the native READMEs link to it. - The playground's tools follow the rules (they are the reference an agent copies). Adjust descriptions and annotations there where they do not.
-
docs/CI.md's markdown link check passes.
Out of scope
- Any automated checking of these rules, in the CLI or in the SDKs. Descriptions and annotations are judgement calls; the guidance is the deliverable.
- Dominant language
- TypeScript
- Stars
- 17
- Forks
- 0
- Avg merge
- 19h 18m
- Merged PRs (30d)
- 27
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from callstackincubator/appduct
-
Difficulty 1/5 Under an hour Newbie friendliness 94/100
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
All issues in callstackincubator/appduct
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
bug clawsweeper:linked-pr-open clawsweeper:needs-live-repro clawsweeper:no-new-fix-pr impact:message-loss issue-rating: 🐚 platinum hermit P2 regression
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 78/100
fullcalendar/fullcalendar#8106 ·