ANP Manifest Reference: How to Write a Package Manifest
Complete reference for the ANP manifest.yaml format. Every field explained with examples, including multi-tool packages, permissions, and runtime configuration.
Overview
Every ANP package requires a manifest.yaml file in the root of the package directory. This file tells AgentNode what your package is, what tools it provides, what inputs and outputs each tool expects, and what runtime requirements must be met for installation. If the manifest is wrong, the package either will not publish or will fail verification.
This reference covers every field in the current manifest specification (version 0.2), with examples for each.
Top-Level Fields
manifest_version (required)
The version of the ANP manifest specification your package conforms to. Currently, the only supported value is "0.2".
manifest_version: "0.2"
This field exists so the specification can evolve without breaking existing packages. Always use the latest supported version when creating new packages.
package_id (required)
A globally unique identifier for your package. Must be a lowercase slug: letters, numbers, and hyphens. No underscores, no uppercase, no spaces.
package_id: web-article-extractor
Choose carefully — this cannot be changed after publishing. It becomes part of the install URL and the registry listing. Good package IDs are short, descriptive, and unlikely to conflict with other packages.
Valid: json-validator, pdf-to-text, sentiment-analyzer, s3-uploader
Invalid: JSON_Validator, my tool, pdf.to.text, a (too short)
version (required)
The semantic version of this release. Must follow semver format.
version: "0.1.0"
When publishing an update, the version must be strictly higher than the currently published version. AgentNode sorts versions semantically, so "0.2.0" comes after "0.1.9", not after "0.1.10" (which is how string sorting would order them).
Conventions:
0.x.x— Pre-stable; breaking changes may happen between minor versions.1.0.0— First stable release; you are committing to backward compatibility.- Bump the patch version for bug fixes, minor for new features, major for breaking changes.
Capabilities
The capabilities section declares what your package can do. Currently, it contains a single key: tools.
capabilities.tools (required)
A list of tools provided by this package. Each tool is an object with the following fields:
Tool: name (required)
The name of the tool. This is what agents use to refer to the tool after installation. Use snake_case.
- name: extract_article
Tool: entrypoint (required)
The Python import path to the function, in module:function format. The module path uses dots to separate directories and the colon separates the module from the function name.
entrypoint: web_article_extractor.tool:extract_article
This means: "import extract_article from web_article_extractor/tool.py." The module must be importable from the package root. The function must be a callable that accepts keyword arguments matching the input_schema and returns a value matching the output_schema.
More examples:
my_pack.core:run— Functionruninmy_pack/core.pytools.text.summarize:summarize_text— Functionsummarize_textintools/text/summarize.pymain:process— Functionprocessinmain.py(top-level module)
Tool: input_schema (required)
A JSON Schema object describing the inputs the tool accepts. This schema is used for validation during smoke testing and by agents to construct correct calls.
input_schema:
type: object
properties:
url:
type: string
description: "The URL of the webpage to extract"
max_length:
type: integer
description: "Maximum characters to return"
default: 5000
required: [url]
Key points:
- The top level must be
type: objectwithproperties. - Use
requiredto list mandatory fields. Optional fields should havedefaultvalues. - Include
descriptionfor every property — agents use these to understand what to pass. - Supported types:
string,integer,number,boolean,object,array,null. - You can use
enumto restrict values:type: string, enum: ["csv", "json", "xml"].
Tool: output_schema (required)
A JSON Schema object describing what the tool returns. The verification pipeline checks that the actual output conforms to this schema, which contributes to the contract compliance score (10 points).
output_schema:
type: object
properties:
title:
type: string
text:
type: string
word_count:
type: integer
extracted_at:
type: string
description: "ISO 8601 timestamp of extraction"
Be precise. If your tool sometimes returns null for a field, declare it as a union: type: [string, "null"]. If a field is always present, include it. If it is only sometimes present, do not list it in a required array on the output schema.
Multi-Tool Packages
A single package can provide multiple tools. List them all under capabilities.tools:
capabilities:
tools:
- name: validate_json
entrypoint: json_toolkit.validate:validate_json
input_schema:
type: object
properties:
data:
type: object
schema:
type: object
required: [data, schema]
output_schema:
type: object
properties:
valid:
type: boolean
errors:
type: array
items:
type: string
- name: format_json
entrypoint: json_toolkit.format:format_json
input_schema:
type: object
properties:
data:
type: object
indent:
type: integer
default: 2
required: [data]
output_schema:
type: object
properties:
formatted:
type: string
size_bytes:
type: integer
Each tool is verified independently. If one tool passes smoke testing and another fails, you earn partial credit. Keep tools in the same package only if they are logically related and share dependencies.
Runtime
The runtime section specifies execution requirements.
runtime.language (required)
The programming language. Currently, only python is supported.
runtime:
language: python
runtime.min_version (required)
The minimum language version required. The verification sandbox runs Python 3.10+, so do not set this below "3.10".
min_version: "3.10"
runtime.dependencies (required, may be empty)
A list of pip-installable packages with optional version constraints. These are installed in the verification sandbox and on the user's machine during resolve_and_install.
dependencies:
- requests>=2.31
- beautifulsoup4>=4.12
- lxml>=5.0
If your tool uses only the Python standard library, provide an empty list:
dependencies: []
Version constraint formats follow pip conventions:
requests>=2.31— Minimum versionrequests>=2.31,<3.0— Version rangerequests==2.31.0— Exact version (not recommended — too rigid)requests— Any version (not recommended — may break with future releases)
Frameworks
The optional frameworks field indicates which agent frameworks your package is designed to integrate with. This is metadata for discoverability — it does not affect how the package works.
frameworks:
- langchain
- crewai
- autogen
If your package is framework-agnostic (most are), you can omit this field entirely.
Permissions
The optional permissions field declares what external resources your tool needs access to. This helps agents and users understand the security profile of the package before installing it.
permissions:
network:
- "https://api.example.com/*"
environment:
- EXAMPLE_API_KEY
filesystem:
- read: "/tmp/cache"
permissions.network
A list of URL patterns the tool makes HTTP requests to. Use wildcards for path segments.
permissions.environment
A list of environment variable names the tool reads. This signals to users that they need to set these variables before using the tool.
permissions.filesystem
Filesystem paths the tool reads from or writes to. Specify whether it is read or write access.
Permissions are currently informational — they are not enforced at runtime. But declaring them honestly helps users trust your package and may affect scoring in future specification versions.
Complete Example
Here is a full manifest for a multi-tool package with all optional fields:
manifest_version: "0.2"
package_id: weather-toolkit
version: "1.2.0"
capabilities:
tools:
- name: get_current_weather
entrypoint: weather_toolkit.current:get_current_weather
input_schema:
type: object
properties:
city:
type: string
description: "City name (e.g., 'London', 'New York')"
units:
type: string
enum: ["celsius", "fahrenheit"]
default: "celsius"
required: [city]
output_schema:
type: object
properties:
city:
type: string
temperature:
type: number
units:
type: string
condition:
type: string
humidity:
type: integer
- name: get_forecast
entrypoint: weather_toolkit.forecast:get_forecast
input_schema:
type: object
properties:
city:
type: string
description: "City name"
days:
type: integer
description: "Number of days to forecast (1-7)"
default: 3
required: [city]
output_schema:
type: object
properties:
city:
type: string
forecast:
type: array
items:
type: object
properties:
date:
type: string
high:
type: number
low:
type: number
condition:
type: string
runtime:
language: python
min_version: "3.10"
dependencies:
- httpx>=0.27
- python-dateutil>=2.9
frameworks:
- langchain
- crewai
permissions:
network:
- "https://api.openweathermap.org/*"
environment:
- OPENWEATHER_API_KEY
Common Mistakes
- Mismatched entrypoint and file path. If the entrypoint says
my_tool.core:run, the filemy_tool/core.pymust exist and contain a function calledrun. This is the most common cause of import failures. - Missing dependencies. If your code does
import requestsbutrequestsis not inruntime.dependencies, the install step passes but the import step fails. - Schema mismatch. If the
output_schemasays a field is anintegerbut your function returns afloat, you lose contract compliance points. - Using hyphens in module names. The
package_idcan bemy-tool, but the Python module directory must bemy_tool. Python cannot import modules with hyphens. - Forgetting
__init__.py. Without this file in your module directory, Python will not recognize it as an importable package. - Setting
min_versiontoo low. If you use features likematchstatements (3.10+) ortypealiases with|syntax (3.10+), set the minimum version accordingly.
Validation
Before publishing, you can validate your manifest locally by checking it against these rules:
manifest_versionis"0.2".package_idmatches the pattern^[a-z0-9]+(-[a-z0-9]+)*$.versionis valid semver.- Every tool has
name,entrypoint,input_schema, andoutput_schema. - Every
entrypointhas exactly one colon separating the module path from the function name. - The referenced files exist on disk.
The CLI also validates the manifest before uploading, so you will catch errors before they reach the verification pipeline.
For further details on publishing, see the Publishing Guide. For testing strategies that maximize your verification score, see Writing Tests for Your Agent Skill.
LLM Runtime: Let the Model Handle It
If your agent uses OpenAI or Anthropic tool calling, AgentNodeRuntime handles tool registration, system prompt injection, and the tool loop automatically. The LLM discovers, installs, and runs AgentNode capabilities on its own — no hardcoded tool calls needed.
from openai import OpenAI
from agentnode_sdk import AgentNodeRuntime
runtime = AgentNodeRuntime()
result = runtime.run(
provider="openai",
client=OpenAI(),
model="gpt-4o",
messages=[{"role": "user", "content": "your task here"}],
)
print(result.content)
The Runtime registers 5 meta-tools (agentnode_capabilities, agentnode_search, agentnode_install, agentnode_run, agentnode_acquire) that let the LLM search the registry, install packages, and execute tools autonomously. Works with Anthropic too — just change provider="anthropic" and pass an Anthropic client.
See the LLM Runtime documentation for the full API reference, trust levels, and manual tool calling.