Skills, Files, and Sandbox

Skills

ToolDescriptionPermission
list_skillsList the Agent Skills available in this organization — one line per skill (name and description).skill:read
load_skillLoad a specialized Agent Skill — a reusable SKILL.md instruction set.skill:read
create_skillCreate a new Agent Skill from a SKILL.md manifest.skill:create
update_skillUpdate an existing Agent Skill from a SKILL.md manifest.update on the skill (granted per item)
edit_skillMake a targeted edit to an existing Agent Skill without resending the whole SKILL.md.update on the skill (granted per item)

list_skills

Required RBAC permission: skill:read

This tool takes no arguments.

load_skill

Required RBAC permission: skill:read

Input

ParameterTypeRequiredDescription
namestringYesThe skill to load, as named by list_skills.
pathstringNoOptional. Omit (or pass an empty string) to load the skill's instructions and bundled-file list. Pass a resource path from that list (e.g. references/REFERENCE.md) to read one bundled file instead.

create_skill

Required RBAC permission: skill:create

Input

ParameterTypeRequiredDescription
initialGrantsobject[]No
initialGrants[].subjectobjectYes
initialGrants[].subject.type"user" | "team" | "serviceAccount" | "role" | "organization"Yes
initialGrants[].subject.idstring | "*"Yes
initialGrants[].actionsstring[]Yes
contentstringYesA complete SKILL.md manifest: a YAML frontmatter block with name and description (and optional license, compatibility, allowed-tools, agent, templated, metadata), followed by the Markdown instruction body. Set templated: true to render the body through Handlebars (e.g. {{user.name}}) at activation. allowed-tools is a space-separated list of tools the skill is pre-approved to use. agent names an agent the skill runs in — when set, activating the skill delegates it to that agent instead of loading the instructions into the caller's context.
filesobject[]NoOptional bundled resource files. Each is { path, content } with text content; the path prefix classifies the file — references/ for docs, scripts/ for code, assets/ for other files.
files[].pathstringYesResource path, e.g. references/API.md or scripts/run.py
files[].contentstringYesText content of the file
files[].encoding"utf8" | "base64"No

update_skill

Required RBAC permission: update on the skill (granted per item)

Input

ParameterTypeRequiredDescription
namestringYesThe current name of the skill to update, as named by list_skills.
contentstringYesA complete SKILL.md manifest: a YAML frontmatter block with name and description (and optional license, compatibility, allowed-tools, agent, templated, metadata), followed by the Markdown instruction body. Set templated: true to render the body through Handlebars (e.g. {{user.name}}) at activation. allowed-tools is a space-separated list of tools the skill is pre-approved to use. agent names an agent the skill runs in — when set, activating the skill delegates it to that agent instead of loading the instructions into the caller's context.
filesobject[]NoOptional. WHEN PROVIDED, REPLACES THE SKILL'S ENTIRE bundled file set. Omit it to leave the existing resource files untouched. There is no per-file patch: to change one file you must resend all of them — read the current files back first with load_skill (with and without a path).
files[].pathstringYesResource path, e.g. references/API.md or scripts/run.py
files[].contentstringYesText content of the file
files[].encoding"utf8" | "base64"No

edit_skill

Required RBAC permission: update on the skill (granted per item)

Input

ParameterTypeRequiredDescription
namestringYesThe current name of the skill to edit, as named by list_skills.
baseVersionintegerYesThe version the edit is based on — the version shown on the <skill_content>/<skill_file> frame you loaded with load_skill. The edit is rejected if the skill's head has moved past it.
pathstringNoOmit (or pass an empty string) to edit the SKILL.md body; pass a bundled file path (from the <skill_resources> list) to edit that file instead. Only text (utf8) files are editable — binary assets are not.
editsobject[]Nostr_replace edits applied in order to the target; the whole edit is atomic (any failure leaves the skill unchanged). This is the way to change a large SKILL.md without resending it all. Pass either edits or replacementContent, never both.
edits[].old_strstringYesExact text to replace; must occur exactly once in the target (add surrounding context to disambiguate).
edits[].new_strstringYesReplacement text (may be empty to delete).
replacementContentstringNoThe complete new content of the target, replacing it outright with no old_str matching — use it for a small file or a full rewrite. Prefer edits for the SKILL.md body so you don't resend the whole thing. Pass either edits or replacementContent, never both.

Files

ToolDescriptionPermission
search_filesList or search the conversation's persistent files.agent:read
read_fileRead a persistent file directly, without copying it into the sandbox.agent:read
save_fileWrite bytes you are providing inline in this call — text or base64 included in the arguments — to the conversation's persistent files.agent:read
edit_fileEdit an existing persistent file by replacing a snippet, keeping its id and filename.agent:read
delete_filePermanently delete a persistent file, identified by id (the id or ref from search_files, or a fileId from save_file) or by filename.agent:read
copy_fileExchange a file between this chat and the app the user has open: copy a chat/project file or a chat attachment INTO the open app's file store (so the app can load it), or copy a file OUT of the app...agent:read

search_files

Required RBAC permission: agent:read

Input

ParameterTypeRequiredDescription
querystringNoCase-insensitive substring matched against filenames only. Omit it (or pass empty) to list the files (the first 200).
scope"chat" | "app"No"chat" (default) = this chat's files; "app" = the files of the app the user has open, which is how you find what the app has produced before copying one out with copy_file.
project_idstringNoUse this project's files instead of the current chat's — how you reach project files when working outside a chat (get_project returns the id). Only projects you own or that are shared with you can be used. Cannot be used from a chat that already belongs to a different project, nor combined with scope: "app".

Output

FieldTypeRequiredDescription
filesobject[]Yes
files[].idstring | nullYesRow id (UUID), or null for a hand-placed file with no row.
files[].refstringYesStable handle for this file — pass it to read_file / upload_file / edit_file / delete_file. Works for hand-placed files too (where id is null).
files[].filenamestringYes
files[].mimeTypestringYes
files[].sizeBytesnumberYes
files[].createdAtstringYes

read_file

Required RBAC permission: agent:read

Input

ParameterTypeRequiredDescription
idstringNoId or ref of the file to read — the id or ref from search_files, or a fileId from save_file.
filenamestringNoFilename to read instead of id; rejected as ambiguous if more than one file shares the name.
offsetintegerNo1-based line number to start reading from. Defaults to 1.
limitintegerNoMaximum number of lines to read. Defaults to 2000.
project_idstringNoUse this project's files instead of the current chat's — how you reach project files when working outside a chat (get_project returns the id). Only projects you own or that are shared with you can be used. Cannot be used from a chat that already belongs to a different project, nor combined with scope: "app".

Output

FieldTypeRequiredDescription
kind"text" | "image"Yestext = numbered lines in the text content; image = the file is returned as an inline image block.
fileIdstring | nullYesThe file's id, or null for a hand-placed file with no row.
filenamestringYes
mimeTypestringYes
sizeBytesnumberYes
totalLinesnumberNo
startLinenumberNo
returnedLinesnumberNo
truncatedbooleanNoTrue when more lines follow the returned window (raise offset to continue).
contentstringNoThe returned window's text, WITHOUT the line numbers — the file's own bytes. Present for text reads so a structured consumer (an app via archestra.tools.call, which unwraps to structuredContent and never sees the text block) gets usable content instead of only metadata. The numbered rendering stays in the text output, where line numbers are what makes edit_file addressable.

save_file

Required RBAC permission: agent:read

Input

ParameterTypeRequiredDescription
filenamestringYesPlain filename including extension (e.g. "joke.md"). No paths.
contentstringNoUTF-8 text content of the file.
contentBase64stringNoBase64-encoded binary content.
mimeTypestringNoOptional MIME type. Sniffed from the bytes when omitted.
overwritebooleanNoReplace an existing file of the same name in place, keeping its id. Default false errors if the name is already taken.
project_idstringNoUse this project's files instead of the current chat's — how you reach project files when working outside a chat (get_project returns the id). Only projects you own or that are shared with you can be used. Cannot be used from a chat that already belongs to a different project, nor combined with scope: "app".

Output

FieldTypeRequiredDescription
fileIdstringYes
filenamestringYes
projectNamestring | nullYesOwning project when saved into a project; null otherwise.
mimeTypestringYes
sizeBytesnumberYes
overwrittenbooleanYesTrue when an existing same-named file was replaced in place.

edit_file

Required RBAC permission: agent:read

Input

ParameterTypeRequiredDescription
idstringNoId of the file to edit — the id or ref from search_files, or a fileId from save_file.
filenamestringNoFilename to edit instead of id; rejected as ambiguous if more than one file shares the name.
old_stringstringYesThe exact text to replace; must match the file's current content (read it first with read_file). Include enough surrounding context to be unique unless replace_all is set.
new_stringstringYesThe text to insert in place of old_string.
replace_allbooleanNoReplace every occurrence of old_string. Default false replaces a single occurrence and errors if old_string is not unique.
project_idstringNoUse this project's files instead of the current chat's — how you reach project files when working outside a chat (get_project returns the id). Only projects you own or that are shared with you can be used. Cannot be used from a chat that already belongs to a different project, nor combined with scope: "app".

Output

FieldTypeRequiredDescription
fileIdstringYes
filenamestringYes
mimeTypestringYes
sizeBytesnumberYes
replacementsnumberYesHow many occurrences of old_string were replaced.

delete_file

Required RBAC permission: agent:read

Input

ParameterTypeRequiredDescription
idstringNoId of the file to delete — the id or ref from search_files, or a fileId from save_file.
filenamestringNoFilename to delete instead of id; rejected as ambiguous if more than one file shares the name.
project_idstringNoUse this project's files instead of the current chat's — how you reach project files when working outside a chat (get_project returns the id). Only projects you own or that are shared with you can be used. Cannot be used from a chat that already belongs to a different project, nor combined with scope: "app".

Output

FieldTypeRequiredDescription
fileIdstringYesThe deleted file's id, or its ref for a rowless file.
filenamestringYes
deletedtrueYes

copy_file

Required RBAC permission: agent:read

Input

ParameterTypeRequiredDescription
fromobjectYesWhere the bytes come from: {"type":"chat_file","id"|"filename"} | {"type":"chat_attachment","attachmentId"|"filename"} | {"type":"app_file","id"|"filename"}.
from.type"chat_file" | "chat_attachment" | "app_file"Yes
from.idstringNoWhen type="chat_file": File id from search_files. When type="app_file": File id in the app's store.
from.filenamestringNoWhen type="chat_file": Filename instead of id; ambiguous names rejected. When type="chat_attachment": Original filename of an attachment in this conversation (when you have no id). If the same name was attached more than once, the newest one wins. When type="app_file": Filename instead of id.
from.attachmentIdstringNoId of an attachment uploaded to THIS conversation.
toobjectYesWhere the copy lands.
to.scope"chat" | "app"Yes"app" = the open app's per-viewer store; "chat" = this chat's files (the project's files when this chat belongs to a project).
to.filenamestringNoDestination filename; defaults to the source's name. Plain filename, no paths.
to.overwritebooleanNoReplace an existing same-named destination file in place. Default false: a duplicate name is an error.

Output

FieldTypeRequiredDescription
fileIdstringYesId of the copy at the destination.
filenamestringYes
mimeTypestringYes
sizeBytesnumberYes
destination"conversation" | "project" | "app"YesThe scope the copy landed in.
overwrittenbooleanYes

Code Sandbox

These tools are served only when the code runtime is enabled — set ARCHESTRA_CODE_RUNTIME_DAGGER_RUNNER_HOST, or ARCHESTRA_CODE_RUNTIME_ENABLED=true together with an orchestrator kubeconfig. Without it they do not appear in tools/list. The Code Sandbox page covers what the runtime is and how an agent uses it.

ToolDescriptionPermission
run_commandExecute a shell command in the conversation's sandbox (Debian, working dir /home/sandbox).agent:read
download_fileCopy a file that already exists at a path in the conversation's sandbox into the conversation's persistent files.agent:read
upload_filePlace a file into the conversation's sandbox at a path, from a chat attachment, inline base64, inline text, or one of your persistent files.agent:read

run_command

Required RBAC permission: agent:read

Input

ParameterTypeRequiredDescription
commandstringYesShell command to execute (bash). Runs in the sandbox's working directory (or cwd when provided). Returns text output only — use download_file for generated files.
cwdstringNoOptional absolute path inside the container. Defaults to the sandbox's working directory (/home/sandbox).
timeoutSecondsintegerNoOptional wall-clock limit in seconds, capped at the deployment maximum.
targetobjectNoWhich sandbox to use. Omit (or leave empty) for the conversation's default sandbox (created on first use), which holds the conversation's attachments. Pass { "fresh": true } for a new empty sandbox, or { "id": "<uuid>" } to target a specific one.
target.freshbooleanNoSet true for a brand-new empty sandbox, without the conversation's attachments or earlier work; its id is returned.
target.idstringNoAn existing sandbox id (UUID) returned by an earlier call.

Output

FieldTypeRequiredDescription
commandIdstringYes
sandboxIdstringYes
commandstringYes
cwdstring | nullYes
stdoutstringYes
stderrstringYes
exitCodenumberYes
durationMsnumberYes
timedOutbooleanYes
truncatedbooleanYes
binaryStrippedbooleanYesTrue when NUL bytes were stripped from stdout/stderr before storage.
stagingNoticesstring[]YesNotices about chat attachments that could not be auto-staged (e.g. too large). Empty when all attachments are available in the sandbox.

download_file

Required RBAC permission: agent:read

Input

ParameterTypeRequiredDescription
pathstringYesPath to the file inside the container — absolute, or relative to the sandbox's working directory.
mimeTypestringNoOptional MIME type recorded with the file. Sniffed from the bytes when omitted.
overwritebooleanNoReplace an existing same-named persistent file in place, keeping its id. Default false errors if the name is already taken.
targetobjectNoWhich sandbox to use. Omit (or leave empty) for the conversation's default sandbox (created on first use), which holds the conversation's attachments. Pass { "fresh": true } for a new empty sandbox, or { "id": "<uuid>" } to target a specific one.
target.freshbooleanNoSet true for a brand-new empty sandbox, without the conversation's attachments or earlier work; its id is returned.
target.idstringNoAn existing sandbox id (UUID) returned by an earlier call.

Output

FieldTypeRequiredDescription
fileIdstringYes
sandboxIdstringYes
pathstringYes
mimeTypestringYes
sizeBytesnumberYes
stagingNoticesstring[]YesNotices about chat attachments that could not be auto-staged (e.g. too large). Empty when all attachments are available in the sandbox.
overwrittenbooleanYesTrue when an existing same-named file was replaced in place.

upload_file

Required RBAC permission: agent:read

Input

ParameterTypeRequiredDescription
pathstringYesDestination path inside the container — absolute under /skills or /home/sandbox, or relative to the sandbox's working directory.
sourceobjectYesWhere the file bytes come from. One of four shapes, each tagged by a type: a chat attachment ({"type":"chat_attachment","attachmentId"|"filename":...}), inline base64 ({"type":"base64","dataBase64":...}), inline text ({"type":"text","text":"print(1)"}), or a file from the user's persistent files ({"type":"my_file","filename":...}, found via search_files). Use this to place input bytes; to create a file the sandbox will then run or read, write it with run_command instead.
source.type"chat_attachment" | "base64" | "text" | "my_file"Yes
source.attachmentIdstringNoId of an attachment in the current conversation. The bytes are copied directly and never enter your context.
source.filenamestringNoWhen type="chat_attachment": Original filename of an attachment in this conversation (when you have no id). If the same name was attached more than once, the newest one wins. When type="my_file": Exact filename of a persistent file (when you have no id).
source.dataBase64stringWhen type="base64"Base64-encoded file bytes.
source.mimeTypestringNo
source.originalNamestringNo
source.textstringWhen type="text"UTF-8 text content of the file.
source.idstringNoId or ref of a persistent file, as returned by search_files (id for stored files, ref for hand-placed ones).
targetobjectNoWhich sandbox to use. Omit (or leave empty) for the conversation's default sandbox (created on first use), which holds the conversation's attachments. Pass { "fresh": true } for a new empty sandbox, or { "id": "<uuid>" } to target a specific one.
target.freshbooleanNoSet true for a brand-new empty sandbox, without the conversation's attachments or earlier work; its id is returned.
target.idstringNoAn existing sandbox id (UUID) returned by an earlier call.

Output

FieldTypeRequiredDescription
uploadIdstringYes
sandboxIdstringYes
pathstringYes
mimeTypestringYes
sizeBytesnumberYes