Tenzro Testnet is live —request testnet TNZO
← Back to Tutorials

Discover Skills, Tools, and Agent Templates in the Hub

Getting StartedBeginner15 min

The Tenzro Hub is the on-chain registry of composable building blocks for autonomous systems. Everything that agents need — skills (atomic capabilities), tools (callable utilities), and agent templates (pre-configured agent blueprints) — is published to the registry, discoverable via JSON-RPC, and callable from any MCP- or A2A-compatible client.

This tutorial walks you through querying the hub over the public RPC, filtering entries programmatically with the TypeScript SDK, and composing a skill + tool + template into an autonomous workflow.

What you'll need

1. Open the Hub in your browser

The fastest way to see what's in the registry is the live Hub page. It polls every 10 seconds and groups entries into tabs for Skills, Agent Templates, and Tools.

Open Tenzro Hub →

2. List skills via JSON-RPC

Skills are atomic, reusable capabilities (e.g., web-search, code-review). Each skill has an input/output schema, an optional endpoint, pricing in atto-TNZO, and an invocation counter tracked on-chain.

curl https://rpc.tenzro.network \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tenzro_listSkills",
    "params": {}
  }'

A typical response looks like this:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": [
    {
      "skill_id": "7a8c4f12-...",
      "name": "web-search",
      "description": "Searches the public web and returns ranked results",
      "capabilities": ["search", "retrieval"],
      "category": "data",
      "version": "1.0.0",
      "status": "active",
      "provider_id": "did:tenzro:machine:..."
    }
  ]
}

3. List tools

Tools are callable utilities — HTTP fetchers, PDF parsers, code linters, database connectors. Unlike skills, tools are usually invoked via MCP and don't need to be an agent themselves.

curl https://rpc.tenzro.network \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tenzro_listTools",
    "params": {}
  }'

4. List agent templates

Agent templates are pre-configured blueprints for spawning autonomous agents. A template bundles an agent type, a set of declared capabilities, and an optional list of tags for discoverability.

curl https://rpc.tenzro.network \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tenzro_listAgentTemplates",
    "params": {}
  }'

5. Query the hub from TypeScript

The website ships with typed helpers in src/lib/rpc.ts. You can import them directly in any Next.js server component, API route, or standalone Node script.

import {
  listSkills,
  listTools,
  listAgentTemplates,
  type SkillInfo,
  type ToolInfo,
  type AgentTemplateInfo,
} from "@/lib/rpc";

async function browseHub() {
  const [skills, tools, templates] = await Promise.all([
    listSkills(),
    listTools(),
    listAgentTemplates(),
  ]);

  console.log(`Found ${skills.length} skills`);
  console.log(`Found ${tools.length} tools`);
  console.log(`Found ${templates.length} agent templates`);

  // Filter for active skills in a specific category
  const dataSkills = skills.filter(
    (s: SkillInfo) =>
      s.category === "data" &&
      (s.status ?? "active").toLowerCase() === "active"
  );

  // Find tools by tag
  const httpTools = tools.filter((t: ToolInfo) =>
    t.tags?.includes("http")
  );

  // Find templates matching a capability
  const payingAgents = templates.filter((t: AgentTemplateInfo) =>
    t.capabilities.includes("payments")
  );

  return { dataSkills, httpTools, payingAgents };
}

Each helper returns an empty array on failure (never throws), so you can freely compose them with Promise.all or Promise.allSettled without needing try/catch blocks.

6. Poll for live updates

Because the registry is on-chain, new entries appear the moment a block finalizes. For UIs and dashboards, a simple 10-second polling loop is usually enough:

// Poll the hub every 10 seconds for live updates
setInterval(async () => {
  const skills = await listSkills();
  updateUI(skills);
}, 10_000);

7. Compose a workflow

Once you can enumerate the registry, composing a workflow is just filtering and matching. Here's a minimal example that picks a search skill, an HTTP tool, and a paying-agent template, then hands them off to an autonomous runtime:

// Compose a skill + tool + template into a workflow
const { dataSkills, httpTools, payingAgents } = await browseHub();

// 1. Pick a search skill
const searchSkill = dataSkills.find((s) => s.name === "web-search");

// 2. Pick an HTTP fetcher tool
const fetcher = httpTools.find((t) => t.name === "http-get");

// 3. Pick a paying agent template
const agent = payingAgents[0];

if (searchSkill && fetcher && agent) {
  console.log(
    `Spawn ${agent.name} with skill=${searchSkill.name} tool=${fetcher.name}`
  );
  // hand off to the autonomous runtime...
}

What's next

Now that you can discover entries, the next step is to invoke them. Head to the payment and agent tutorials to wire up a full workflow: