Skip to main content

Documentation

The complete reference for discovering, installing, publishing, and integrating AI agent capabilities with AgentNode.

Quick Start

Go from zero to using your first AI agent capability in under five minutes. This walkthrough installs the CLI, searches the registry, installs a pack, and uses it in Python code.

1. Install the CLI

terminal
$ npm install -g agentnode-cli

added 1 package in 2.1s

2. Authenticate

Log in to connect the CLI to your AgentNode account. If you do not have an account yet, register at agentnode.net/auth/register.

terminal
$ agentnode login
? Email: developer@example.com
? Password: ********
? 2FA Code: 123456

Authenticated as developer@example.com
API key stored in ~/.agentnode/credentials

3. Search for a capability

terminal
$ agentnode search "pdf extraction"

Results for "pdf extraction":

  pdf-reader-pack          v1.0.0  trusted   Extract text, tables, and metadata from PDFs
  pdf-extractor-pack       v1.0.0  verified  High-fidelity PDF text extraction
  ocr-reader-pack          v1.1.0  trusted   OCR-based document reading including PDFs

3 results found

4. Install a pack

terminal
$ agentnode install pdf-reader-pack

Installing pdf-reader-pack@1.2.0...
  Downloading package       done
  Verifying hash (SHA-256)  done
  Installing dependencies   done
  Writing lockfile           done

Installed pdf-reader-pack@1.2.0

5. Run it in your code

agent.pypython
from agentnode_sdk import run_tool

# Run with automatic subprocess isolation (all trust levels)
result = run_tool("pdf-reader-pack", file_path="quarterly-report.pdf")
print(result.result["text"])
print(result.mode_used)  # "subprocess" (default) or "direct" (explicit opt-in)

# Multi-tool packs: specify the tool name
result = run_tool("csv-analyzer-pack", tool_name="describe", file_path="data.csv")

That is it. You searched the registry, installed a trust-verified pack, and used it with a single function call. Read on for the full reference.

Runtime QuickStart

Build agents that discover and install capabilities at runtime — no hardcoded dependencies. Five lines from pip install to a working tool.

Install the SDK

terminal
$ pip install agentnode-sdk

The 5-line agent pattern

Describe what your agent needs. AgentNode resolves it to the best-scored, trust-verified package — downloads, verifies, and installs it locally. Then run it with automatic isolation.

agent.pypython
from agentnode_sdk import AgentNodeClient, run_tool

client = AgentNodeClient(api_key="ank_live_...")

# Resolve capability → install best match (trust-verified)
client.resolve_and_install(["pdf_extraction"])

# Run with trust-aware isolation (auto = safe default)
result = run_tool("pdf-reader-pack", file_path="report.pdf")
print(result.result["text"])

That is the complete runtime flow. resolve_and_install() handles resolution, trust verification, download, hash check, extraction, dependency install, and lockfile update. run_tool() then executes with automatic subprocess isolation for all trust levels.

The smart_run() pattern (v0.4.0)

Even simpler: wrap your logic and let AgentNode detect, install, and retry automatically when a capability is missing.

smart_agent.pypython
from agentnode_sdk import AgentNodeClient

client = AgentNodeClient(api_key="ank_live_...")

# If process_pdf fails because pdfplumber is missing,
# AgentNode detects the gap, installs a PDF skill, and retries
result = client.smart_run(
    lambda: process_pdf("report.pdf"),
    auto_upgrade_policy="safe",  # only verified+ skills
)

print(result.success)        # True
print(result.upgraded)       # True (skill was installed)
print(result.installed_slug) # "pdf-reader-pack"

Step-by-step for more control

When you need to inspect candidates, check policies, or control trust requirements before installing:

agent_detailed.pypython
from agentnode_sdk import AgentNodeClient, run_tool

client = AgentNodeClient(api_key="ank_live_...")

# 1. Resolve: find the best package for a capability
result = client.resolve(capabilities=["pdf_extraction"])
best = result.results[0]
print(f"Best match: {best.slug} v{best.version}")
print(f"  Trust: {best.trust_level}  Score: {best.score}")

# 2. Pre-flight check (optional): verify trust + permissions
check = client.can_install(best.slug, require_trusted=True)
if not check.allowed:
    print(f"Blocked: {check.reason}")
    exit(1)

# 3. Install locally (download → verify hash → extract → pip install → lockfile)
installed = client.install(best.slug)
print(installed.message)  # "Installed pdf-reader-pack@1.2.0"

# 4. Run with isolation (auto-mode routes by trust level)
data = run_tool(best.slug, file_path="report.pdf")
print(data.result["text"])
print(f"Ran in {data.mode_used} mode ({data.duration_ms}ms)")

What happens under the hood

StepWhat it does
detect_gap()Analyzes error to identify missing capability — 3 layers: ImportError (high), keywords (medium), context (low)
resolve()Scores packages by capability match (40%), framework fit (20%), runtime compatibility (15%), trust level (15%), permissions (10%)
can_install()Pre-flight check — verifies trust level, permissions, deprecation status without downloading anything
install()Downloads artifact, verifies SHA-256 hash, extracts to ~/.agentnode/packages/, runs pip install for dependencies, writes agentnode.lock with trust metadata
run_tool()Always runs in subprocess isolation by default (mode='auto'). Pass mode='direct' to opt into in-process execution. Returns RunToolResult with output, timing, and mode used
smart_run()Full loop: run → detect gap → resolve → install → retry once. Returns SmartRunResult with complete transparency

Lockfile

Every install writes to agentnode.lock in your project root. This pins exact versions and hashes for reproducible builds across environments.

agentnode.lockjson
{
  "pdf-reader-pack": {
    "version": "1.2.0",
    "hash": "sha256:a1b2c3d4...",
    "entrypoint": "pdf_reader.extract:run",
    "tools": ["extract_pdf", "extract_tables"],
    "installed_at": "2026-03-24T10:30:00Z"
  }
}

LLM Runtime

AgentNodeRuntime connects any OpenAI, Anthropic, or Gemini agent to AgentNode with zero configuration. It registers 5 meta-tools, injects a system prompt, and runs the tool loop automatically. The LLM discovers, installs, and runs capabilities on its own.

Quick start

terminal
$ pip install agentnode-sdk

OpenAI

openai_agent.pypython
from openai import OpenAI
from agentnode_sdk import AgentNodeRuntime

runtime = AgentNodeRuntime()
client = OpenAI()

result = runtime.run(
    provider="openai",
    client=client,
    model="gpt-4o",
    messages=[{"role": "user", "content": "Count the words in 'Hello world'"}],
)
print(result.content)

Anthropic

anthropic_agent.pypython
from anthropic import Anthropic
from agentnode_sdk import AgentNodeRuntime

runtime = AgentNodeRuntime()
client = Anthropic()

result = runtime.run(
    provider="anthropic",
    client=client,
    model="claude-sonnet-4-6",
    messages=[{"role": "user", "content": "Search for PDF tools on AgentNode"}],
)

Gemini

gemini_agent.pypython
from google import genai
from agentnode_sdk import AgentNodeRuntime

runtime = AgentNodeRuntime()
client = genai.Client()

result = runtime.run(
    provider="gemini",
    client=client,
    model="gemini-2.5-flash",
    messages=[{"role": "user", "content": "What AgentNode tools are available?"}],
)

OpenRouter / any OpenAI-compatible provider

Use Mistral, DeepSeek, Qwen, Llama, and more via OpenRouter or any OpenAI-compatible endpoint:

openrouter_agent.pypython
from openai import OpenAI
from agentnode_sdk import AgentNodeRuntime

runtime = AgentNodeRuntime()
client = OpenAI(
    api_key="sk-or-...",
    base_url="https://openrouter.ai/api/v1",
)

result = runtime.run(
    provider="openai",
    client=client,
    model="mistralai/mistral-large",
    messages=[{"role": "user", "content": "Find and install a PDF reader tool"}],
)

Manual tool calling

For any provider that supports tool calling, get tool definitions and dispatch calls manually with handle():

manual.pypython
runtime = AgentNodeRuntime()

# Get tool definitions in your provider's format
tools = runtime.as_openai_tools()    # OpenAI function-calling format
tools = runtime.as_anthropic_tools() # Anthropic format
tools = runtime.as_gemini_tools()    # Gemini format
tools = runtime.as_generic_tools()   # Generic / baseline format

# When the LLM makes a tool call, dispatch it:
result = runtime.handle("agentnode_search", {"query": "pdf extraction"})
# → {"success": true, "result": {"total": 5, "results": [...]}}

Constructor

init.pypython
AgentNodeRuntime(
    client=None,                     # Optional AgentNodeClient
    api_key=None,                    # Optional API key
    minimum_trust_level="verified",  # "verified" | "trusted" | "curated"
)

5 meta-tools

These tools are automatically registered when you create a Runtime. The LLM calls them as needed during the tool loop.

ToolDescription
agentnode_capabilitiesList installed packages (local, no API call)
agentnode_searchSearch the registry (max 5 results)
agentnode_installInstall a package by slug
agentnode_runExecute an installed tool
agentnode_acquireSearch + install in one step

API reference

MethodDescription
tool_specs()Internal typed tool definitions (list[ToolSpec])
as_openai_tools()Tools in OpenAI function-calling format
as_anthropic_tools()Tools in Anthropic format
as_gemini_tools()Tools in Google Gemini format
as_generic_tools()Tools in generic/baseline format
system_prompt()AgentNode system prompt block (append to yours)
tool_bundle()Combined {"tools": [...], "system_prompt": "..."}
handle(name, args)Dispatch a tool call. Returns dict. Never throws.
run(provider, client, ...)Auto-loop with tool dispatch. Never throws.

run() parameters

ParameterTypeDefaultDescription
providerstr"openai", "anthropic", or "gemini"
clientAnyProvider SDK client instance
messageslist[dict]Conversation messages
modelstr""Model name (e.g. "gpt-4o")
max_tool_roundsint8Max tool call rounds before stopping
inject_system_promptboolTrueAppend AgentNode prompt to system message

Trust levels

minimum_trust_level controls which packages can be installed and run through the Runtime. Higher levels are stricter:

LevelAccepts
"verified"verified, trusted, curated
"trusted"trusted, curated
"curated"curated only

Three surfaces

CLIFor humans — search, install, publish
SDK / ClientFor programmatic access — search, resolve, install, run
RuntimeFor LLM agents — tool registration, dispatch, auto-loop

Agents

AgentNode agents are self-describing AI agents packaged with a standardized manifest. Unlike traditional agents that hide behavior in code, every AgentNode agent declares its goal, behavior, permissions, tool access, and limits in a single agentnode.yaml.

Agent tiers

Each agent is classified by what it needs to run:

TierDescriptionExample
llm_onlyPure LLM reasoning — no tools, no API callsBlog writer, report generator
llm_plus_toolsLLM + AgentNode tool packs (search, extract, analyze)Deep research, code review
llm_plus_credentialsLLM + tools + external API credentialsCRM enrichment, cloud cost analysis

Agent manifest fields

The agent: section in the manifest declares the agent configuration. All fields are visible on the package detail page.

FieldRequiredDescription
entrypointYesPython module:function to execute the agent
goalYesWhat the agent does (shown in UI)
system_promptRecommendedAgent behavior description (shown as 'Agent Behavior' in UI)
tierNollm_only | llm_plus_tools | llm_plus_credentials
tool_access.allowed_packagesNoList of tool packs the agent may use (empty = full registry)
limits.max_iterationsNoMaximum reasoning iterations (1-100)
limits.max_tool_callsNoMaximum tool calls (1-500)
limits.max_runtime_secondsNoMaximum execution time (1-3600)
isolationNoprocess or thread (default: thread)

Installing and running an agent

terminal
$ agentnode install deep-research-agent
run_agent.pypython
from agentnode_sdk import run_tool

result = run_tool("deep-research-agent",
    goal="Compare React vs Vue adoption in 2026")

print(result.result["report"])
print(result.result["sources"])

Agent behavior transparency

Every agent shows its behavior description on the package page under “Agent Behavior”. This is a human-readable description of what the agent does — not necessarily the prompt sent to the LLM. It lets you evaluate an agent before installing it.

Combined with declared permissions, tool access, and verification results, you get full transparency into what an agent does, what it can access, and how it was tested.

See the full list of available agents at agentnode.net/agents.

Installation

System requirements

RequirementDetails
Node.jsv18 or later (for the CLI)
Pythonv3.10 or later (for running packs and using the SDK)
npmv9 or later
OSmacOS, Linux, Windows (WSL recommended on Windows)

Choose your install

Use casePackageInstall
Build agents & apps in Pythonagentnode-sdkpip install agentnode-sdk
Install & publish from terminalagentnode-clinpm install -g agentnode-cli
Use with LangChain / LangGraphagentnode-langchainpip install agentnode-langchain
Use with MCP (Claude, Cursor)agentnode-mcppip install agentnode-mcp

Install the CLI

The AgentNode CLI is distributed as a global npm package. It provides all commands for searching, installing, publishing, and managing packs.

terminal
$ npm install -g agentnode-cli

Verify the installation:

terminal
$ agentnode --version
agentnode/0.3.1

$ agentnode --help
Usage: agentnode <command> [options]

Commands:
  login             Authenticate with the registry
  search            Search for packages
  resolve           Resolve capabilities to packages
  install           Install a package
  update            Update a package to the latest version
  rollback          Roll back to a specific version
  info              Show package details
  explain           Explain capabilities, permissions, and use cases
  auth              Manage local credentials (own API tokens)
  credentials       Manage server-side credentials (OAuth)
  audit             View the policy decision audit trail
  doctor            Analyze setup and suggest improvements
  list              Show installed packages
  publish           Publish a package
  validate          Validate a manifest
  report            Generate a security report
  recommend         Get recommendations for missing capabilities
  resolve-upgrade   Find upgrade packages for capability gaps
  policy-check      Check policy constraints
  api-keys          Manage API keys
  import            Import tools from other frameworks

Authentication & API Keys

Who needs an account? Only publishers (people who want to upload packages) and users who install from the registry. Read-only operations like search, info, and explain work without any authentication.

OperationAuth Required?Who Uses This
search, info, explainNoAnyone — explore the registry freely
install, resolve, updateYes (API key)Developers integrating packages into their agents
publish, validateYes (API key + publisher profile)Package authors publishing to the registry
credentials list/testYes (API key)Users managing server-side OAuth credentials
auth (local tokens)NoAnyone — local credentials need no account

How to get an API key: Register an account on the website, then create an API key in your account settings or via agentnode api-keys create. The key is shown once at creation — save it immediately.

terminal
# Interactive login — stores the API key locally
$ agentnode login
Enter your API key: ********
✓ Logged in as developer (ank_****f456)

# Or set the key directly
$ agentnode api-keys set ank_live_abc123def456

# For CI/CD — use an environment variable
$ export AGENTNODE_API_KEY=ank_live_abc123def456

# Check which key is active
$ agentnode api-keys list
  Source:   ~/.agentnode/config.json
  Key:     ank_****f456

API keys are stored locally in ~/.agentnode/config.json. The backend stores only a SHA-256 hash of your key — the plaintext is never persisted on the server. Keys can be revoked at any time from your account settings.

Searching & Discovery

AgentNode search is designed for AI agent developers. Instead of keyword matching against package names, search queries are matched against capability descriptions, tool declarations, tags, and metadata. Results are ranked by relevance, trust level, and framework compatibility.

Basic search

terminal
$ agentnode search "web scraping"

Results for "web scraping":

  webpage-extractor-pack   v1.0.0  trusted   Extract clean text and metadata from any webpage
  browser-automation-pack  v1.1.0  verified  Automate browser interactions for data extraction
  web-search-pack          v1.0.0  trusted   Search the web and retrieve structured results

3 results found

Filtering results

Narrow results by framework, trust level, runtime, or capability ID.

terminal
# Only show packs compatible with LangChain
$ agentnode search "pdf" --framework langchain

# Only show trusted or curated packs
$ agentnode search "email" --trust trusted

# Filter by runtime
$ agentnode search "data analysis" --runtime python

# Filter by specific capability ID
$ agentnode search --capability pdf_extraction

# Combine filters
$ agentnode search "document processing" --framework crewai --trust verified

Search flags

FlagTypeDescription
--frameworkstringFilter by framework compatibility: langchain, crewai, generic
--truststringMinimum trust level: unverified, verified, trusted, curated
--runtimestringFilter by runtime: python
--capabilitystringFilter by exact capability ID from the taxonomy
--limitnumberMaximum number of results to return (default: 20)
--jsonbooleanOutput results as JSON for programmatic consumption
--publisherstringFilter by publisher namespace

Understanding results

Each result shows the package slug, current version, trust level, and a summary. Use agentnode info or agentnode explain for detailed information about a specific pack before installing.

terminal
$ agentnode explain pdf-reader-pack

pdf-reader-pack@1.2.0
  Publisher:    agentnode-official
  Trust:        trusted
  Runtime:      python >=3.10
  Frameworks:   langchain, crewai, generic

  Capabilities:
    - pdf_extraction: Extract text, tables, and metadata from PDF documents

  Permissions:
    Network:        none
    Filesystem:     read (reads input PDF files)
    Code Execution: none
    Data Access:    input_only

  Use Cases:
    - Extract text from PDF reports for summarization
    - Parse tables from financial PDFs
    - Read metadata and page counts from document archives

  Install: agentnode install pdf-reader-pack

Resolution Engine

Resolution is different from search. While search finds packages matching a text query, resolution takes a list of capability IDs your agent needs and returns the optimal packages to fill those gaps. The resolution engine scores candidates across multiple dimensions and respects policy constraints.

How resolution scoring works

Each candidate package receives a composite score from 0 to 1 based on five weighted factors:

FactorWeightDescription
Capability match40%How well the pack's declared capabilities match your requested capability IDs
Framework compatibility20%Whether the pack supports your agent's framework (LangChain, CrewAI, etc.)
Runtime fit15%Whether the pack's runtime and version constraints match your environment
Trust level15%Higher trust levels (curated > trusted > verified > unverified) score higher
Permissions safety10%Packs requesting fewer permissions score higher (principle of least privilege)

CLI resolution

terminal
$ agentnode resolve pdf_extraction web_search --framework langchain

Resolving 2 capabilities for langchain...

  pdf_extraction:
    1. pdf-reader-pack       v1.0.0  score: 0.94  trusted
    2. pdf-extractor-pack    v1.0.0  score: 0.81  verified

  web_search:
    1. web-search-pack       v1.0.0  score: 0.92  trusted
    2. browser-automation-pack v1.1.0 score: 0.73  verified

Recommended: agentnode install pdf-reader-pack web-search-pack

SDK resolution

resolve.pypython
from agentnode_sdk import AgentNodeClient

client = AgentNodeClient(api_key="ank_live_abc123def456")

# Resolve multiple capability gaps at once
result = client.resolve(
    capabilities=["pdf_extraction", "web_search", "email_sending"],
    framework="langchain",
    limit=5,
)

for match in result.results:
    print(f"{match.matched_capabilities}: {match.slug} (score: {match.score})")
    print(f"  Trust: {match.trust_level}")
    print()

Policy constraints

The resolution engine accepts policy constraints that automatically filter out non-compliant packages. This is critical for production deployments where agents must operate within strict security boundaries.

terminal
# Only resolve packages that are trusted or curated
$ agentnode resolve pdf_extraction --trust trusted

# Only resolve packages with no network access
$ agentnode resolve pdf_extraction --policy-no-network

# Check if a specific package meets your policy
$ agentnode policy-check pdf-reader-pack --trust trusted --no-code-execution
Policy check for pdf-reader-pack@1.2.0:
  Trust level:     trusted     PASS
  Network:         none        PASS
  Filesystem:      read        PASS
  Code execution:  none        PASS
  Data access:     input_only  PASS

Package passes all policy constraints.

Installing Packs

Basic installation

terminal
$ agentnode install pdf-reader-pack

Installing pdf-reader-pack@1.2.0...
  Downloading package       done
  Verifying hash (SHA-256)  done
  Installing dependencies   done
  Writing lockfile           done

Installed pdf-reader-pack@1.2.0

Install a specific version

terminal
$ agentnode install pdf-reader-pack@1.1.0

Install multiple packs

terminal
$ agentnode install pdf-reader-pack web-search-pack email-drafter-pack

What happens during installation

When you run agentnode install, the following steps execute in order:

  1. Version resolution -- the registry resolves the latest compatible version (or the pinned version you specified).
  2. Download -- the package archive is downloaded from the registry.
  3. Hash verification -- the downloaded archive is verified against the SHA-256 hash stored in the registry. If the hash does not match, the install is aborted.
  4. Dependency installation -- Python dependencies declared in the pack are installed via pip.
  5. Lockfile update -- the pack version and hash are recorded in agentnode.lock for reproducible installations.

The lockfile

The agentnode.lock file records exactly which versions and hashes are installed. Commit this file to version control for reproducible builds across environments.

agentnode.lockyaml
# Auto-generated by agentnode. Do not edit manually.
lockfile_version: 2

packages:
  csv-analyzer-pack:
    version: "1.1.0"
    hash: "sha256:a1b2c3d4e5f6..."
    installed_at: "2025-01-15T10:30:00Z"
    entrypoint: "csv_analyzer_pack.tool"
    tools:
      - name: "describe"
        entrypoint: "csv_analyzer_pack.tool:describe"
        capability_id: "csv_analysis"
      - name: "filter"
        entrypoint: "csv_analyzer_pack.tool:filter_rows"
        capability_id: "data_cleaning"

  pdf-reader-pack:
    version: "1.2.0"
    hash: "sha256:f6e5d4c3b2a1..."
    installed_at: "2025-01-15T10:31:00Z"
    entrypoint: "pdf_reader_pack.tool"
    tools: []

Using packs in code

Every pack is loaded through the SDK's load_tool() function. v0.2 packs support multiple tools with individual entrypoints. v0.1 packs work the same way with a single default entrypoint.

agent.pypython
from agentnode_sdk.installer import load_tool

# v0.2 multi-tool pack — load specific tools by name
describe = load_tool("csv-analyzer-pack", tool_name="describe")
filter_rows = load_tool("csv-analyzer-pack", tool_name="filter")

result = describe({"file_path": "data.csv"})
filtered = filter_rows({"file_path": "data.csv", "column": "status", "value": "active"})

# v0.1 single-tool packs — no tool_name needed
extract = load_tool("pdf-reader-pack")
pdf_result = extract({"file_path": "report.pdf"})

search = load_tool("web-search-pack")
search_result = search({"query": "AgentNode", "max_results": 5})

Updating and rolling back

terminal
# Update to latest version
$ agentnode update pdf-reader-pack
Updating pdf-reader-pack 1.2.0 -> 1.3.0... done

# Roll back to a specific version
$ agentnode rollback pdf-reader-pack@1.2.0
Rolling back pdf-reader-pack 1.3.0 -> 1.2.0... done

# List all installed packs
$ agentnode list
Installed packages:
  pdf-reader-pack    v1.0.0  trusted
  web-search-pack    v1.0.0  trusted

Publishing Guide

Publishing a pack to AgentNode makes your AI tool discoverable, installable, and verifiable by any agent developer. This guide walks through the full process from account creation to published pack.

Step 1: Create your publisher account

Sign up at agentnode.net/auth/register and enable two-factor authentication. Your publisher namespace (e.g., your-org) appears in every package you publish and cannot be changed later.

Step 2: Structure your project

A minimal pack has three files: the manifest, a pyproject.toml for Python packaging, and the tool module with your tool functions.

project structure
my-pack/
  agentnode.yaml          # ANP manifest (required)
  pyproject.toml          # Python package config (required)
  src/
    my_pack/
      __init__.py
      tool.py             # Tool functions (required)

Step 3: Write your agentnode.yaml manifest

The manifest is the source of truth for what your pack does, what it needs, and how it integrates. See the ANP Manifest Reference below for every field.

agentnode.yamlyaml
manifest_version: "0.2"
package_id: "github-integration-pack"
package_type: "toolpack"
name: "GitHub Integration Pack"
publisher: "your-namespace"
version: "1.0.0"
summary: "Interact with GitHub repos, issues, and PRs."
description: "A comprehensive toolkit for GitHub automation including issue creation, PR review, repository management, and webhook handling."

runtime: "python"
entrypoint: "github_integration_pack.tool"
install_mode: "package"
hosting_type: "agentnode_hosted"

capabilities:
  tools:
    - name: "create_issue"
      capability_id: "github_integration"
      description: "Create a new GitHub issue"
      entrypoint: "github_integration_pack.tool:create_issue"
      input_schema:
        type: "object"
        properties:
          token:
            type: "string"
            description: "GitHub personal access token"
          repo:
            type: "string"
            description: "Repository in owner/repo format"
          title:
            type: "string"
          body:
            type: "string"
        required: ["token", "repo", "title"]
    - name: "list_repos"
      capability_id: "github_integration"
      description: "List repositories for authenticated user"
      entrypoint: "github_integration_pack.tool:list_repos"
      input_schema:
        type: "object"
        properties:
          token:
            type: "string"
        required: ["token"]

permissions:
  network:
    level: "unrestricted"
    justification: "Requires access to GitHub API"
  filesystem:
    level: "none"
  code_execution:
    level: "none"
  data_access:
    level: "input_only"

compatibility:
  frameworks: ["generic"]
  python: ">=3.10"

tags: ["github", "integration", "devtools", "automation"]

Step 4: Implement your tool functions

src/github_integration_pack/tool.pypython
from agentnode_sdk.exceptions import AgentNodeToolError

def create_issue(inputs: dict) -> dict:
    """Create a new GitHub issue."""
    token = inputs["token"]
    repo = inputs["repo"]
    title = inputs["title"]
    body = inputs.get("body", "")

    # Your implementation here
    response = _github_api(token, f"/repos/{repo}/issues", {
        "title": title, "body": body
    })
    return {"issue_number": response["number"], "url": response["html_url"]}

def list_repos(inputs: dict) -> dict:
    """List repositories for authenticated user."""
    token = inputs["token"]
    repos = _github_api(token, "/user/repos")
    return {"repos": [{"name": r["name"], "url": r["html_url"]} for r in repos]}

# Optional: backward-compatible run() wrapper for v0.1 callers
# Not required for v0.2 — per-tool entrypoints (tool:create_issue, tool:list_repos) are used instead
def run(inputs: dict) -> dict:
    operation = inputs.get("operation", "list_repos")
    dispatch = {"create_issue": create_issue, "list_repos": list_repos}
    handler = dispatch.get(operation)
    if not handler:
        raise AgentNodeToolError(f"Unknown operation: {operation}", tool_name=operation)
    return handler(inputs)

Step 5: Validate

terminal
$ agentnode validate .

Validating github-integration-pack...
  Manifest syntax       OK
  Capability IDs        OK (1 tool, 0 resources)
  Permissions           OK (network: unrestricted)
  Entrypoint            OK (github_integration_pack.tool)
  Compatibility         OK (3 frameworks)

Package is valid and ready to publish.

Step 6: Publish

terminal
$ agentnode publish .

Publishing github-integration-pack@1.0.0...
  Uploading package       done
  Security scan           passed (no issues found)
  Signing package         done (Ed25519)
  Indexing capabilities   done

Published! https://agentnode.net/packages/github-integration-pack

Tip: Use agentnode publish --dry-run . to test the full publishing pipeline without actually publishing. This runs validation, security scanning, and packaging but does not upload to the registry.

ANP Manifest Reference

The agentnode.yaml manifest is the heart of every pack. It declares identity, capabilities, permissions, and compatibility in a single human-readable file.

Identity fields

FieldTypeRequiredDescription
manifest_versionstringYesANP format version. "0.1" or "0.2". Use "0.2" for multi-tool packs with per-tool entrypoints.
package_idstringYesUnique identifier for the package. Must be lowercase, hyphenated. Example: "pdf-reader-pack"
package_typestringYesPackage type. Currently "toolpack" is the primary type.
namestringYesHuman-readable display name. Example: "PDF Reader Pack"
publisherstringYesPublisher namespace from your account. Example: "agentnode-official"
versionstringYesSemantic version. Must follow semver: "1.0.0", "2.1.3"
summarystringYesOne-line description (under 120 characters). Used in search results.
descriptionstringNoLonger description with full details. Supports plain text.

Runtime fields

FieldTypeRequiredDescription
runtimestringYesExecution runtime. Currently "python".
entrypointstringYesPackage-level Python module path. Example: "pdf_reader_pack.tool". In v0.2, individual tools can have their own entrypoints.
install_modestringYesHow the pack is installed. Values: "package" (pip install), "standalone" (script).
hosting_typestringNoWhere the pack is hosted. Values: "agentnode_hosted" (default), "self_hosted", "remote".

Capabilities

The capabilities section declares what your pack can do. Each tool in the tools array maps to a function the pack exposes.

FieldTypeRequiredDescription
capabilities.toolsarrayYesArray of tool declarations.
tools[].namestringYesTool name used in code. Example: "extract_pdf"
tools[].capability_idstringYesStandardized capability ID from the taxonomy. Example: "pdf_extraction"
tools[].entrypointstringv0.2Per-tool entrypoint in module.path:function format. Required for multi-tool v0.2 packs. Example: "csv_analyzer_pack.tool:describe"
tools[].descriptionstringYesWhat this tool does, in plain language.
tools[].input_schemaobjectNoJSON Schema describing the tool's input parameters.
tools[].output_schemaobjectNoJSON Schema describing the tool's return value.

Permissions

Every pack must explicitly declare what system resources it accesses. This is not optional -- it is enforced at publish time and surfaced to users before installation.

FieldValuesDescription
permissions.network.levelnone | restricted | unrestrictedNetwork access. "none" = no outbound calls. "restricted" = specific domains only. "unrestricted" = any network access.
permissions.network.justificationstringWhy this permission level is needed (recommended for restricted/unrestricted).
permissions.filesystem.levelnone | temp | read | writeFile system access. "none" = no FS access. "temp" = temp directory only. "read" = read files. "write" = read and write.
permissions.code_execution.levelnone | sandboxed | fullCode execution. "none" = no code exec. "sandboxed" = restricted sandbox. "full" = unrestricted execution.
permissions.data_access.levelinput_only | output_only | bidirectionalData flow direction. "input_only" = reads input, does not send data out. "bidirectional" = sends and receives.

Compatibility

FieldTypeRequiredDescription
compatibility.frameworksarrayNoAuto-defaults to ["generic"]. ANP packages work across all frameworks automatically.
compatibility.pythonstringNoPython version constraint. Example: ">=3.10"

Tags

An array of lowercase string tags for search and categorization. Example: ["pdf", "extraction", "documents"]. Tags are free-form but should describe the domain and use case.

CLI Reference

Complete reference for all 18 commands in the AgentNode CLI.

agentnode login

Authenticate with the AgentNode registry. Stores credentials in ~/.agentnode/credentials.

terminal
$ agentnode login
? Email: developer@example.com
? Password: ********
? 2FA Code: 123456
Authenticated as developer@example.com

agentnode search <query>

Search the registry for packages matching a text query.

FlagDescription
--framework <name>Filter by framework (langchain, crewai, generic)
--trust <level>Minimum trust level (unverified, verified, trusted, curated)
--runtime <name>Filter by runtime (python)
--capability <id>Filter by capability ID
--publisher <slug>Filter by publisher namespace
--limit <n>Maximum results (default: 20)
--jsonOutput as JSON
terminal
$ agentnode search "email automation" --framework langchain --trust verified

agentnode resolve <capability_id...>

Resolve one or more capability IDs to ranked package recommendations using the scoring engine.

FlagDescription
--framework <name>Preferred framework for scoring
--trust <level>Minimum trust level
--jsonOutput as JSON
terminal
$ agentnode resolve pdf_extraction email_sending --framework crewai

agentnode install <slug> [slug...]

Install one or more packs. Supports version pinning with slug@version.

terminal
$ agentnode install pdf-reader-pack
$ agentnode install pdf-reader-pack@1.1.0
$ agentnode install pdf-reader-pack web-search-pack

agentnode update <slug>

Update an installed pack to its latest version.

terminal
$ agentnode update pdf-reader-pack
Updating pdf-reader-pack 1.2.0 -> 1.3.0... done

agentnode rollback <slug>@<version>

Roll back an installed pack to a specific previous version.

terminal
$ agentnode rollback pdf-reader-pack@1.2.0
Rolling back pdf-reader-pack 1.3.0 -> 1.2.0... done

agentnode info <slug>

Display detailed metadata about a package: version history, publisher, trust level, permissions, capabilities, and compatibility.

terminal
$ agentnode info pdf-reader-pack

agentnode explain <slug>

Explain a package in plain language: what it does, what permissions it requires, which frameworks it supports, and typical use cases. Designed for deciding whether to install.

terminal
$ agentnode explain pdf-reader-pack

agentnode audit

View and manage the AgentNode Guard policy decision audit trail. Every install and run decision is logged to ~/.agentnode/audit.jsonl.

SubcommandDescription
audit showShow recent audit entries (default: last 20)
audit show --limit 50Show more entries
audit show --jsonOutput raw JSON for scripting
audit statsSummary: allow/deny/prompt counts, top packages
audit clear --yesDelete the audit log
terminal
$ agentnode audit show
TIMESTAMP            EVENT             SLUG                      ACTION    SOURCE                  TRUST
───────────────────────────────────────────────────────────────────────────────────────────────────────────
2026-04-16 14:23:01  client_install    pdf-reader-pack           allow     default                 trusted
2026-04-16 14:23:05  run_tool          pdf-reader-pack           allow     default                 trusted
2026-04-16 14:25:12  client_install    untrusted-pack            deny      trust_level             unverified

$ agentnode audit stats
  Total entries:  142
  Period:         2026-04-10 → 2026-04-16
  Actions:   allow  118  (83.1%)   deny  19  (13.4%)   prompt  5  (3.5%)

agentnode doctor

Analyze your local setup, check for outdated packs, missing dependencies, configuration issues, and suggest improvements.

terminal
$ agentnode doctor
Checking environment...
  Node.js:    v20.10.0    OK
  Python:     3.11.5      OK
  CLI:        1.0.0       OK
  Auth:       logged in   OK
  Lockfile:   found       OK

  1 outdated pack: pdf-reader-pack (1.2.0 -> 1.3.0)
  Run: agentnode update pdf-reader-pack

agentnode list

Show all locally installed packs with versions and trust levels.

terminal
$ agentnode list
Installed packages:
  pdf-reader-pack    v1.0.0  trusted
  web-search-pack    v1.0.0  trusted
  email-drafter-pack v1.0.0  verified

agentnode publish <directory>

Publish a pack to the registry. Runs validation, security scanning, signing, and indexing.

FlagDescription
--dry-runRun the full pipeline without uploading
terminal
$ agentnode publish .
$ agentnode publish ./my-pack --dry-run

agentnode validate <directory>

Validate a manifest without publishing. Checks syntax, capability IDs, permissions consistency, entrypoint resolution, and framework compatibility.

terminal
$ agentnode validate .

agentnode report <slug>

Generate a full security report for a package, including trust history, scan results, dependency analysis, and permission audit.

terminal
$ agentnode report pdf-reader-pack

agentnode recommend

Analyze your installed packs and suggest additional capabilities that complement your current setup.

terminal
$ agentnode recommend
Based on your installed packs, you might also need:
  document_summary    -> document-summarizer-pack   trusted
  data_visualization  -> data-visualizer-pack       verified

agentnode resolve-upgrade

Find higher-scored or more trusted alternatives for your currently installed packs.

terminal
$ agentnode resolve-upgrade
Checking for upgrades...
  pdf-extractor-pack -> pdf-reader-pack (higher trust, better score)

agentnode policy-check <slug>

Check whether a package meets specified policy constraints.

FlagDescription
--trust <level>Required minimum trust level
--no-networkRequire no network access
--no-code-executionRequire no code execution
--no-filesystem-writeRequire no filesystem write access
terminal
$ agentnode policy-check pdf-reader-pack --trust trusted --no-network

agentnode auth <provider>

Store a local API token for a connector provider (e.g. GitHub, Slack). Tokens are saved to ~/.agentnode/credentials.json with 0600 permissions. No AgentNode account required.

Subcommand / FlagDescription
auth <provider>Store a token for the given provider (interactive prompt)
auth listList locally stored credentials
auth remove <provider>Remove a locally stored credential
--validateValidate the token against the provider's API before saving
terminal
$ agentnode auth github --validate
? Paste your GitHub token: ********
✓ Token validated — stored for github

agentnode credentials <subcommand>

Manage server-side OAuth credentials stored in the AgentNode backend. These are obtained via OAuth flows and proxied through the API — your tool never sees the raw token.

Subcommand / FlagDescription
credentials listList all server-side credentials
credentials test <id>Test connectivity for a credential
credentials delete <id>Revoke and delete a credential
--jsonOutput as JSON (available on all subcommands)
terminal
$ agentnode credentials list
Credentials (2):
  a1b2c3d4  github     active  domains=[api.github.com]
  e5f6g7h8  slack      active  domains=[slack.com]

agentnode import <file> --from <platform>

Import existing tools from other frameworks and generate an ANP manifest automatically. See Import Tools for full details.

FlagDescription
--from <platform>Source platform: mcp, langchain, openai, crewai, clawhub, skillssh
--output <dir>Output directory for generated manifest (default: current directory)
terminal
$ agentnode import my_tools.py --from langchain

Python SDK

The Python SDK provides programmatic access to the AgentNode registry for search, resolution, trust checking, installation, tool loading, and capability gap detection. Use it to build agents that detect missing capabilities and safely acquire verified skills on demand.

Installation

terminal
$ pip install agentnode-sdk

Initialization

app.pypython
from agentnode_sdk import AgentNodeClient

# API key authentication (recommended)
client = AgentNodeClient(api_key="ank_live_abc123def456")

# Or use a bearer token
client = AgentNodeClient(token="your_bearer_token")

# Custom base URL (for self-hosted registries)
client = AgentNodeClient(
    api_key="ank_live_abc123def456",
    base_url="https://api.your-registry.com/v1"
)

Search

search.pypython
result = client.search(
    query="pdf extraction",
    framework="langchain",
    per_page=10
)

print(f"Found {result.total} packages")
for hit in result.hits:
    print(f"  {hit.slug}  {hit.trust_level}  {hit.summary}")

Resolve

Resolve finds the best package for a set of capability IDs, scoring each candidate on capability match, framework fit, runtime compatibility, trust level, and permissions.

resolve.pypython
result = client.resolve(
    capabilities=["pdf_extraction", "web_search"],
    framework="langchain"
)

for match in result.results:
    print(f"{match.slug} v{match.version}")
    print(f"  Score: {match.score}  Trust: {match.trust_level}")
    print(f"  Breakdown: cap={match.breakdown.capability} "
          f"fw={match.breakdown.framework} "
          f"trust={match.breakdown.trust}")

Pre-flight check

Check whether a package can be installed under given trust and permission constraints — without downloading anything.

check.pypython
check = client.can_install(
    "pdf-reader-pack",
    require_trusted=True,
    denied_permissions=["network", "code_execution"]
)

if check.allowed:
    print(f"OK — trust: {check.trust_level}")
else:
    print(f"Blocked: {check.reason}")

Install

Downloads the artifact, verifies the SHA-256 hash, extracts to ~/.agentnode/packages/, installs pip dependencies, and writes agentnode.lock.

install.pypython
result = client.install("pdf-reader-pack", require_trusted=True)

print(result.message)       # "Installed pdf-reader-pack@1.2.0"
print(result.installed)     # True
print(result.hash_verified) # True

Load and run tools

run.pypython
# Load a tool from an installed package
extract = client.load_tool("pdf-reader-pack")
result = extract({"file_path": "report.pdf"})

# Multi-tool packs: load a specific tool by name
describe = client.load_tool("csv-analyzer-pack", tool_name="describe")
summary = describe({"file_path": "data.csv"})

One-call autonomous install

For agents that need to self-upgrade: describe what you need and let AgentNode handle the rest.

autonomous.pypython
# Resolve + trust check + install in one call
result = client.resolve_and_install(
    capabilities=["pdf_extraction"],
    require_trusted=True  # only install trusted/curated packages
)

if result.installed:
    tool = client.load_tool(result.slug)
    data = tool({"file_path": "report.pdf"})
else:
    print(f"Could not install: {result.message}")

Capability gap detection (v0.4.0)

AgentNode can analyze runtime errors to detect missing capabilities — without any LLM. Three detection layers with confidence levels:

  • HighImportError for a known module (e.g. pdfplumber, pandas, selenium)
  • Medium — Error message contains technical keywords (e.g. "chromedriver", "csv parser")
  • Low — Context hints like file extensions or URLs
detect.pypython
from agentnode_sdk import detect_gap

gap = detect_gap(ImportError("No module named 'pdfplumber'"))
print(gap.capability)   # "pdf_extraction"
print(gap.confidence)   # "high"
print(gap.source)       # "import_error"

# Context helps when the error itself isn't specific
gap = detect_gap(RuntimeError("failed"), context={"file": "report.pdf"})
print(gap.capability)   # "pdf_extraction"
print(gap.confidence)   # "low"

detect_and_install() (v0.4.0)

The product-level API for self-upgrading agents. Detects the gap, resolves the best match, and installs it — all in one call.

detect_install.pypython
try:
    result = my_agent_logic()
except Exception as exc:
    upgrade = client.detect_and_install(
        exc,
        auto_upgrade_policy="safe",  # only verified+ skills
        on_detect=lambda cap, conf, err: print(f"Detected: {cap} ({conf})"),
        on_install=lambda slug: print(f"Installed: {slug}"),
    )

    if upgrade.installed:
        result = my_agent_logic()  # retry manually
    else:
        print(f"Detection: {upgrade.capability} ({upgrade.confidence})")
        print(f"Error: {upgrade.error}")

smart_run() (v0.4.0)

Convenience wrapper: wrap your logic and let AgentNode handle detection, installation, and exactly one retry automatically.

smart.pypython
result = client.smart_run(
    lambda: process_pdf("report.pdf"),
    auto_upgrade_policy="safe",
)

if result.success:
    print(result.result)          # your function's return value
    print(result.upgraded)        # True if a skill was installed
    print(result.installed_slug)  # e.g. "pdf-reader-pack"
    print(result.duration_ms)     # total time including retry
else:
    print(result.error)
    print(result.original_error)  # the first error, always available

Auto-upgrade policies (v0.4.0)

Named policies control what gets auto-installed. When set, the policy overrides individual parameters like require_verified.

PolicyBehavior
"off"Detect only, never install
"safe"Auto-install verified+ skills (recommended)
"strict"Auto-install trusted+ skills only

Low-confidence detections are blocked from auto-install by default. Use allow_low_confidence=True to override.

Package metadata

metadata.pypython
# Package details
pkg = client.get_package("pdf-reader-pack")
print(f"{pkg.name} v{pkg.latest_version}")
print(f"Downloads: {pkg.download_count}")
print(f"Deprecated: {pkg.is_deprecated}")

# Install metadata (capabilities, permissions, artifact info)
meta = client.get_install_metadata("pdf-reader-pack")
print(f"Runtime: {meta.runtime}")
print(f"Entrypoint: {meta.entrypoint}")
for cap in meta.capabilities:
    print(f"  {cap.name} ({cap.capability_id})")
if meta.permissions:
    print(f"  Network: {meta.permissions.network_level}")
    print(f"  Filesystem: {meta.permissions.filesystem_level}")

REST API

The AgentNode REST API provides direct HTTP access to all registry functionality. Base URL: https://api.agentnode.net/v1

Authentication

Include your API key in the X-API-Key header. Read-only endpoints (search, info) may work without authentication but are rate-limited.

terminalbash
curl -H "X-API-Key: ank_live_abc123def456" \
  https://api.agentnode.net/v1/packages/pdf-reader-pack

Search packages

terminalbash
# POST /v1/search
curl -X POST "https://api.agentnode.net/v1/search" \
  -H "Content-Type: application/json" \
  -d '{"q": "pdf extraction", "framework": "langchain", "trust": "verified"}'

# Response:
{
  "results": [
    {
      "slug": "pdf-reader-pack",
      "name": "PDF Reader Pack",
      "version": "1.2.0",
      "summary": "Extract text, tables, and metadata from PDF documents",
      "trust_level": "trusted",
      "publisher": "agentnode-official",
      "frameworks": ["generic"],
      "capabilities": ["pdf_extraction"]
    }
  ],
  "total": 1
}

Get package details

terminalbash
# GET /v1/packages/:slug
curl "https://api.agentnode.net/v1/packages/pdf-reader-pack"

# Response:
{
  "slug": "pdf-reader-pack",
  "name": "PDF Reader Pack",
  "version": "1.2.0",
  "publisher": "agentnode-official",
  "trust_level": "trusted",
  "summary": "Extract text, tables, and metadata from PDF documents",
  "runtime": "python",
  "capabilities": [
    {
      "name": "extract_pdf",
      "capability_id": "pdf_extraction",
      "description": "Extract text, tables, and metadata from PDF documents"
    }
  ],
  "permissions": {
    "network": "none",
    "filesystem": "read",
    "code_execution": "none",
    "data_access": "input_only"
  },
  "compatibility": {
    "frameworks": ["generic"],
    "python": ">=3.10"
  }
}

Resolve capabilities

terminalbash
# POST /v1/resolve
curl -X POST "https://api.agentnode.net/v1/resolve" \
  -H "X-API-Key: ank_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "capabilities": ["pdf_extraction", "web_search"],
    "framework": "langchain",
    "policy": {
      "min_trust": "verified"
    }
  }'

# Response:
{
  "results": [
    {
      "slug": "pdf-reader-pack",
      "version": "1.2.0",
      "score": 0.94,
      "trust_level": "trusted",
      "matched_capabilities": ["pdf_extraction"]
    },
    {
      "slug": "web-search-pack",
      "version": "1.0.0",
      "score": 0.92,
      "trust_level": "trusted",
      "matched_capabilities": ["web_search"]
    }
  ]
}

Check policy

terminalbash
# POST /v1/check-policy
curl -X POST "https://api.agentnode.net/v1/check-policy" \
  -H "X-API-Key: ank_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "package_slug": "pdf-reader-pack",
    "policy": {
      "min_trust": "trusted",
      "max_permissions": {
        "network": "none",
        "code_execution": "none"
      }
    }
  }'

# Response:
{
  "passes": true,
  "checks": [
    { "name": "trust_level", "passed": true, "actual": "trusted", "required": "trusted" },
    { "name": "network", "passed": true, "actual": "none", "max": "none" },
    { "name": "code_execution", "passed": true, "actual": "none", "max": "none" }
  ]
}

Publish a package

terminalbash
# POST /v1/packages/publish
curl -X POST "https://api.agentnode.net/v1/packages/publish" \
  -H "X-API-Key: ank_live_abc123def456" \
  -H "Content-Type: multipart/form-data" \
  -F "artifact=@./dist/my-pack-1.0.0.tar.gz" \
  -F "manifest=@./agentnode.yaml"

# Response:
{
  "slug": "my-pack",
  "version": "1.0.0",
  "url": "https://agentnode.net/packages/my-pack",
  "trust_level": "unverified"
}

List capabilities

terminalbash
# GET /v1/capabilities
curl "https://api.agentnode.net/v1/capabilities"

# Response:
{
  "capabilities": [
    { "id": "pdf_extraction", "category": "Document Processing", "description": "Extract text and data from PDF files" },
    { "id": "web_search", "category": "Web & Browsing", "description": "Search the web and return structured results" },
    { "id": "email_sending", "category": "Communication", "description": "Compose and send emails" }
  ]
}

Additional endpoints

MethodEndpointDescription
POST/v1/auth/registerCreate a new account
POST/v1/auth/loginAuthenticate and receive a session token
POST/v1/auth/2fa/setupInitialize two-factor authentication
POST/v1/auth/2fa/verifyVerify a 2FA code
GET/v1/packages/:slug/trustGet trust level details and history
POST/v1/packages/:slug/reviewsSubmit a review for a package
GET/v1/packages/:slug/reviewsList reviews for a package
POST/v1/packages/:slug/reportReport a package for security or policy violations
GET/v1/packages/:slug/install-infoGet install metadata (hash, URL, dependencies)
POST/v1/packages/:slug/installRecord an installation event
POST/v1/recommendGet pack recommendations based on installed capabilities
POST/v1/packages/validateValidate a manifest without publishing

MCP Integration

The Model Context Protocol (MCP) is an open standard for connecting AI models to external tools and data sources. The AgentNode MCP adapter lets you search, resolve, and browse the AgentNode registry directly from MCP-compatible editors like Claude Code and Cursor.

Installation

terminal
$ pip install agentnode-mcp

Two modes of operation

The MCP adapter runs in two modes:

  • Pack server -- exposes a single installed pack as MCP tools. Use when you want to give an editor access to one specific pack.
  • Platform server -- exposes the full AgentNode platform API as MCP tools. Use when you want to search, resolve, and browse the registry from your editor.

Pack server

terminal
# Expose a single pack as MCP tools
$ agentnode-mcp --pack pdf-reader-pack

Platform server

terminal
# Expose the full AgentNode platform API
$ agentnode-mcp-platform --api-url https://api.agentnode.net

Available MCP tools (platform server)

ToolDescription
agentnode_searchSearch the registry for packages by query, framework, and trust level
agentnode_resolveResolve capability IDs to ranked package recommendations
agentnode_explainGet a detailed explanation of a package's capabilities and permissions
agentnode_capabilitiesList all available capability IDs in the taxonomy

Claude Code configuration

Add the following to your Claude Code MCP configuration file (typically claude_desktop_config.json or your project .mcp.json):

claude_desktop_config.jsonjson
{
  "mcpServers": {
    "agentnode": {
      "command": "agentnode-mcp-platform",
      "args": ["--api-url", "https://api.agentnode.net"],
      "env": {
        "AGENTNODE_API_KEY": "ank_live_abc123def456"
      }
    }
  }
}

Cursor configuration

Add the same server block to your Cursor MCP settings. The exact file location depends on your OS:

cursor mcp configjson
{
  "mcpServers": {
    "agentnode": {
      "command": "agentnode-mcp-platform",
      "args": ["--api-url", "https://api.agentnode.net"],
      "env": {
        "AGENTNODE_API_KEY": "ank_live_abc123def456"
      }
    }
  }
}

Using a specific pack in your editor

To expose a specific installed pack as an MCP tool (so your editor can use it directly):

claude_desktop_config.jsonjson
{
  "mcpServers": {
    "pdf-reader": {
      "command": "agentnode-mcp",
      "args": ["--pack", "pdf-reader-pack"]
    }
  }
}

GitHub Action

The agentnode/publish@v1 GitHub Action automates pack publishing from your CI/CD pipeline. Push a tag or create a release, and the action validates, scans, signs, and publishes your pack automatically.

Basic workflow

.github/workflows/publish.ymlyaml
name: Publish to AgentNode
on:
  release:
    types: [published]

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"

      - name: Install dependencies
        run: pip install -r requirements.txt

      - name: Publish pack
        uses: agentnode/publish@v1
        with:
          api-key: ${{ secrets.AGENTNODE_API_KEY }}

Action inputs

InputRequiredDefaultDescription
api-keyYes--Your AgentNode API key. Store as a repository secret.
dry-runNofalseRun validation and scanning without publishing. Set to "true" for PR checks.
directoryNo.Path to the pack directory containing agentnode.yaml.

Dry-run on pull requests

Use dry-run mode to validate manifests on every pull request without publishing:

.github/workflows/validate.ymlyaml
name: Validate AgentNode Pack
on:
  pull_request:
    paths:
      - "agentnode.yaml"
      - "src/**"

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Validate pack
        uses: agentnode/publish@v1
        with:
          api-key: ${{ secrets.AGENTNODE_API_KEY }}
          dry-run: true

Example output

github actions log
Run agentnode/publish@v1
  Validating agentnode.yaml...
    Manifest syntax       OK
    Capability IDs        OK (1 tool, 0 resources)
    Permissions           OK (network: unrestricted)
    Entrypoint            OK (github_integration_pack.tool)
    Compatibility         OK (3 frameworks)

  Running security scan...
    Bandit scan           passed (0 issues)
    Dependency audit      passed

  Publishing github-integration-pack@1.0.0...
    Uploading package     done
    Signing package       done (Ed25519)
    Indexing capabilities done

  Published: https://agentnode.net/packages/github-integration-pack

Triggering on tags

If you prefer tag-based releases instead of GitHub Releases:

.github/workflows/publish-on-tag.ymlyaml
name: Publish to AgentNode
on:
  push:
    tags:
      - "v*"

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Publish pack
        uses: agentnode/publish@v1
        with:
          api-key: ${{ secrets.AGENTNODE_API_KEY }}

Package Verification

AgentNode verifies every package on publish in a real sandbox and computes a verification score from 0–100. The score is based on evidence — not self-reported badges. Scores are visible on every package page and factor into search ranking.

Verification steps

Each package goes through four checks, each contributing points to the overall score:

1. Install

15 pts

The package is installed in a clean virtual environment. If installation fails (missing dependencies, build errors), the package is automatically quarantined.

2. Import

15 pts

All declared tool entrypoints are imported and checked for existence and callability. If any entrypoint is missing or not callable, the package is quarantined.

3. Smoke test

25 pts

Tools are called with test inputs generated from their JSON schema. Results are classified as passed (25 pts), inconclusive (0–12 pts depending on reason), or failed (0 pts). Smoke failures do not block the package but reduce the score.

4. Tests

15 pts

If the package includes a test suite, it is executed with pytest. Real tests that pass earn 15 pts. Auto-generated tests earn 8 pts. No tests: 3 pts. Integration tests marked with @pytest.mark.integration are skipped.

Quality checks (multi-run)

After a successful smoke test, the same input is run multiple times to measure stability:

CheckPointsWhat it measures
Reliability0–10Proportion of runs that succeed (e.g. 3/3 = 10 pts)
Determinism0–5Output consistency across runs (same hash = 5 pts)
Contract0–10Return value is serializable, non-null, structurally valid
Warnings−2 eachDeprecation warnings, unsafe patterns (max −10)

Verification tiers

The total score maps to a tier displayed on the package page and in search results:

Gold

90–100

Verified

70–89

Partial

50–69

Unverified

<50

Inconclusive reasons & partial credit

Not every tool can be fully tested in a sandbox. A tool that needs an API key is not broken — it just cannot be smoke-tested without credentials. We classify why a smoke test is inconclusive and score accordingly:

ReasonSmoke ptsMeaning
needs_credentials12/25Requires API keys not available in sandbox
missing_system_dependency12/25Requires Chromium, FFmpeg, etc.
needs_binary_input12/25Requires real PDF, image, or audio files
external_network_blocked12/25Needs network access blocked in sandbox
not_implemented0/25Stub package, raises NotImplementedError
unknown_smoke_condition8/25Ambiguous error — may be broken or just missing data

How to improve your score

As a publisher, there are several things you can do to maximize your verification score:

Include real tests

A passing test suite earns 15 pts (vs. 3 pts with no tests). Use pytest and place tests in a tests/ directory. Mark integration tests that need external services with @pytest.mark.integration.

Define a complete input schema

Declare input_schema with properties, required, and type for every field. Use enum for constrained fields and default values where appropriate. The more schema detail, the better our test input generation.

Add schema examples

Include an examples key in your input schema with a working example input. This is the highest-confidence test input and is tried first.

Return serializable values

Tools should return JSON-serializable values (dicts, lists, strings). Returning None or non-serializable objects reduces the contract score.

Quarantine behavior

Packages are automatically quarantined if installation or import fails. Quarantined packages are hidden from search results and cannot be installed. Other issues (smoke test, unit tests) reduce the score but do not block usage.

Continuous re-verification

Scores are not static. Every package is automatically re-verified on every publish. If a dependency update breaks something, the score drops and users see it before their agent does. Admins can also trigger targeted re-verification at any time.

What verification guarantees

Guaranteed

  • Can be installed in a clean environment
  • All declared entrypoints exist and are callable
  • Package structure is valid
  • Score reflects real sandbox execution

Not guaranteed

  • Correct behavior with real-world data
  • Availability of external services
  • Full test coverage
  • Tools requiring credentials/system deps work correctly

Verification is evidence-based, not absolute. It filters out broken packages and scores what it can prove. “Partially Verified” means “not fully testable in a sandbox” — not “broken.”

Credentials & Connectors

Some packages connect to external APIs (GitHub, Slack, etc.). These connector packages need credentials to authenticate. AgentNode provides two ways to manage credentials: local tokens you own, and server-side OAuth via the AgentNode backend.

How credential resolution works

When a connector package runs, the SDK resolves credentials through a configurable chain. By default (auto mode), it tries each source in order until it finds a match:

1. Environment Variable

AGENTNODE_CRED_GITHUB, AGENTNODE_CRED_SLACK, etc. Best for CI/CD pipelines and containers.

2. Local Credential File

~/.agentnode/credentials.json — tokens stored via agentnode auth. No account needed.

3. Server-Side (API)

OAuth2 tokens managed by the AgentNode backend. Secrets never leave the server — requests are proxied.

Local credentials (agentnode auth)

Use agentnode auth to store your own API tokens locally. No AgentNode account required. Tokens are validated against the provider's API before being saved.

terminal
# Store a GitHub token
$ agentnode auth github
  Create a token at: https://github.com/settings/tokens
  Recommended scopes: repo, read:user

Paste your token: ********
Validating token... valid
GitHub credential stored.

# Store a Slack token
$ agentnode auth slack

# List stored credentials
$ agentnode auth list

# Remove a credential
$ agentnode auth remove github

Credentials are stored in ~/.agentnode/credentials.json with file permissions restricted to the current user (0600 on Unix). This follows the same pattern used by gh, docker, and aws CLI tools.

Server-side credentials (agentnode credentials)

For OAuth2 flows that require a callback URL, the AgentNode backend handles the token exchange. Your secrets never leave the server — tool execution is proxied through the backend.

terminal
# List server-side credentials
$ agentnode credentials list

# Test connectivity
$ agentnode credentials test <id>

# Revoke a credential
$ agentnode credentials delete <id>

Environment variables

For CI/CD and automated environments, set credentials as environment variables. The naming convention is AGENTNODE_CRED_ followed by the provider name in uppercase:

terminal
export AGENTNODE_CRED_GITHUB=ghp_xxxxxxxxxxxxx
export AGENTNODE_CRED_SLACK=xoxb-xxxxxxxxxxxxx

Resolution mode

You can control which sources are checked via credentials.resolve_mode in your config:

ModeSources CheckedUse Case
auto (default)env → local file → APIBest for development — tries everything
envEnvironment variables onlyCI/CD pipelines, containers
localLocal file onlyOffline development, air-gapped systems
apiServer-side onlyManaged environments, OAuth2 flows
~/.agentnode/config.json
{
  "credentials": {
    "resolve_mode": "auto"
  }
}

Security model

  • CredentialHandle — tools never see raw tokens. They receive an opaque handle that makes authenticated requests on their behalf. The handle validates target domains against the connector's allowed list before attaching credentials.
  • Domain restriction — each credential is bound to specific API domains (e.g., api.github.com). Requests to unauthorized domains are rejected before any secret is attached.
  • No serialization — CredentialHandles cannot be pickled, serialized, or printed. repr() shows only the provider name, never the secret.
  • Proxy mode — server-side credentials are never sent to the client. Requests are proxied through the backend, so the token stays on the server.

Trust & Security

Trust is not binary. AgentNode provides a layered trust model where every pack has a clear, auditable trust level that progresses over time through verification, community usage, and manual review.

The four trust levels

Unverified

Newly published pack. Metadata has been validated and the manifest is syntactically correct, but no further review has been performed. Use with caution in production.

Verified

Publisher identity has been confirmed. The pack passes automated security scans (Bandit), and its declared permissions are consistent with actual behavior. Publisher has 2FA enabled.

Trusted

Security scanned with zero findings, tests pass, active maintenance history, meaningful community usage, and no reported issues. The pack has demonstrated reliability over time.

Curated

Manually reviewed by the AgentNode team. Code has been audited, permissions verified against actual behavior, and the pack meets the highest quality bar. This is the highest assurance level in the registry.

How to progress through trust levels

FromToRequirements
UnverifiedVerifiedConfirm publisher identity, enable 2FA, pass Bandit security scan, permissions match declared behavior
VerifiedTrustedZero security findings, tests pass, active maintenance, community usage, no unresolved reports
TrustedCuratedManual review by AgentNode team, code audit, permissions verification, documentation review

Security scanning

Every pack published to the registry undergoes automated security scanning:

  • Bandit analysis -- static analysis for common Python security issues (hardcoded passwords, SQL injection, insecure deserialization, etc.)
  • Ed25519 signatures -- every published pack is signed with the publisher's key. Install-time verification ensures the pack has not been tampered with after publication.
  • Typosquatting detection -- the registry detects package names that are suspiciously similar to popular packs (e.g., pdf-reeder-pack vs. pdf-reader-pack) and flags them for manual review.
  • Hash verification -- SHA-256 hashes are computed at publish time and verified at install time. If the hash does not match, the installation is aborted.

The permission model

Every pack must explicitly declare its permissions across four dimensions. Agents and users see the full permission manifest before installation, and the resolution engine can filter by permission constraints.

DimensionLevelsDescription
Networknone, restricted, unrestrictedWhat network access the pack requires. "none" means no outbound calls. "restricted" means specific domains only. "unrestricted" means any network access.
Filesystemnone, temp, read, writeWhat file system access the pack requires. "temp" means temporary directory only. "read" means it reads files. "write" means it reads and writes.
Code Executionnone, sandboxed, fullWhether the pack executes arbitrary code. "sandboxed" means restricted execution environment. "full" means unrestricted.
Data Accessinput_only, output_only, bidirectionalThe direction of data flow. "input_only" means the pack reads input but does not send data externally. "bidirectional" means it both receives and sends data.

Inspecting a package

Use agentnode info and agentnode policy-check to review a package's trust level, permissions, and whether it meets your policy constraints before installation.

terminal
$ agentnode info pdf-reader-pack
$ agentnode policy-check pdf-reader-pack --trust trusted --no-network

Data Sovereignty

AgentNode is a registry and policy engine — not a data processor. Your data never touches our servers. Tools run locally in your environment. The backend only stores what's needed for the registry catalog (package metadata, account credentials). Everything else stays on your machine.

Your data stays local

  • Tool input/output data — the data your agents process never touches our servers. Tools run locally in your environment, not on ours.
  • LLM prompts or responses — we have no visibility into what your agent sends to or receives from language models.
  • Usage telemetry — the SDK does not phone home. No analytics, no tracking, no usage beacons. The only network calls are explicit ones you trigger (install, search, resolve).
  • Local credentials — tokens stored via agentnode auth stay in ~/.agentnode/credentials.json on your machine. They are never uploaded.
  • Audit logs — Guard's audit trail (~/.agentnode/audit.jsonl) is local-only. Policy decisions stay on your machine.

Execution model

All tool execution happens locally in your Python process. The AgentNode backend is only involved in three scenarios:

Registry Operations

Search, install, resolve, publish — catalog operations that transfer package metadata and artifacts.

OAuth Proxy

Server-side credentials: the backend proxies API calls so OAuth tokens never leave the server. Optional — you can use local tokens instead.

Remote Runner

For packages that explicitly declare remote execution. The SDK marks these as remote_run in the audit trail. Most packages run locally.

Accounts & API keys

An AgentNode account is needed only for write operations (installing, publishing) and server-side credentials. Read-only operations like search, info, and explain work without any authentication.

API keys are the primary authentication mechanism for the CLI and SDK. They replace session-based login for programmatic access:

  • Create an API key in your account settings on the website or via agentnode api-keys create <label>
  • Store it locally with agentnode api-keys set <key> or via agentnode login
  • Use it automatically — the CLI reads from config, or set AGENTNODE_API_KEY for CI/CD
  • Revoke at any time from your account settings — revoked keys are immediately rejected

Only a SHA-256 hash of your API key is stored on the server. If the database is compromised, the plaintext key cannot be recovered. Keys are matched using constant-time comparison (hmac.compare_digest) to prevent timing attacks.

Offline-capable

Once packages are installed, the SDK works fully offline. The lockfile (agentnode.lock) contains all metadata needed to run tools without network access. Set credentials.resolve_mode: "local" to ensure credential resolution never reaches out to the API. Policy enforcement (Guard) is entirely local — no server calls, no latency.

AgentNode Guard

AgentNode Guard is the pre-execution policy gateway built into the SDK. Every install and run call passes through Guard before anything executes. Guard checks trust levels, permission boundaries, and environment context — then allows, denies, or prompts. Every decision is logged to an append-only audit trail.

How it works

Guard sits at the center of every execution path: the Python SDK, the CLI, the MCP adapter, and the agent runtime. There is no way to run or install a pack without Guard evaluating the request first.

1. Check

Guard reads your config (~/.agentnode/config.json), the package's trust level and permissions, and the runtime environment (secrets present? CI? container?).

2. Decide

Based on your policy, Guard returns one of three actions: allow, deny, or prompt. Broken or missing config defaults to deny (fail-closed).

3. Audit

Every decision is logged to ~/.agentnode/audit.jsonl with timestamp, event type, package, action, source, and environment context. The audit trail is append-only and auto-rotated.

Enforcement points

Guard is enforced at every execution path. There is no bypass.

PathCheckEnforcement
client.install()check_installHard — policy crash = deny
runner.run_tool()check_runHard — deny or prompt stops execution
runtime.handle()check_runHard — returns policy_denied error
MCP call_tool()check_runHard — fail-closed (non-interactive = deny)
agent_runnertrust checkHard — own trust verification
remote_runnerdispatcherHard — audited as remote_run event

Policy configuration

Guard reads your policy from ~/.agentnode/config.json. These are the key settings:

~/.agentnode/config.json
{
  "trust": {
    "minimum_trust_level": "verified"
  },
  "permissions": {
    "network": "prompt",
    "filesystem": "prompt",
    "code_execution": "sandboxed"
  },
  "audit": {
    "max_size_mb": 10,
    "max_files": 5
  }
}
SettingValuesDescription
trust.minimum_trust_levelunverified, verified, trusted, curatedPackages below this level are denied
permissions.networkallow, prompt, denyHow to handle packages requesting network access
permissions.filesystemallow, prompt, denyHow to handle packages requesting filesystem access
permissions.code_executionsandboxed, prompt, denyHow to handle packages requesting code execution
audit.max_size_mbnumber (default: 10)Rotate audit log when it exceeds this size
audit.max_filesnumber (default: 5)Maximum number of rotated audit files to keep

Environment-aware decisions

Guard detects your runtime environment and escalates decisions when risk is higher:

  • Secrets detected — if environment variables like AWS_*, OPENAI_*, or DATABASE_URL are present, Guard escalates to prompt for unverified packages with network access
  • CI mode — detected via CI, GITHUB_ACTIONS, etc. Non-interactive environments use deny instead of prompt
  • Strict mode — set AGENTNODE_GUARD_STRICT=true to force all uncertain decisions to deny instead of prompt

Viewing the audit trail

Every Guard decision is logged. Use the CLI to inspect:

terminal
# Show recent decisions
$ agentnode audit show

# Show statistics
$ agentnode audit stats

# Export as JSON for analysis
$ agentnode audit show --limit 100 --json > decisions.json

Import Tools

Already have tools written for another framework? The import command detects tool names, descriptions, and input schemas from your existing code and generates an ANP manifest automatically. No rewriting required.

Supported platforms

PlatformWhat it detectsCommand
MCP@server.tool() decorated functions, tool descriptions, input schemasagentnode import server.py --from mcp
LangChainBaseTool subclasses, @tool decorated functions, schemasagentnode import tools.py --from langchain
OpenAI FunctionsFunction definitions in JSON formatagentnode import functions.json --from openai
CrewAI@tool decorated functions, tool descriptionsagentnode import tools.py --from crewai
ClawHubClawHub manifest filesagentnode import manifest.json --from clawhub
Skills.shSkills.sh skill configsagentnode import skill.json --from skillssh

Import from MCP

terminal
$ agentnode import mcp_server.py --from mcp

Detected 3 tools in mcp_server.py:
  search_web      -> capability: web_search
  extract_page    -> capability: webpage_extraction
  send_email      -> capability: email_sending

Generated agentnode.yaml with 3 tools.
Review and edit the manifest, then publish with: agentnode publish .

Import from LangChain

terminal
$ agentnode import search_tool.py --from langchain

Detected 1 tool in search_tool.py:
  SearchTool (BaseTool subclass)
    name: "web_search"
    description: "Search the web for information"
    -> capability: web_search

Generated agentnode.yaml with 1 tool.

Import from OpenAI Functions

terminal
$ agentnode import functions.json --from openai

Detected 2 functions in functions.json:
  get_weather     -> capability: weather_lookup
  search_docs     -> capability: document_search

Generated agentnode.yaml with 2 tools.

Import from CrewAI

terminal
$ agentnode import crew_tools.py --from crewai

Detected 2 tools in crew_tools.py:
  @tool search_internet  -> capability: web_search
  @tool analyze_data     -> capability: data_analysis

Generated agentnode.yaml with 2 tools.

Web import tool

Prefer a visual interface? Use the web-based import tool to paste your code or upload a file and generate a manifest in your browser.

After importing

The import command generates an agentnode.yaml manifest with auto-detected values. You should review the generated manifest and:

  1. Verify the detected capability IDs are correct
  2. Set the appropriate permission levels (the importer defaults to conservative values)
  3. Add your publisher namespace
  4. Verify the per-tool entrypoints are correct (e.g. tool:create_issue for multi-tool packs)
  5. Run agentnode validate . to confirm everything is correct
  6. Publish with agentnode publish .