Skip to content

ToolContract

Module: mas.runtime.contracts.tool_contract

ToolContract is the runtime boundary for listing and calling tools. The engine, local plugin, and MCP plugin all dispatch through call_tool(tool_name, arguments).

provider.call_tool("web-search", {"query": "Apple stock price"})
  1. The LLM (or test) emits a tool name plus a JSON object of arguments.
  2. The runtime registry looks up the name and forwards to the owning plugin.
  3. Local tools: ToolContract.call_tool validates arguments and calls execute(**arguments).
  4. MCP: MCPToolProvider.call_tool sends MCP tools/call with the same name and arguments.

execute(**kwargs) is the in-process helper for a single tool class. Composite providers (local registry, MCP, skill tools) override call_tool and do not go through execute.

MCP tools/call is this method. Extra MCP SDK parameters and result parts are optional kwargs / optional envelope keys on the same call, or they are connection policy on infra — they are not a second invocation API.


Required surface

Method Required payload
list_tools() [{name, description, parameters}]
call_tool(tool_name, arguments) dict / envelope with result (and is_error on failure)
execute(**kwargs) local single-tool helper only

invoke_call_tool forwards optional kwargs only when the callee declares them (or takes **kwargs).


Optional advertise (list_tools / kind: Tool)

Emitted only when set. Schema: tool.schema.yaml. Guide: tool.md.

Contract getter / YAML list_tools key
get_title() / spec.title title
get_output_schema() / spec.output_schema output_schema
is_idempotent() / spec.idempotent idempotent
is_read_only() / spec.read_only read_only (None = omit)
is_destructive() / spec.destructive destructive
is_open_world() / spec.open_world open_world
get_icons() / spec.icons icons
get_task_support() / spec.task_support task_support
get_meta() / spec.meta meta
get_semantics() / spec.semantics semantics
get_timeout_seconds() / spec.timeout_seconds timeout_seconds

Optional call_tool kwargs

call_tool(
    tool_name,
    arguments,
    timeout_seconds=None,
    progress_callback=None,
    cancel_event=None,          # accepted; no MCP SDK mapping
    meta=None,
    input_responses=None,
    request_state=None,
    allow_input_required=None,
    allow_claimed=None,
    ctx=None,
    user="",
)

The default ToolContract.call_tool ignores these and runs execute(**arguments). The MCP client forwards the ones the SDK supports (read_timeout_seconds, progress_callback, meta, elicitation flags).


Optional result keys (ToolResultEnvelope)

Daily payload is {status, result, is_error} (plus result_mode / execution_mode on the envelope). Extra keys appear only when set: content, structured_content, result_type, meta.


Not on ToolContract — infra ToolServerRegistry

These describe where the server lives, not what the tool is, and not how it is invoked:

Field Place
url / endpoint, transport, command / args / env / cwd Infra tool server
HTTP headers (secrets: env:VAR; omit when unused) Infra tool server
Connection timeout Infra tool server
follow_pagination (flatten nextCursor; default true) Infra tool server
cache_ttl_ms / cache_scope (list-result cache policy) Infra tool server

A contract-only caller uses list_tools() and call_tool(name, arguments). It does not see URL, headers, pagination, or cache policy.

Reference: infra.md — ToolServerRegistry · tool-server-registry.md. Example: library-samples/infra/mcp-localhost.yaml.

The agent spec does not declare tool providers. The infra tool-server entry declares protocol: mcp; the runtime discovers the tool names from the server unless infra supplies an explicit tools list.


See also