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
AgentToolcontract (typically by extendingToolBase) or any plain class whose methods are annotated with@Tool. Java refers to the latter as reflective function tools —Toolkit#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.
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 theAgentTool 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.
@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 emitsRequireExternalExecutionEvent 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:
agentscope-examples/documentation/.../tool/ToolBaseExample.java, tool/ToolExecutionContextExample.java.
Receiving context
TheRuntimeContext 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.
call then routes the matching instance to any tool that asks for it:
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
TheRuntimeContext 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__{server_name}__{tool_name} to avoid collisions; tools marked readOnlyHint are auto-allowed by the permission system.
Registering MCP tools
UseMcpClientBuilder to build an McpClientWrapper, then register it on the Toolkit:
- STDIO
- Streamable HTTP
- SSE
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 aSKILL.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 moreAgentSkillRepository 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():
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, theToolkit 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 inio.agentscope.core.skill.SkillToolFactory) into theskill-build-in-toolsgroup. - 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.
Example tool call payload:
- Returns the requested content (the
SKILL.mdmarkdown, or the named resource file). - 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 requestedpathdoes not exist, the viewer returns an error that lists the available resource paths (withSKILL.mdfirst) 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— registerShellCommandToolin 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.
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 andenableMetaTool(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_toolscall wholly overwrites the active set — any non-basic group not explicitly set totrueis 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.
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