Wymcp. Help
(Wymcp v0.2.2)
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 renders through Wymcp.Tool.Schema.action_summaries/1, which
shares its content source with the tools/list description builder
(Wymcp.Tool.Schema.build/1) rather than being called by it, 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.
It will not render around a gap, at any of the three levels. Help obtains
every action schema it renders through Wymcp.Tool.fetch_action_schema!/3
or Wymcp.Tool.fetch_action_schemas!/1, which check the mandatory keys
where the schema is obtained — the read-side corollary stated in
Wymcp.Tool's moduledoc — so a schema missing one raises ArgumentError
naming the tool, the action and the key before anything is rendered.
Publishing the entry instead would assert something false about the action:
silence about :properties reads as a claim that it takes none, and a null
description reaches the wire as the action's description.
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
pair in run/2: vocabulary through the same Wymcp.Tool.check_arguments/4
a generated tool's dispatch uses, and types through help's own
check_argument_types/2 — a tool that hand-writes its schema owns the
types of the keys it declares, and the framework's two type checks cover
only its own action/data. Both valid sets derive from the schema
above. Both halves are needed: argument validation in
Wymcp.Methods.ToolsCall checks structure only — 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 while a mount module compiles (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. (A
mistyped action or data never gets this far: ToolsCall's argument
validation answers it -32602 before any tool runs, unobserved by tool
telemetry — a property of the -32602 path, not of help.)
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 a mount module's compile
(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.