Optional. 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.
A 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.
files
object[]
No
Optional 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[].path
string
Yes
Resource path, e.g. references/API.md or scripts/run.py
files[].content
string
Yes
Text content of the file
files[].encoding
"utf8" | "base64"
No
update_skill
Required RBAC permission: update on the skill (granted per item)
Input
Parameter
Type
Required
Description
name
string
Yes
The current name of the skill to update, as named by list_skills.
content
string
Yes
A 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.
files
object[]
No
Optional. 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[].path
string
Yes
Resource path, e.g. references/API.md or scripts/run.py
files[].content
string
Yes
Text content of the file
files[].encoding
"utf8" | "base64"
No
edit_skill
Required RBAC permission: update on the skill (granted per item)
Input
Parameter
Type
Required
Description
name
string
Yes
The current name of the skill to edit, as named by list_skills.
baseVersion
integer
Yes
The 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.
path
string
No
Omit (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.
edits
object[]
No
str_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_str
string
Yes
Exact text to replace; must occur exactly once in the target (add surrounding context to disambiguate).
edits[].new_str
string
Yes
Replacement text (may be empty to delete).
replacementContent
string
No
The 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.
Exchange 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...
Case-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_id
string
No
Use 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
Field
Type
Required
Description
files
object[]
Yes
files[].id
string | null
Yes
Row id (UUID), or null for a hand-placed file with no row.
files[].ref
string
Yes
Stable 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).
Id or ref of the file to read — the id or ref from search_files, or a fileId from save_file.
filename
string
No
Filename to read instead of id; rejected as ambiguous if more than one file shares the name.
offset
integer
No
1-based line number to start reading from. Defaults to 1.
limit
integer
No
Maximum number of lines to read. Defaults to 2000.
project_id
string
No
Use 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
Field
Type
Required
Description
kind
"text" | "image"
Yes
text = numbered lines in the text content; image = the file is returned as an inline image block.
fileId
string | null
Yes
The file's id, or null for a hand-placed file with no row.
filename
string
Yes
mimeType
string
Yes
sizeBytes
number
Yes
totalLines
number
No
startLine
number
No
returnedLines
number
No
truncated
boolean
No
True when more lines follow the returned window (raise offset to continue).
content
string
No
The 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.
Plain filename including extension (e.g. "joke.md"). No paths.
content
string
No
UTF-8 text content of the file.
contentBase64
string
No
Base64-encoded binary content.
mimeType
string
No
Optional MIME type. Sniffed from the bytes when omitted.
overwrite
boolean
No
Replace an existing file of the same name in place, keeping its id. Default false errors if the name is already taken.
project_id
string
No
Use 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
Field
Type
Required
Description
fileId
string
Yes
filename
string
Yes
projectName
string | null
Yes
Owning project when saved into a project; null otherwise.
mimeType
string
Yes
sizeBytes
number
Yes
overwritten
boolean
Yes
True when an existing same-named file was replaced in place.
Id of the file to edit — the id or ref from search_files, or a fileId from save_file.
filename
string
No
Filename to edit instead of id; rejected as ambiguous if more than one file shares the name.
old_string
string
Yes
The 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_string
string
Yes
The text to insert in place of old_string.
replace_all
boolean
No
Replace every occurrence of old_string. Default false replaces a single occurrence and errors if old_string is not unique.
project_id
string
No
Use 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".
Id of the file to delete — the id or ref from search_files, or a fileId from save_file.
filename
string
No
Filename to delete instead of id; rejected as ambiguous if more than one file shares the name.
project_id
string
No
Use 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
Field
Type
Required
Description
fileId
string
Yes
The deleted file's id, or its ref for a rowless file.
Where 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.id
string
No
When type="chat_file": File id from search_files. When type="app_file": File id in the app's store.
from.filename
string
No
When 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.attachmentId
string
No
Id of an attachment uploaded to THIS conversation.
to
object
Yes
Where 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.filename
string
No
Destination filename; defaults to the source's name. Plain filename, no paths.
to.overwrite
boolean
No
Replace an existing same-named destination file in place. Default false: a duplicate name is an error.
Shell 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.
cwd
string
No
Optional absolute path inside the container. Defaults to the sandbox's working directory (/home/sandbox).
timeoutSeconds
integer
No
Optional wall-clock limit in seconds, capped at the deployment maximum.
target
object
No
Which 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.fresh
boolean
No
Set true for a brand-new empty sandbox, without the conversation's attachments or earlier work; its id is returned.
target.id
string
No
An existing sandbox id (UUID) returned by an earlier call.
Output
Field
Type
Required
Description
commandId
string
Yes
sandboxId
string
Yes
command
string
Yes
cwd
string | null
Yes
stdout
string
Yes
stderr
string
Yes
exitCode
number
Yes
durationMs
number
Yes
timedOut
boolean
Yes
truncated
boolean
Yes
binaryStripped
boolean
Yes
True when NUL bytes were stripped from stdout/stderr before storage.
stagingNotices
string[]
Yes
Notices about chat attachments that could not be auto-staged (e.g. too large). Empty when all attachments are available in the sandbox.
Path to the file inside the container — absolute, or relative to the sandbox's working directory.
mimeType
string
No
Optional MIME type recorded with the file. Sniffed from the bytes when omitted.
overwrite
boolean
No
Replace an existing same-named persistent file in place, keeping its id. Default false errors if the name is already taken.
target
object
No
Which 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.fresh
boolean
No
Set true for a brand-new empty sandbox, without the conversation's attachments or earlier work; its id is returned.
target.id
string
No
An existing sandbox id (UUID) returned by an earlier call.
Output
Field
Type
Required
Description
fileId
string
Yes
sandboxId
string
Yes
path
string
Yes
mimeType
string
Yes
sizeBytes
number
Yes
stagingNotices
string[]
Yes
Notices about chat attachments that could not be auto-staged (e.g. too large). Empty when all attachments are available in the sandbox.
overwritten
boolean
Yes
True when an existing same-named file was replaced in place.
Destination path inside the container — absolute under /skills or /home/sandbox, or relative to the sandbox's working directory.
source
object
Yes
Where 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.attachmentId
string
No
Id of an attachment in the current conversation. The bytes are copied directly and never enter your context.
source.filename
string
No
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="my_file": Exact filename of a persistent file (when you have no id).
source.dataBase64
string
When type="base64"
Base64-encoded file bytes.
source.mimeType
string
No
source.originalName
string
No
source.text
string
When type="text"
UTF-8 text content of the file.
source.id
string
No
Id or ref of a persistent file, as returned by search_files (id for stored files, ref for hand-placed ones).
target
object
No
Which 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.fresh
boolean
No
Set true for a brand-new empty sandbox, without the conversation's attachments or earlier work; its id is returned.
target.id
string
No
An existing sandbox id (UUID) returned by an earlier call.