import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic();
const WORKSPACE_ID = "ws_123";
const ARG_API_KEY = "YOUR_API_KEY";
const ARG_BASE = "https://api.arg.ai/api";
// Define arg.ai workspace tools
const tools: Anthropic.Tool[] = [
{
name: "run_bash",
description: "Run a shell command in the workspace sandbox",
input_schema: {
type: "object",
properties: { command: { type: "string" } },
required: ["command"],
},
},
{
name: "read_file",
description: "Read a file from the workspace",
input_schema: {
type: "object",
properties: {
path: { type: "string" },
offset: { type: "integer" },
limit: { type: "integer" },
},
required: ["path"],
},
},
{
name: "write_file",
description: "Write a file to the workspace",
input_schema: {
type: "object",
properties: {
path: { type: "string" },
content: { type: "string" },
},
required: ["path", "content"],
},
},
{
name: "edit_file",
description: "Replace a string in a file",
input_schema: {
type: "object",
properties: {
path: { type: "string" },
old_string: { type: "string" },
new_string: { type: "string" },
},
required: ["path", "old_string", "new_string"],
},
},
{
name: "grep",
description: "Search file contents with a regex pattern",
input_schema: {
type: "object",
properties: {
pattern: { type: "string" },
path: { type: "string" },
include: { type: "string" },
},
required: ["pattern"],
},
},
];
// Map tool names to arg.ai endpoints
const TOOL_ENDPOINTS: Record<string, string> = {
run_bash: "run-bash",
read_file: "read-file",
write_file: "write-file",
edit_file: "edit-file",
grep: "grep",
};
async function callTool(name: string, args: Record<string, unknown>) {
const endpoint = TOOL_ENDPOINTS[name];
const res = await fetch(
`${ARG_BASE}/workspaces/${WORKSPACE_ID}/tools/${endpoint}`,
{
method: "POST",
headers: {
"X-API-Key": ARG_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify(args),
}
);
return res.json();
}
// Agent loop
const messages: Anthropic.MessageParam[] = [
{ role: "user", content: "List the files in /home/user/project and read the README" },
];
while (true) {
const response = await anthropic.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 4096,
tools,
messages,
});
if (response.stop_reason === "tool_use") {
const assistantContent = response.content;
messages.push({ role: "assistant", content: assistantContent });
const toolResults: Anthropic.ToolResultBlockParam[] = [];
for (const block of assistantContent) {
if (block.type === "tool_use") {
const result = await callTool(block.name, block.input as Record<string, unknown>);
toolResults.push({
type: "tool_result",
tool_use_id: block.id,
content: JSON.stringify(result),
});
}
}
messages.push({ role: "user", content: toolResults });
} else {
const text = response.content.find((b) => b.type === "text");
console.log(text?.text);
break;
}
}
import json
import requests
import anthropic
WORKSPACE_ID = "ws_123"
ARG_API_KEY = "YOUR_API_KEY"
ARG_BASE = "https://api.arg.ai/api"
# Define arg.ai workspace tools
tools = [
{
"name": "run_bash",
"description": "Run a shell command in the workspace sandbox",
"input_schema": {
"type": "object",
"properties": {"command": {"type": "string"}},
"required": ["command"],
},
},
{
"name": "read_file",
"description": "Read a file from the workspace",
"input_schema": {
"type": "object",
"properties": {
"path": {"type": "string"},
"offset": {"type": "integer"},
"limit": {"type": "integer"},
},
"required": ["path"],
},
},
{
"name": "write_file",
"description": "Write a file to the workspace",
"input_schema": {
"type": "object",
"properties": {
"path": {"type": "string"},
"content": {"type": "string"},
},
"required": ["path", "content"],
},
},
{
"name": "edit_file",
"description": "Replace a string in a file",
"input_schema": {
"type": "object",
"properties": {
"path": {"type": "string"},
"old_string": {"type": "string"},
"new_string": {"type": "string"},
},
"required": ["path", "old_string", "new_string"],
},
},
{
"name": "grep",
"description": "Search file contents with a regex pattern",
"input_schema": {
"type": "object",
"properties": {
"pattern": {"type": "string"},
"path": {"type": "string"},
"include": {"type": "string"},
},
"required": ["pattern"],
},
},
]
TOOL_ENDPOINTS = {
"run_bash": "run-bash",
"read_file": "read-file",
"write_file": "write-file",
"edit_file": "edit-file",
"grep": "grep",
}
def call_tool(name: str, args: dict) -> dict:
endpoint = TOOL_ENDPOINTS[name]
resp = requests.post(
f"{ARG_BASE}/workspaces/{WORKSPACE_ID}/tools/{endpoint}",
headers={"X-API-Key": ARG_API_KEY, "Content-Type": "application/json"},
json=args,
)
return resp.json()
# Agent loop
client = anthropic.Anthropic()
messages = [
{"role": "user", "content": "List the files in /home/user/project and read the README"},
]
while True:
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=4096,
tools=tools,
messages=messages,
)
if response.stop_reason == "tool_use":
messages.append({"role": "assistant", "content": response.content})
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = call_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result),
})
messages.append({"role": "user", "content": tool_results})
else:
text = next(b for b in response.content if b.type == "text")
print(text.text)
break
How it works
- Define tools — each arg.ai tool endpoint is registered as a tool with matching parameters
- Run the agent loop — send messages to Claude; when the model returns
tool_useblocks, execute them against the arg.ai API - Return results — pass tool output back as
tool_resultblocks so the model can continue