Which one
- MCP client (Claude Desktop, Cursor, VS Code): no adapter needed. Point it at
runeward mcp. See rest-api.md and thedist/mcp/manifest. - Python agent (LangChain, CrewAI, LlamaIndex, OpenAI Agents SDK, Strands): the
runewardpackage. - TypeScript agent (Vercel AI SDK, LangChain.js, Strands): the
@runeward/sdkpackage. - Your own code: use either
RunewardClientalone, a thin typed REST wrapper.
All target the control plane from runeward serve (default http://localhost:8080) and share one method surface: create_sandbox, shell, python, node, read_file/write_file/list_files/search_files, list_approvals/approve/deny, kill_sandbox, audit/verify_audit. These names keep their original spellings, although the matching MCP tools are now runeward_create_citadel, runeward_kill_citadel and runeward_list_conclave.
If runeward serve uses a token (--token / RUNEWARD_API_TOKEN) or RBAC, pass it: RunewardClient(..., token="...") or new RunewardClient({ token: "..." }).
Verdicts
Raw clients raise typed exceptions; framework tools return short strings the model can read.
| Verdict | Meaning | What the agent must do |
|---|---|---|
allow |
The action ran | For shell, still check exit_code |
deny |
Policy refused it | Do not retry the same action. Choose an allowed approach or report the block. |
require-approval |
A human must sign off | Pause and surface the approval_id. Resolve it in the dashboard, the CLI or POST /v1/conclave/{id}/{approve,deny}. |
Use the tightest policy (Charter) that lets the task succeed.
Python
The core client uses only the standard library. Framework extras load lazily.
python -m pip install runeward
python -m pip install 'runeward[langchain]' # or crewai, llamaindex, openai-agents, strands
For repository development: python -m pip install -e ./adapters/python.
from runeward import RunewardClient, RunewardDenied, RunewardApprovalRequired
rw = RunewardClient("http://localhost:8080")
sbx = rw.create_sandbox("dev")
print(rw.shell(sbx["id"], ["python3", "--version"])["stdout"])
try:
rw.shell(sbx["id"], ["rm", "-rf", "/"])
except RunewardDenied as e:
print("blocked by policy:", e.reason) # do NOT retry
except RunewardApprovalRequired as e:
print("needs a human:", e.approval_id) # pause for an operator
rw.kill_sandbox(sbx["id"])
Each framework module has a make_runeward_tools(client) factory that returns native tools named runeward_*:
| Framework | Import | Pass tools to |
|---|---|---|
| LangChain | runeward.langchain_tools |
AgentExecutor / create_react_agent(...) |
| CrewAI | runeward.crewai_tools |
crewai.Agent(tools=tools, ...) |
| LlamaIndex | runeward.llamaindex_tools |
FunctionAgent(tools=tools, ...) / ReActAgent |
| OpenAI Agents SDK | runeward.openai_agents_tools |
agents.Agent(name="...", tools=tools) |
| Strands Agents SDK | runeward.strands_tools |
strands.Agent(tools=tools) |
Per-framework examples are in the Python adapter README.
TypeScript
The core client uses global fetch with no runtime dependencies (Node 18+, Deno, Bun, browsers). Tool wrappers need optional peer dependencies, loaded lazily.
npm install @runeward/sdk # core client
npm install @runeward/sdk ai zod # + Vercel AI SDK tools
npm install @runeward/sdk @langchain/core zod
npm install @runeward/sdk @strands-agents/sdk zod
For repository development: npm install ./adapters/typescript.
import { RunewardClient } from "@runeward/sdk";
const rw = new RunewardClient({ baseUrl: "http://localhost:8080" });
const sbx = await rw.createSandbox("dev");
console.log((await rw.shell(sbx.id, ["node", "--version"])).stdout);
await rw.killSandbox(sbx.id);
Each subpath exports an async makeRunewardTools(client):
| Framework | Import from |
|---|---|
| Vercel AI SDK | @runeward/sdk/ai-tools |
| LangChain.js | @runeward/sdk/langchain-tools |
| Strands Agents SDK | @runeward/sdk/strands-tools |
Pass the result as tools to generateText(...), createReactAgent(...) or new Agent(...).
More in the TypeScript adapter README.
Written from docs/adapters.md at commit 1ee29ff4ab36. Rune Box is open source under Apache-2.0.