Wymcp. Help
(Wymcp v0.1.1)
View Source
The framework-owned introspection tool — the server's entire introspection
surface, injected by Wymcp.Router into every server under the reserved
tool name help.
Help answers at three levels: a bare call returns the server index (every
tool with its action summaries); tool returns that tool complete (all
action schemas with notes, related actions, and examples); tool plus
action returns one action complete, with the target tool's
Wymcp.Tool.action_context/2 output under "context". Resolution order
is tool first, then action — action without tool is an error, and
unknown targets error naming the valid ones and pointing at the help
index (isError: true content the calling LLM can self-correct from),
never a silent fallback to a broader answer.
The index shares its content source with the tools/list description
builder (Wymcp.Tool.Schema.action_summaries/1), so the two cannot drift.
Server-level prose does not live here — it belongs in the initialize
instructions router option.
Help answers from ctx.tools — the request's resolved tool list, which
Wymcp.Methods.ToolsCall sets on every context — so it needs no session
and serves both eras.
This module implements the tool wire contract by hand (input_schema/0,
run/2) rather than through use Wymcp.Tool: help has no action
dispatch, its two parameters live at the top level of arguments, and
its input schema sets additionalProperties: false so a misspelled
parameter is a stated contract violation rather than a silent answer to
the wrong question. Publishing that is one half; the other is the gate in
run/2, which calls the same Wymcp.Tool.check_arguments/4 a generated
tool's dispatch uses, with help's own valid set derived from the schema
above. Both halves are needed: Wymcp.Methods.ToolsCall strips the
declaration before argument validation runs — a stray name is a
dispatch gate's answer everywhere in wymcp, never a -32602 naming no
key — so without the gate a misspelled tol would silently answer the
index. Its definition/0 is assembled by the same
Wymcp.Tool.build_definition/1 every generated tool uses, so a
definition key added there reaches help without hand-sync.
It is the framework's only @behaviour Wymcp.Tool tool, and the only
reason that path exists. Wymcp.Tool's run/2 and input_schema/0 come
from __before_compile__ and are not defoverridable, so a tool without
action dispatch cannot use the macro — the path is an internal
accommodation, not a consumer contract; a consumer tool uses the macro.
Being behaviour-only, this module owes every required callback by hand:
actions/0, run_action/3, hints/2 and handle_error/1 are dead
stubs carried for that reason alone, and Wymcp.Router.init/1 checks
them at every server's boot (the callback-surface invariant, homed in
Wymcp.Tool).
Every call that reaches an answer emits [:wymcp, :help, :called] after
that answer is resolved — see Wymcp.Telemetry. A call rejected by the
arguments gate above does not: it resolved no target, so the event's
tool, action and level would describe an index call that never
happened. Such a rejection stays observable as [:wymcp, :tool, :stop]
with error_kind: :dispatch, like any other tool's gate rejection.
flowchart TD
H[Wymcp.Help] --> R["run/2"]
subgraph External
R -->|"action_summaries/1"| SC[Tool.Schema]
R -->|"shared tool-surface helpers"| WT[Wymcp.Tool]
WT -->|"action_context/2"| T(Target tool)
H -->|"build_definition/1"| WT
R --> TE[Telemetry]
end
Summary
Functions
True when module claims the reserved tool name.
Functions
True when module claims the reserved tool name.
The reserved name is "help" — the tool name only the framework may
use: consumer tools may neither claim it at boot (Wymcp.Router.init/1)
nor replace it at runtime (Wymcp.Session.register_tool/2). Both raise
sites route through this predicate; each keeps its own message tail
naming its path.