Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.agentscope.io/llms.txt

Use this file to discover all available pages before exploring further.

Overview

A workspace is the agent’s execution environment. It supplies the agent with three categories of resources — tools (built-in tools and MCPs), skills, and context offloading for compressed messages and oversized tool results — and owns the lifecycle of the resources living inside it (MCP server processes, dynamically added skills, offloaded files). AgentScope ships three workspace implementations — local filesystem, Docker container, and E2B cloud sandbox — plus a workspace manager that allocates and tracks workspaces in Agent Service so that multi-tenant deployments can map workspaces to users, agents, or sessions without rewriting the agent code. For Docker and E2B, MCP servers run inside the isolated environment; the host reaches them through an in-workspace gateway covered in MCP Gateway.

Use a Workspace

Create a Workspace

AgentScope ships three workspace implementations, one per execution backend:
ClassBackend
LocalWorkspaceHost filesystem (built-in tools run host-side)
DockerWorkspaceDocker container via aiodocker
E2BWorkspaceE2B cloud sandbox via AsyncSandbox
Each backend has its own persistence model and directory layout — pick the tab matching your target environment:
LocalWorkspace persists state directly under workdir on the host filesystem — restarts simply re-open the same directory. The directory has the following layout:
{workdir}/
├── .mcp           # registered MCP client configs (JSON array)
├── data/          # offloaded multimodal payloads (deduped by SHA-256)
├── skills/        # skill subdirectories, each with SKILL.md
│   └── .skills    # name/hash index for de-duplication
└── sessions/      # per-session context.jsonl and tool-result files
from agentscope.workspace import LocalWorkspace

workspace = LocalWorkspace(
    workdir="/data/my-workspace",
    default_mcps=[],
    skill_paths=["./skills/web-search"],
)
await workspace.initialize()
default_mcps and skill_paths are seed-time inputs — they populate a brand-new workspace on first initialize(). On restart the workspace restores its MCP list from the persisted .mcp file, so re-passing the seeds is a no-op. All three implementations share the same WorkspaceBase interface, so the same agent code runs against any backend. The methods fall into four roles:
initialize() / close() / reset()
lifecycle (developer)
Provision the workspace, release its resources, and clear per-session state for pool reuse. Also drives the async with protocol.
list_tools() / list_mcps() / list_skills() / get_instructions()
discovery (agent)
Enumerate the built-in tools, active MCPClient instances, available skills, and a workspace-specific system prompt fragment.
offload_context(session_id, msgs) / offload_tool_result(session_id, tool_result)
offloading (agent)
Persist compressed context or oversized tool results into sessions/<session_id>/ and return a reference path the agent stores in place of the original payload.
add_mcp(mcp_client) / remove_mcp(name) / add_skill(skill_path) / remove_skill(name)
dynamic management (user)
Register or remove MCP servers and skills at runtime; changes are persisted to .mcp and skills/ so they survive restarts.

Integrate with Agent

A workspace plugs into Agent along two axes — as a source of tools / MCPs / skills, and as the offloader for context compression:
from agentscope import Agent
from agentscope.tool import Toolkit
from agentscope.workspace import LocalWorkspace

workspace = LocalWorkspace(workdir="./my-workspace")
await workspace.initialize()

agent = Agent(
    name="coder",
    system_prompt="You are a coding assistant.",
    model=model,
    toolkit=Toolkit(
        tools=await workspace.list_tools(),
        mcps=await workspace.list_mcps(),
        skills_or_loaders=await workspace.list_skills(),
    ),
    offloader=workspace,
)
AxisWiringWhat the agent gets
ResourcesToolkit(tools=..., mcps=..., skills_or_loaders=...)Built-in tools, MCP-provided tools, and skills available in the workspace
OffloadingAgent(offloader=workspace)When context compression triggers or a tool result exceeds the size limit, the agent calls workspace.offload_context() / offload_tool_result() and stores the returned reference path in place of the original payload
Agent only depends on the Offloader protocol (offload_context / offload_tool_result), so any object satisfying that protocol can take the role — the workspace is the typical implementation.
Because the workspace exposes its resources as flat lists, you can partition them into ToolGroups when the agent has too many tools to keep all active at once. Pass the groups to Toolkit(tool_groups=[...]) and the agent activates them on demand through the built-in ResetTools meta-tool — only the reserved basic group stays always-on.
from agentscope.tool import Toolkit, ToolGroup

mcps = await workspace.list_mcps()
skills = await workspace.list_skills()

toolkit = Toolkit(
    tools=await workspace.list_tools(),         # always active (basic group)
    tool_groups=[
        ToolGroup(name="search", description="Web search and retrieval.",
                  mcps=[m for m in mcps if m.name.startswith("search")]),
        ToolGroup(name="coding", description="Code editing skills.",
                  skills_or_loaders=skills),
    ],
)

Workspace Manager

A workspace manager is the allocator and lifecycle owner for workspaces in a multi-tenant service. It is used by Agent Service to map incoming requests to the right workspace instance and to release them on shutdown. A manager is responsible for:
  • Allocationcreate_workspace(user_id, agent_id, session_id) builds a fresh workspace and tracks it; get_workspace(..., workspace_id) returns a live one or rebuilds on cache miss.
  • Caching and TTL — workspaces are cached in memory keyed by workspace_id; idle entries are evicted after ttl seconds and their underlying resources (containers, sandboxes, MCP processes) torn down.
  • Isolation policy — the manager decides whether two requests share a workspace; the built-in managers all isolate by agent_id, but WorkspaceManagerBase is a tiny abstract class that can be subclassed for per-user or per-session policies.
  • Cleanupclose(workspace_id) evicts a single entry and close_all() drains the cache on app shutdown.
AgentScope ships three managers, each paired with one workspace backend and all isolating per agent:
ClassPairs withIsolation keyCache key
LocalWorkspaceManagerLocalWorkspaceagent_id (workdir = <basedir>/<agent_id>)workspace_id
DockerWorkspaceManagerDockerWorkspace(user_id, agent_id) (workdir = <basedir>/<user_id>/<agent_id>)workspace_id
E2BWorkspaceManagerE2BWorkspaceagent_id (workspace metadata, no host workdir)workspace_id
Construct a manager and use it like a workspace allocator:
from agentscope.app._manager import LocalWorkspaceManager

manager = LocalWorkspaceManager(
    basedir="/data/workspaces",
    skill_paths=["./skills/coding"],
    ttl=3600.0,
)

ws = await manager.create_workspace(
    user_id="user-1",
    agent_id="agent-42",
    session_id="session-abc",
)

# Later, on a follow-up request for the same workspace:
ws = await manager.get_workspace(
    user_id="user-1",
    agent_id="agent-42",
    session_id="session-abc",
    workspace_id=ws.workspace_id,
)
To plug a different isolation policy (per-user, per-session, or hybrid), subclass WorkspaceManagerBase and override get_workspace / create_workspace with your own keying — see Agent Service · Workspace implementation and isolation for how the service wires a manager into the request lifecycle.
In the agent service, the workspace manager is bound to the FastAPI app state during the lifespan and shared across all requests; routers acquire workspaces through get_workspace_manager dependency injection. See Agent Service for the full integration.

MCP Gateway

DockerWorkspace and E2BWorkspace cannot register host-side MCP clients directly — the MCP servers live inside the container or sandbox, and stdio sessions cannot cross that boundary. AgentScope solves this with an MCP gateway: a lightweight FastAPI process that runs inside the workspace, owns the upstream MCP sessions, and exposes them over a single authenticated HTTP endpoint that the host talks to. The gateway exposes a small REST surface — GET /health, GET/POST/DELETE /mcps, GET /mcps/{name}/tools, POST /mcps/{name}/tools/{tool} — protected by a per-workspace bearer token minted at each initialize(). On the host, two adapters preserve the standard interfaces:
  • GatewayMCPClient — an MCPClient subclass whose connect / close / list_tools calls become HTTP requests against the gateway, so the rest of the toolkit cannot tell it apart from a local MCP client.
  • GatewayMCPTool — a ToolBase subclass whose __call__ posts to /mcps/{name}/tools/{tool} and reconstructs the returned ToolChunk.
This abstraction keeps the agent-side code identical across all three workspace backends — a workspace returns MCPClient instances from list_mcps() regardless of whether the upstream session lives on the host (LocalWorkspace) or inside an isolated environment (DockerWorkspace / E2BWorkspace).

Further Reading

Agent

Agent abstraction, the ReAct loop, and offloader integration

Tool

Built-in tools, MCP integration, and toolkit composition

Agent Service

Multi-tenant service that drives the workspace manager

Context

Context compression and the offloading triggers