Skip to content

Skills & Tools

Three ways to give your agent new capabilities: tools, skills, and MCP servers. Each fits a different shape of need.

MechanismBest forWhere it runs
Built-in toolsFilesystem, shell, webSandbox container
Custom toolsYour own JSON-schema’d actionSandbox or your endpoint
Custom skillsReusable prompt + reference filesMounted into sandbox
MCP serversAny MCP-spec capability setWherever the MCP server lives

The agent_toolset_20260401 toolset ships with: bash, read, write, edit, glob, grep, web_fetch, web_search. Add it to your agent and the model can do filesystem and shell work in the per-session container.

{
"name": "my-agent",
"model": "claude-sonnet-4-6",
"system": "...",
"tools": [
{ "type": "agent_toolset_20260401" }
]
}

web_fetch and web_search route through openma’s outbound proxy, so they work without the sandbox having direct internet access.

Define a tool inline on the agent with a JSON schema:

{
"tools": [
{
"type": "custom",
"name": "lookup_user",
"description": "Look up a user by their internal ID.",
"input_schema": {
"type": "object",
"properties": {
"user_id": { "type": "string" }
},
"required": ["user_id"]
},
"execution": {
"type": "http",
"endpoint": "https://internal.example.com/api/users/lookup",
"method": "POST"
}
}
]
}

When the model calls the tool:

  1. The sandbox sends an outbound HTTPS request to your endpoint.
  2. If the endpoint host is bound to a Vault, the proxy injects the auth header automatically. The model never sees the credential.
  3. The response is fed back as the tool result.

You can also execute tools entirely inside the sandbox by setting execution: { type: "sandbox", command: "..." }.

A skill is a SKILL.md describing the capability, plus any reference files (templates, schemas, examples) the model needs. The platform mounts everything at /home/user/.skills/{name}/ (using the SKILL.md name, not the skill id) and inlines the SKILL.md body directly into the system prompt at session start — no lazy read, no follow-up read tool call to discover what’s there. Format is compatible with Anthropic’s Claude Code skills.

In the Console: Skills → New skill. Two API shapes:

Terminal window
# (a) JSON — files inlined
curl -X POST "$OMA_BASE_URL/v1/skills" \
-H "x-api-key: $OMA_API_KEY" \
-H "content-type: application/json" \
-d '{
"files": [
{
"filename": "SKILL.md",
"content": "---\nname: invoice-parser\ndescription: Extract structured data from supplier invoices.\n---\n\n# Steps\n1. ..."
},
{ "filename": "schema.json", "content": "{...}" }
]
}'
# (b) Multipart — zip upload (use for large skills with binary files)
curl -X POST "$OMA_BASE_URL/v1/skills/upload" \
-H "x-api-key: $OMA_API_KEY" \
-F "file=@./invoice-parser.zip"
# Invoice parser
Use this skill when the user uploads a PDF or image of an invoice.
## How to extract
1. Read `/home/user/.skills/invoice-parser/schema.json` for the target shape.
2. Use the `pdf` built-in skill to extract text.
3. Match fields by label (e.g. "Total Due", "Invoice Number").
4. Return JSON matching the schema.
## Examples
See `/home/user/.skills/invoice-parser/example_invoice.pdf` for a reference layout.

Skills attach as objects, not bare strings (a bare string array silently doesn’t bind):

{ "skills": [{ "skill_id": "skill_abc123", "type": "custom" }] }

On session start the system prompt receives:

<source name="skill:skill_abc123">
<skill name="invoice-parser">
{full SKILL.md body}
</skill>
</source>

and the files mount at /home/user/.skills/invoice-parser/SKILL.md etc.

Four ship out of the box (type: "anthropic"): xlsx, pdf, docx, pptx. Reference them by id from your agent — no upload needed.

Connect any Model Context Protocol server and openma auto-generates an mcp__<server>__<tool> (double underscore) for every capability the server exposes.

{
"mcp_servers": [
{
"name": "github",
"type": "url",
"url": "https://api.githubcopilot.com/mcp/",
"authorization_token": "..."
}
]
}

Auth modes — credentials never enter the sandbox:

ModeHow
noneomit authorization_token, no matching vault credential
inline bearerauthorization_token: "..." on the server entry
vault static bearermatching auth.type: "static_bearer" credential in a session vault (matched by mcp_server_url host)
vault OAuthmatching auth.type: "mcp_oauth" credential — refreshes on 401 and 403 (Airtable/Asana/Sentry use 403 for expired tokens), CAS-writes new token to D1, retries once

stdio MCP servers run inside the sandbox container: set type: "stdio" with command, args, port. OMA spawns the process, waits for the port to bind, proxies the existing tool wiring at it. Tool discovery is bounded at 15 s per server; up to 20 servers per agent.