Skills and tools
The registries agents use to find and pay for capabilities: skills, MCP tools, knowledge and templates, with bundled code run in a deny-by-default sandbox.
Agents on Tenzro discover what they can use, invoke it and pay per call. Everything they can use is a resource in one of six registries, and each registry is searchable on its own or all together.
| Class | What it is | List | Use |
|---|---|---|---|
| Skill | A named capability: an endpoint or a sandboxed component | tenzro_listSkills | tenzro_useSkill |
| Tool | An MCP server, an HTTP API or a native capability | tenzro_listTools | tenzro_useTool |
| Knowledge | A vector index, document corpus or data feed | tenzro_listKnowledge | tenzro_useKnowledge |
| Workflow template | A reusable multi-step workflow | tenzro_listWorkflowTemplates | tenzro_instantiateWorkflow |
| Agent template | A reusable agent from the marketplace | tenzro_listAgentTemplates | tenzro_spawnAgentTemplate |
| Model | Inference in any modality | tenzro_listModels | OpenAI-compatible APIs |
Discover everything at once
tenzro_listResources searches all six registries in one query: filter by class, capability tags, category, creator and maximum price per call.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tenzro_listResources",
"params": {
"classes": ["skill", "tool", "knowledge"],
"capability_tags": ["retrieval"],
"query": "contract clauses",
"max_tnzo_price": 10000000000000000,
"limit": 50
}
}tenzro_useResource invokes any resource by id. The node detects which registry holds it; pass class to skip the lookup.
tenzro resources list --classes skill,tool --tags retrieval --max-price 10000000000000000
tenzro resources use --resource-id <id> --params '{"query":"indemnity caps"}'Skills
A skill takes one of two forms.
- Endpoint skill. It names an HTTP, MCP or A2A URL. The publisher hosts the code and the node calls it.
- Bundled skill. It ships a content-addressed WebAssembly component (WASI 0.2), and the node runs it in the sandbox described below.
{ "endpoint": "https://skills.example.org/summarize" }{
"bundle": {
"uri": "tenzro://blob/<blake3-hex>",
"sha256": "<sha256-hex>",
"size_bytes": 481232
}
}Nodes also serve built-in skills on the builtin:// scheme, which run inside the node with no outbound hop: web-search, code-review, data-analysis, text-summarization, blockchain-query and tenzro-trainer. The text skills take text and route through intent-based model selection, so the caller names an outcome (budget, quality floor) rather than a model. A built-in that needs an upstream the operator has not configured is not registered, so discovery lists only what a node can actually serve.
tenzro skill list --bundled-only
tenzro skill search retrieval
tenzro skill get <skill_id>
tenzro skill use <skill_id> --input '{"text":"..."}'
tenzro skill register --name summarize --description "Summarise a document" \
--capabilities nlp --creator-did did:tenzro:human:... \
--bundle-uri tenzro://blob/<blake3-hex> --bundle-sha256 <sha256-hex> --bundle-size 481232 \
--price-per-call 1000000000000000 --creator-wallet 0x...Pin what you run
Anyone can publish, and publishers can update their own entries. A caller that needs certainty names what it expects: expected_version and expected_sha256 are checked against the registry entry before anything is charged, and a mismatch is refused rather than substituted.
tenzro skill use <skill_id> --expected-version 1.4.0 --expected-sha256 <sha256-hex> \
--input '{"query":"..."}'Tools
A tool is an MCP server, an HTTP API or a native capability. Its transport is one of:
| Transport | Meaning |
|---|---|
mcp | A remote MCP server over Streamable HTTP |
api | An HTTP API |
native | A capability built into the node |
mcp-stdio | A local MCP subprocess. Operator-registered only. |
Built-in tools include web-search-mcp (web_search, url_fetch), code-executor (runs a submitted WASI component in the sandbox) and file-manager (a workspace scoped to the agent, relative paths only).
tenzro tool list --transport mcp
tenzro tool search retrieval
tenzro tool use <tool_id> --tool-name web_search --params '{"query":"GPU spot price index"}'
tenzro tool register --name clause-search --description "Search contract clauses over MCP" \
--endpoint https://tools.example.org/mcp --capabilities retrieval --category dataOperator-hosted MCP servers
An operator can run third-party or in-house MCP servers on its node and sell access to them. Upstream credentials go into the node's sealed credential vault, encrypted at rest and injected only into the outbound call; tenants never see them. Storing a secret and registering a local subprocess are admin operations.
tenzro mcp store-secret --sealed-secret-ref search_api_key_v1 --plaintext-file ./key.txt
tenzro mcp evict-subprocess --tool-id <tool_id> # after rotating a credential
tenzro mcp forget-secret --sealed-secret-ref search_api_key_v1The sandbox
Bundled skills and components are untrusted code from unknown authors, so the sandbox, not the registry, is the boundary. It is deny-by-default:
- no filesystem, no network, no environment variables and no host methods unless the host grants them explicitly;
- a fuel budget that counts WebAssembly operations, so the same input consumes the same fuel on any machine;
- a wall-clock deadline;
- a fresh instance per invocation, with nothing carried between calls.
Before a bundle runs, the node fetches it by its BLAKE3 locator, re-hashes the bytes against the declared SHA-256 and checks the registry entry. A mismatch fails before settlement, so it costs the caller nothing.
Every run returns a receipt:
{
"component_id": "skill:<skill_id>:<invocation_id>",
"content_hash_hex": "<sha256-hex>",
"function": "invoke",
"input_hash_hex": "<sha256-hex>",
"output_hash_hex": "<sha256-hex>",
"outcome": "success",
"fuel": { "budget": 50000000, "consumed": 182344, "remaining": 49817656 },
"completed_at_ms": 1790000000000
}outcome is one of success, trapped, fuel-exhausted, deadline-exceeded or host-contract-violation.
Outbound calls made on a caller's behalf, by endpoint skills, tools or url_fetch, go only to public addresses. They never reach loopback, link-local, private-range or cloud metadata addresses.
Component interfaces (WIT)
Components target one of three versioned WIT packages. The host rejects a component whose package version does not match.
tenzro:skill@1.0.0 generic skill: one invoke export, JSON in, JSON out
tenzro:mcp-tool@1.0.0 MCP tools/list and tools/call
tenzro:a2a-skill@1.0.0 A2A skill: handle-task and stream-taskHost interfaces a component may import, each linked only when granted:
tenzro:skill/ledger@1.0.0 read-balance, submit-tx, latest-height
tenzro:skill/signing@1.0.0 sign, public-key
tenzro:skill/identity@1.0.0 resolve, caller-did
wasi:io, wasi:clocks, wasi:random, wasi:cli (0.2.9)Build with any language that targets WASI 0.2, for example Rust with wasm32-wasip2.
Payment and scoping
Skills and tools may carry a price per call in TNZO. The paying account signs each paid invocation; the creator receives the price minus the governance-set marketplace commission. Usage statistics are public (tenzro skill usage, tenzro tool usage).
Tenant API keys can be restricted per class with allowed_tools, allowed_skills, allowed_knowledge, allowed_workflow_templates, allowed_agent_templates and allowed_models, and capped per resource with max_per_resource_tnzo. An empty list means no restriction in that class.