Skip to main content

Overview

Tools are how an agent acts on the world — running business operations, calling APIs, reading and writing data. Each tool exposes itself to the LLM as a JSON Schema, and the agent invokes it through a unified interface. AgentScope organizes tool-related building blocks under three concepts:
  • Tool — any object implementing the AgentTool contract (typically by extending ToolBase) or any plain class whose methods are annotated with @Tool. Java refers to the latter as reflective function toolsToolkit#registerTool(Object) registers them by reflection automatically.
  • Toolkit — the container that registers tools, MCP clients, and skills, exposes their JSON schemas to the model, and dispatches each tool call to the matching tool object.
  • Tool Group — a named bundle of tools / MCP clients / skills that can be activated or deactivated as a unit. The agent uses a built-in meta tool to switch groups at runtime, keeping the context focused.
When you only call registerTool(Object), every @Tool method on the registered object joins the reserved "basic" group — always active. Add MCP clients, tool groups, or skills to extend the agent further — see the sections below.

Java tools

A Java tool is any object satisfying the AgentTool contract. AgentScope ships an abstract base class ToolBase for declaring tools with explicit parameter schemas, plus a reflective adapter that wraps plain methods into tools.

AgentTool / ToolBase contract

ToolBase is the abstract AgentTool implementation. The table below lists its properties and methods. Properties exposed to the agent and runtime: Methods that integrate with the execution flow and the permission system:

Built-in tools

AgentScope currently ships these built-in tools: Usage:
The Toolkit automatically registers the reset_tools meta tool and the load_skill_through_path skill viewer tool when extra tool groups or skills are present — you don’t need to instantiate them manually. See self-managed tools and Skill.

Custom tools (annotation-based)

The lightest-weight way: annotate plain methods with @Tool and @ToolParam, then call Toolkit#registerTool(Object). The framework derives the JSON schema from Java types and the description for the agent.
Common @Tool attributes:

Custom tools (extending ToolBase)

When you need a custom permission policy, external execution, or a more complex schema, extend ToolBase:

External execution tools

External-execution tools delegate the actual work outside the agent runtime — typically to a human operator or an external system. The agent emits RequireExternalExecutionEvent and pauses. When the next call feeds back matching ToolResultBlocks, the agent emits ExternalExecutionResultEvent with the same replyId before continuing. This pattern is the foundation of human-in-the-loop flows — some actions need human approval or human execution. To create an external tool, set externalTool to true and skip implementing callAsync:
Runnable examples: agentscope-examples/documentation/.../tool/ToolBaseExample.java, tool/ToolExecutionContextExample.java.

Receiving context

The RuntimeContext passed to agent.call(msgs, runtimeContext) is forwarded to every tool invocation in that reply. Tools can read it in two ways: annotation-based tools through automatic injection, and ToolBase.callAsync through ToolCallParam.

Automatic injection (@Tool methods)

Inside a @Tool method, any parameter without @ToolParam is treated as framework-injected. The resolution order: “User POJO” means: no @ToolParam, not primitive, not ContentBlock / Msg, not under java.* / javax.*. Every other parameter (those with @ToolParam, or that fall outside the above types) is read from the LLM-supplied JSON by name.
The caller registers the POJO by type once; every call then routes the matching instance to any tool that asks for it:
The model never sees userCtx — it is not part of the tool’s JSON schema. Full example: agentscope-examples/documentation/.../tool/ToolExecutionContextExample.java.

Accessing context in ToolBase.callAsync

Tools that extend ToolBase read context through ToolCallParam:
ToolCallParam also exposes getAgent(), getInput(), getEmitter(), getToolUseBlock(), and the deprecated getContext(). Prefer getRuntimeContext() in new code.

Coordinating between hooks and tools

The RuntimeContext string layer (put(String, Object) / get(String)) is a short-lived channel between middleware and tools during a single call — a middleware can write at onActing/onReasoning and a tool that injects a RuntimeContext parameter reads it. The instance is unbound from the agent (along with all hooks) when the call finishes.

MCP

AgentScope integrates with the Model Context Protocol (MCP), letting the agent talk to any MCP-compatible tool provider. The framework handles protocol negotiation, tool discovery, and result conversion. Three transports are supported:
  • STDIO — local process via stdin/stdout
  • SSE / Streamable HTTP — remote HTTP long-connection
MCP tools are exposed in the toolkit under the namespace mcp__{server_name}__{tool_name} to avoid collisions; tools marked readOnlyHint are auto-allowed by the permission system.

Registering MCP tools

Use McpClientBuilder to build an McpClientWrapper, then register it on the Toolkit:
Runnable examples: agentscope-examples/documentation/.../mcp/McpStdioExample.java, mcp/McpSseExample.java, mcp/McpStreamableHttpExample.java.

Skill

Skills are markdown-based instruction sets that extend an agent’s capabilities without writing new tool code. Each skill is a directory containing a SKILL.md file with frontmatter metadata and detailed instructions. Unlike tools, skills are not directly callable. The agent reads skill instructions through an auto-registered viewer tool named load_skill_through_path, then carries them out using whatever tools it already has.

Registering skills

Attach one or more AgentSkillRepository directly via ReActAgent.builder().skillRepository(...). At build() time the builder auto-installs DynamicSkillMiddleware, which rebuilds the skill prompt and tool groups from the configured sources on every call():
Multiple skillRepository(...) calls append in order (low → high priority); when two repositories expose a skill with the same name, the later entry wins. Use skillRepositories(List<AgentSkillRepository>) to replace the list. Reference implementations: agentscope-examples/documentation/.../skill/AgentSkillExample.java, skill/SkillWithToolGroupExample.java.

How skills work

When skills are present, the Toolkit performs a two-phase setup. Initialisation:
  • The toolkit scans every registered skill source and collects each skill’s name, description, and directory.
  • It auto-registers the built-in viewer tool load_skill_through_path (implemented in io.agentscope.core.skill.SkillToolFactory) into the skill-build-in-tools group.
  • It assembles a system-prompt fragment listing the available skills (names + descriptions) and instructing the agent to read full content via load_skill_through_path.
At runtime, the agent invokes the viewer with two required arguments: Example tool call payload:
Each successful call has two effects:
  1. Returns the requested content (the SKILL.md markdown, or the named resource file).
  2. Activates the skill — its associated tool group is enabled in the Toolkit, so any tools bundled with the skill become callable for the rest of the turn. If the requested path does not exist, the viewer returns an error that lists the available resource paths (with SKILL.md first) so the agent can retry.
A skill is not a tool — the agent cannot call it directly. The agent must read the instructions via load_skill_through_path first, then act on them with other tools.

Skill script execution: configuring shell tools

Skills only provide instructions — actual execution relies on the tools the agent already has. If a skill’s instructions involve running scripts (e.g. scripts/run.py), the agent needs shell access:
  • ReActAgent — register ShellCommandTool in the toolkit:
  • HarnessAgent — the harness module ships workspace-aware shell and file tools (execute, read_file, write_file, etc.) out of the box; no extra registration needed.

Skill + ToolGroup: on-demand tool disclosure

SkillToolGroup binds a group of tools to a skill name — the group activates automatically when the agent loads that skill, and stays hidden from the model’s schema otherwise, reducing context noise.
When the agent loads the data-analysis skill via load_skill_through_path, the analysis-tools group activates and its tools become immediately available. With enableMetaTool(true), the model can also manage group activation via reset_tools. Reference implementation: agentscope-examples/documentation/.../skill/SkillWithToolGroupExample.java.

Self-managed tools

The built-in meta tool (reset_tools) lets the agent self-manage which tool groups are active at runtime, keeping the context focused — only the tools relevant to the current task are exposed to the model.

Defining tool groups

ToolGroup is a named bundle of tools / MCP clients / skills. Register the group on the Toolkit and turn on the meta tool through the builder:
ToolGroup takes a name, a description, a scope (ToolGroupScope), and an initial active flag. The reserved name "basic" is auto-populated by Toolkit#registerTool(Object) and is always active.

Using the meta tool

Whenever there’s at least one non-basic tool group and enableMetaTool(true) is on, the Toolkit auto-registers reset_tools and exposes its schema to the agent. Each non-basic group becomes a boolean field; calling the meta tool declares the desired final state. Runtime behavior:
  • Tools in the "basic" group are always exposed; the meta tool does not touch them.
  • Each reset_tools call wholly overwrites the active set — any non-basic group not explicitly set to true is deactivated, regardless of its previous state.
  • For each group that just became active, its description and (if provided) instructions are spliced into the meta tool’s return value, telling the agent how to use it correctly.
  • Tools in inactive groups do not appear in the agent’s tool schema, leaving more context for the active toolset.
The meta tool’s input represents the final state of all groups, not a delta. Any group not explicitly set to true is deactivated regardless of previous state.

Further reading

Agent

How agents orchestrate tool calls in the ReAct loop

Permission System

Fine-grained control over which tools execute and when

Middleware

Use onion middlewares to intercept and rewrite tool calls

Human-in-the-Loop

External execution tools and approval workflows