microsoft/agora-workbench
> Drive Agora Workbench MCP servers — any server that exposes an execute_*_code tool — by writing Python that runs inside the server's persistent kernel, where its tools and libraries already live. Activate whenever an execute_*_code tool is connected and the user asks for work that could run there, BEFORE reaching for local shell, standalone scripts, or package installs. The server already has the environment; call its tool instead of rebuilding the capability locally.
npx skills add https://github.com/microsoft/agora-workbench --skill agora-workbench
execute_{server}_code tool, that tool is the way to do the work — its tools and libraries are already installed in the server's kernel. Do not install packages or write standalone scripts locally to replicate what the server provides; call the tool. Even if the server's source is visible in your workspace, use the live tool — don't copy or re-implement it.execute_{server}_code.execute_{server}_code calls. Do not recompute or re-import unnecessarily.search_{server}_tools before assuming a function exists. Never guess tool names.Before writing any code, discover what is available:
search_{server}_tools(query="", top=999) # Full catalog
search_{server}_tools(query="molecular weight") # Targeted search
search_{server}_tools(query="screening", category="skills") # Skills only
tools (callable functions) and skills (multi-step workflows).load_{server}_skill(skill_name="...") and follow its instructions.The primary MCP tool is execute_{server}_code:
| Parameter | Usage |
|-----------|-------|
| code | Python code that calls the server's functions from the kernel namespace |
| description | One-sentence summary shown to the user — always set this |
| timeout | Seconds before execution is killed (increase for heavy computation) |
| background | Set True for long-running jobs; poll with {server}_check_job(job_id=...) |
| execution_session_id | Existing execution session to resume from another agent or MCP connection |
# 1. Discover
search_{server}_tools(query="data processing")
# 2. Execute
execute_{server}_code(
description="Process input data and extract results",
code="result = process_data(input_id='item_001')\nprint(result)",
timeout=60
)
stderr and error from the result.ValueError, it means invalid input. Read the message and adjust arguments.execute_{server}_code call.returned session_id as execution_session_id to execute_{server}_code.
This is not the MCP transport session ID; unknown, expired, or unauthorized
IDs fail rather than creating a new session.
{server}_inspect_session(session_id=...) to see what variables exist and check background job status.{server}_close_session(session_id=...) only when done with a server entirely.{server}_list_sessions() to see active sessions.See the artifacts sub-skill for data fetching, cross-server transfer, and destination tag details.
For complex multi-step tasks with ordered dependencies, use the state graph:
plan_{server}_workflow(mode="overview") # See the full graph
plan_{server}_workflow(mode="path", current_state="...", target_state="...") # Get a sequence
See the workflow-planning sub-skill for full mode details and skill loading patterns.
See the async-execution sub-skill for submitting background jobs for long-running code and parallel execution across multiple inputs.
Stdout from execute_{server}_code is returned in the MCP tool response and
consumed as agent context tokens. Overflowing this with large objects wastes
context, triggers server-side truncation, and can degrade agent reasoning.
print(df), print(long_list),or print(json.dumps(big_dict)).
.head(), .shape, len(), .describe(),.columns.tolist(), or slicing to extract only what you need.
inspect it with targeted follow-up calls:
# ✓ Good — store and summarize
result = compute_expensive_thing(...)
print(f"Shape: {result.shape}, columns: {result.columns.tolist()}")
print(result.head(5).to_string())
# ✗ Bad — dumps entire object into MCP response
result = compute_expensive_thing(...)
print(result)
agora_output("name") (or theAGORA_OUTPUT_DIR variable) for data intended for the user; use /tmp for
intermediate scratch files you'll read back server-side. See the
artifacts sub-skill for the output path helpers.
{server}_send for cross-server transfers — never serializelarge objects through stdout to paste into another server call.
slice it: print(df.iloc[50:100].to_string()).
The server truncates stdout/stderr that exceeds its configured threshold
(default 50 KB). The truncated response includes a notice. While this prevents
context overflow, the lost information may require re-execution — so avoid
hitting the limit proactively.
pip/uv install packages or write standalone local scripts to do work a connected execute_{server}_code tool already covers — the kernel already has the environment. Even if the server's source is in your workspace, call the live tool; do not copy or re-implement it.AGORA_OUTPUT_DIR.{server}_send can transfer it server-to-server.background=True and poll.Take microsoft/agora-workbench from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.