Skip to main content
A skill is a SKILL.md document, optionally bundled with reference files and Python or Node scripts, that a company keeps in its library and attaches to its chat agents. The agent sees a catalog of its skills, loads one when a request matches, and can run a skill’s script in a disposable sandbox in Olyros’s cloud or on one of the company’s own OHO machines. Skills live in the client app under the Agents sidebar group as Skills (/settings/skills): a list, a three-column editor (/settings/skills/new, /settings/skills/:id/edit) and a Skills tab on each agent (/agents/:id/skills). Agents, cloud tasks and sandboxes have their own pages; see Agents for the agent itself.

What it does

A company library of versioned skills. A skill is created from SKILL.md text in the editor (createSkill, updateSkill) or from a zip upload (POST /api/v1/skills/bundles). The frontmatter follows the Agent Skills format: name (lowercase kebab-case, at most 64 characters, the olyros- prefix is reserved), description (at most 1024 characters), optional license, compatibility, metadata, allowed-tools, plus the Claude Code extensions argument-hint, user-invocable, disable-model-invocation and when_to_use. Every save of changed content writes an immutable version (skillVersions, skillVersion); an identical save is a no-op; a save from a stale editor is rejected when expectedLatestVersionId no longer matches. Any version can be restored as a new version (restoreSkillVersion, with or without its files) and downloaded as a zip (GET /api/v1/skills/{skill_id}/versions/{version_id}/bundle.zip). Validation errors block a save; warnings are stored on the version and shown in the editor (validateSkill dry-runs the editor text). Bundles with files. A zip holds SKILL.md plus text files under references/, scripts/, assets/ or any folder (kinds reference, script, asset, other). The pipeline rejects binary files, symlinks, duplicate paths, paths deeper than 4 segments and file names that hold secrets by convention (.env*, *.pem, *.key, id_rsa*); it ignores __MACOSX, .git, .DS_Store and Thumbs.db. A browser save of SKILL.md on a bundled skill carries the latest version’s files forward, so every version is a complete snapshot. The validator warns about unreferenced or oversized files, scripts that call the network, read environment variables or import from outside the skill, packages the sandbox image lacks (DEPENDENCY_NOT_IN_IMAGE), unsupported script extensions, and hidden characters or secrets in any file. Bound to agents, per environment. A company admin binds a skill to an agent (bindSkillToAgent, updateSkillBinding, unbindSkillFromAgent) with an optional pinned version (null follows the skill’s current version), environmentOverrides limited to web_chat and/or slack, and invocationOverride of model, user or both. An inactive skill (isActive = false) is hidden from every agent; unbinding is soft. agentSkills and skillBindings list bindings with missingTools (tools the skill text references that the agent lacks) and bridgeTools (what its code may call). In chat: a catalog, a read tool and /skill commands. Each turn the agent’s active skills (at most 20 per agent) are rendered into its system prompt as <available_skills>. The built-in tool olyros_skill_read(name, path?) returns the full SKILL.md or one bundle file, truncated at 32 KiB. Users invoke skills directly: /skill or /skills shows a pick card, /skill list all lists names, /skill help, /skill info <name>, /skill <name> [arguments] invokes one, and /<name> [arguments] is a shorthand when the name resolves. ! works wherever / does (Slack refuses DMs that start with /). Arguments are capped at 2000 characters, stand in for $ARGUMENTS in the body, and are presented to the model as data, not instructions. Code skills run in a sandbox. A bundle with scripts/*.py (runtime python3.12) or scripts/*.js|.mjs|.cjs (runtime node22) is a code skill. The built-in tool olyros_skill_run(name, command, input_files?, stdin?) takes one command such as node scripts/generate-flyer.js in/content.json out/Flyer.pdf. The command is split POSIX-style and never handed to a shell: the interpreter must be python, python3 or node, the script must be one of the skill’s own scripts/ files and match the interpreter, and arguments may only name paths under /work or the skill mount. Input files land under /work/in; whatever the script writes to /work/out comes back as temporary files offered as links that expire after 7 days (web chat shows them in the reply and a skill_output_files event; Slack attaches them natively). A non-zero exit returns stdout and stderr to the model so it can fix its input and retry. Where code runs: the execution plan. Two backend kinds exist, cloud (the olyros-skill-exec Cloud Run sandbox service) and oho (a one-shot Docker container on one of the company’s OHOs). The effective order is the skill’s executionOrder (updateSkillExecutionOrder), else the company’s skillExecutionOrder, else cloud; allowed values are cloud, oho,cloud, oho and cloud,oho. cloud is usable only when a platform admin enabled cloud skill execution for the company and a cloud backend is configured. oho is usable only when a company admin turned on Run skill code on our OHOs (updateCompanySettings(ohoSkillExecutionEnabled)), the server carries the runtime image definition, and at least one OHO that an admin allowed (setOhoSkillExecutionAllowed) is online and advertises the skill_exec feature. The OHO picked is the agent’s sandbox host, else the OHO behind the company’s default backend, else the one with the fewest running skill runs. When the first backend refuses before anything ran (OHO offline, busy or still building its image; cloud unreachable), the next one in the order gets the run once, and the chat run row says which backend ran and why the first did not. skillExecutionCapabilities(skillId) returns the effective order with each backend’s availability and reason; skillExecOhos lists the company’s OHOs with their allow state. The cloud sandbox. Every call gets a fresh sandbox on a read-only root filesystem with the skill mounted read-only at /skills/<name> and a writable /work. The image holds Python 3.12 with pandas, numpy, openpyxl, python-docx, python-pptx, pypdf, matplotlib, reportlab, pillow, pyyaml, jinja2 and tabulate, and Node 22 with pdf-lib, googleapis, @databricks/sql, xlsx, date-fns, csv-parse, csv-stringify, dayjs, lodash, yargs and marked. There is no pip, npm, npx, curl, wget, git or compiler, only six fixed environment variables, and no network egress unless the run carries a tool bridge session. The OHO runtime is built on each OHO from the same five-file definition (first build 5 to 10 minutes and about 1.2 GB; needs PyPI, npm, nodejs.org and Docker Hub reachable), runs with --network none unless a bridge session is present, and rebuilds when the definition changes. Inputs and outputs travel through signed URLs in the temporary bucket; only control messages cross the OHO link. Trust profile and the tool bridge. Skill code can call the agent’s tools (HTTP tools, MCP servers, built-ins) through a server-side broker using the olyros client package mounted in the sandbox. Each skill has an admin-edited trust profile (updateSkillTrustProfile): toolAccess is none, declared (only what the bundle’s olyros.yaml declares) or agent (everything the agent has); writes is deny, ask or allow; network is none, bridge or internet; secrets is reserved and never honoured. Each company tool and MCP server carries an admin gate for skill code (setToolSkillCodeEnabled, setMcpServerSkillCodeEnabled), and the bridge as a whole is exposed by the platform and allowed by the company (toolBridgeAllowed). Under writes = ask, and for tools of per-user OAuth MCP servers, the run pauses on a consent card (Allow for this run, Always allow for me on this agent, Deny) before it starts; consents are listed and revoked with skillToolConsents and revokeSkillToolConsent, and every call appears in toolCallAudit. A declared tool the agent does not have refuses the run (SKILL_RUN_REQUIRES_UNMET).

Who can use it

  • Reading the library, versions, files, bindings, consents, capabilities and the OHO list: any company member (membership only).
  • Every write (create, edit, restore, delete, bundle upload and download, validate, bind, trust profile, execution order, the skill-code gates on tools and MCP servers, consent revocation), the tool-call audit, OHO execution and order, the tool bridge switch and allowing a specific OHO: company admin. The gates name class-scoped abilities whose minimum role is admin: skill.manage for skill writes, bindings, trust profile, execution order, consent revocation, validateSkill and the bundle REST routes (403 ADMIN_REQUIRED); tool.manage_restricted and mcp.manage for the skill-code gates; tool.audit for toolCallAudit; company.manage for the company settings; oho.manage for allowing an OHO. Settings -> Roles (/settings/roles) lists them, as does Company settings.
  • Enabling cloud skill execution per company, the budget ceilings and tool bridge exposure: platform admin in the admin app (PUT /api/platform/execution/companies/{company_id}/skill-execution).
  • No plan or tier gate exists for skills.

How to configure it

  1. Create the skill (Skills -> New): write SKILL.md and save (createSkill(input{skillMd, displayName, isActive})), or upload a zip (POST /api/v1/skills/bundles, multipart file, optional dry_run and display_name). Errors such as NAME_INVALID, DESCRIPTION_MISSING, FILE_TOO_LARGE or BINARY_FILE must be fixed before the save succeeds.
  2. Iterate: edit the text (updateSkill), upload a new bundle version (POST /api/v1/skills/{skill_id}/bundles with an optional change_note), compare versions and restore one (restoreSkillVersion(skillId, versionId, withFiles)).
  3. Bind it to an agent on the agent’s Skills tab: bindSkillToAgent(agentId, skillId, input{pinnedVersionId, environmentOverrides, invocationOverride}).
  4. For code skills, choose where it runs. Ask a platform admin to enable cloud execution, or turn on Run skill code on our OHOs in Settings -> General and allow one OHO on its host page (Execution -> OHO host). Pick the company order (updateCompanySettings(skillExecutionOrder)) and, if needed, a per-skill order on the editor’s Tools tab (updateSkillExecutionOrder).
  5. Set the trust profile on the Tools tab (updateSkillTrustProfile), open the per-tool skill-code gates the skill needs (declare them in olyros.yaml to narrow access to declared), and tune the agent’s budgets (skillCallTimeoutS, skillTurnBudgetS; bounds from agentRuntimeLimits).
  6. Test in the editor’s Chat tab, which runs a real conversation with a chosen agent.
  7. From a coding agent. With an agent connection that holds skills:write (Agent access), upload_skill_bundle(files, dry_run) validates and uploads the same bundle the zip route takes and download_skill_bundle returns one; the walk-throughs are on Olyros for agents.

Limits and defaults

What it emits

  • One SkillInvocation row per script run with status running, succeeded, failed, timeout, refused or error, the backend and OHO that ran it, runtime, argv, exit code, duration, bytes in and out, capped stdout and stderr (64 KiB / 32 KiB), output file metadata and an error code from one list (SKILL_EXEC_OHO_OFFLINE, SKILL_RUN_TIMEOUT, SKILL_RUN_OUTPUTS_LOST, BRIDGE_REFUSED, …).
  • A usage event with SKU skill.execution.second per finished run, attributed to the backend that ran it: the platform’s cloud backend row for cloud runs, the OHO’s own customer-hosted row (unpriced) for OHO runs. Turn cost tags are copied onto it.
  • Chat events skill_run_result (outcome, backend, OHO name, fallback note) and skill_output_files, and a skills_used summary on the interaction (invoked, run, read).
  • Bridge call rows for every tool call made by skill code, visible in toolCallAudit.
  • Audit events: skill.created, skill.version.created, skill.bundle.uploaded, skill.bundle.downloaded, skill.version.restored, skill.deleted, skill.bound, skill.binding.updated, skill.unbound, skill.trust_profile.updated, skill.execution_order.set, skill.run.finished, oho.skill_exec_allowed.set; mcp.upload_skill_bundle for a bundle uploaded through an agent connection, next to the skill.created or skill.bundle.uploaded row it produced.
  • HITL requests for the /skill pick card and for run consents.

Known gaps

  • No dependency installation. A script can use only what the curated image ships; DEPENDENCY_NOT_IN_IMAGE warns and the run fails at import. Per-skill dependency layers are deferred; the substitute is adding a package to the shared image.
  • Chat agents only. Skills are resolved for the web_chat and slack environments of the server agent runtime. Cloud tasks, executor stages, workflow create_task runs and sandbox agents do not load skills.
  • A run must finish inside the chat turn. There is no queued or detached run, so a script is bounded by the turn budget (about 270 s), and nothing waits for an offline OHO.
  • Text files only. Bundles cannot carry images, fonts or other binary assets (BINARY_FILE); bundle_url is reserved and unused.
  • No secrets reach the sandbox. The secrets dial is stored but never honoured and no environment variables carry credentials; code reaches systems only through the tool bridge.
  • bridge is not narrower than internet. Every backend offers only egress isolation, so a run with a bridge session can also reach the internet; a forwarder channel is designed but not built.
  • No marketplace. Versions come from the editor, the zip upload, the agent connection tool or restore (created_via); a skill authored inside a chat conversation (by the agent that runs it) is not supported.
  • Per-binding invocation override has no editor. invocationOverride is settable through the API only; there is no UI control for it.
  • Cloud execution cannot be self-enabled. Only a platform admin turns it on per company; the company’s own switch covers OHO execution only.
  • Some limits are not settings. Per-OHO concurrency and memory are OHO environment variables, an OHO has no /work disk quota, and the company-level temp_file_max_size_mb is editable but unread (the platform value applies).
  • custom_code tools (a script attached to a tool rather than a skill) are parked and not offered today.

Customer-safe summary

Skills let your team teach an agent a repeatable procedure once and reuse it everywhere the agent chats. A skill is a short instruction document, optionally with reference files and small Python or Node scripts, kept in your company library with a full version history. You attach skills to the agents that need them, choose whether the agent or the user may invoke each one, and users can call a skill directly from web chat or Slack with a slash command. When a skill includes a script, the agent runs it in a disposable, isolated sandbox, either in Olyros’s cloud or on one of your own connected machines, with time limits you set, and hands back any files it produced as download links. An admin controls which of your tools a skill’s code may reach and whether it may write, and users are asked for consent before a write when that is the policy. Every run is recorded with where it ran, how long it took and what it produced.