Agents do not fail safely
Today, agents operate in a fundamentally unsafe model: input → reasoning → tool call → execution. At the point of execution, cost is unknown, permissions are implicit, side effects are hidden, and failure is opaque. The system assumes the agent made the right decision. That assumption is wrong.
call → fail → retry blindly
Agent triggers irreversible action without
understanding consequences
Agent misuses authority it doesn't reason about
Agent cannot recover from permission failures
Agent cannot explain or justify decisions
before execution
understand → evaluate → decide → act (or not)
Agent sees cost, authority, side effects,
and reversibility before acting
Agent checks permissions and budget before
attempting execution
Agent receives structured recovery guidance
when blocked
Agent can escalate to a human when authority
is insufficient
The gap
APIs describe how to call systems. They do not describe what an action means.
What APIs tell agents
- Endpoint URL and HTTP method
- Input/output schema
- Authentication mechanism
What agents actually need
- What does this action cost?
- Is it reversible?
- Am I authorized to do this?
- What are the side effects?
- What do I do if I'm blocked?
For humans, this context lives in documentation, intuition, and experience. Agents have none of these. ANIP makes it part of the interface.
How it works
An ANIP service exposes a standard set of endpoints. Agents discover what's available, check permissions, then invoke with full context.
Discover
Agent fetches the discovery document and manifest to learn what capabilities exist, their side effects, costs, and required scopes.
curl https://service.example/.well-known/anip
Evaluate
Agent checks permissions before acting. The service tells the agent what's available, restricted, or denied — not after a failed call, but on request.
{
"available": [{ "capability": "search_flights", "scope_match": "travel.search" }],
"restricted": [{ "capability": "book_flight", "reason": "missing scope", "grantable_by": "human" }],
"denied": []
}
Invoke
Agent invokes with a scoped delegation token. The response includes structured success or failure with recovery guidance, cost, and lineage identifiers.
{
"success": true,
"invocation_id": "inv_7f3a2b",
"result": { "flights": [{ "number": "AA100", "price": 420 }] },
"cost_actual": { "currency": "USD", "amount": 0 }
}
Verify
Every invocation is audit-logged with signed checkpoints. Agents, operators, and compliance tools can verify what happened, when, and under what authority.
curl -X POST https://service.example/anip/audit \
-H "Authorization: Bearer <token>" \
-d '{"capability": "search_flights", "limit": 5}'
Build an ANIP service in minutes
You write business logic. The runtime handles discovery, JWT tokens, signed manifests, delegation validation, audit logging, and Merkle checkpoints.
- Python
- TypeScript
- Go
- Java
- C#
from fastapi import FastAPI
from anip_service import ANIPService, Capability
from anip_fastapi import mount_anip
service = ANIPService(
service_id="my-service",
capabilities=[
Capability(
name="search_flights",
description="Search available flights",
side_effect="read",
scope=["travel.search"],
handler=lambda ctx, params: {
"flights": [{"number": "AA100", "price": 420}]
},
),
],
authenticate=lambda bearer: {
"demo-key": "human:[email protected]"
}.get(bearer),
)
app = FastAPI()
mount_anip(app, service)
import { Hono } from "hono";
import { createANIPService, defineCapability } from "@anip-dev/service";
import { mountAnip } from "@anip-dev/hono";
const searchFlights = defineCapability({
name: "search_flights",
description: "Search available flights",
sideEffect: "read",
scope: ["travel.search"],
handler: async (ctx, params) => ({
flights: [{ number: "AA100", price: 420 }],
}),
});
const service = createANIPService({
serviceId: "my-service",
capabilities: [searchFlights],
trust: "signed",
authenticate: (bearer) =>
({ "demo-key": "human:[email protected]" })[bearer] ?? null,
});
const app = new Hono();
mountAnip(app, service);
package main
import (
"net/http"
"github.com/anip-protocol/anip/packages/go/service"
"github.com/anip-protocol/anip/packages/go/httpapi"
)
func main() {
svc, _ := service.New(service.Config{
ServiceID: "my-service",
Capabilities: []service.CapabilityDef{searchFlights()},
Storage: "sqlite:///anip.db",
Trust: "signed",
Authenticate: func(bearer string) *string {
keys := map[string]string{
"demo-key": "human:[email protected]",
}
if p, ok := keys[bearer]; ok { return &p }
return nil
},
})
defer svc.Shutdown()
svc.Start()
mux := http.NewServeMux()
httpapi.MountANIP(mux, svc)
http.ListenAndServe(":9100", mux)
}
@SpringBootApplication
public class Application {
@Bean
public ANIPService anipService() {
return new ANIPService(new ServiceConfig()
.setServiceId("my-service")
.setCapabilities(List.of(
SearchFlightsCapability.create()
))
.setStorage("sqlite:///anip.db")
.setTrust("signed")
.setAuthenticate(bearer -> {
Map<String, String> keys = Map.of(
"demo-key", "human:[email protected]"
);
return Optional.ofNullable(keys.get(bearer));
}));
}
@Bean
public AnipController anipController(ANIPService s) {
return new AnipController(s);
}
}
var builder = WebApplication.CreateBuilder(args);
var service = new AnipService(new ServiceConfig {
ServiceId = "my-service",
Capabilities = [SearchFlightsCapability.Create()],
Storage = "sqlite:///anip.db",
Trust = "signed",
Authenticate = bearer => {
var keys = new Dictionary<string, string> {
["demo-key"] = "human:[email protected]"
};
return keys.TryGetValue(bearer, out var p) ? p : null;
}
});
builder.Services.AddAnip(service);
var app = builder.Build();
app.MapControllers();
app.Run();
Same result in every language — 9 protocol endpoints, signed manifest, delegation-based auth, structured failures, and a verifiable audit log.
Follow the quickstartWhat ships today
ANIP is not a spec waiting for implementations. It ships working runtimes, tools, and examples across five languages.
5 runtimes
TypeScript, Python, Java, Go, and C#. Each runtime handles the full protocol — discovery, delegation, audit, checkpoints — so you only write capabilities.
3 transports
HTTP (all runtimes), stdio via JSON-RPC 2.0 (all runtimes), and gRPC via shared proto (Python + Go). Same capabilities, multiple wire formats.
Interface adapters
Mount REST (auto-generated OpenAPI + Swagger), GraphQL (auto-generated SDL), and MCP (Streamable HTTP) alongside native ANIP on the same service.
ANIP Studio
Inspection and invocation UI. Connect to any ANIP service, browse capabilities, check permissions, invoke with structured failure display. Try it live.
Testing tools
Conformance suite validates protocol compliance. Contract testing verifies declared side effects match observed behavior. Both run against any runtime.
Showcase apps
Travel booking, financial operations, and DevOps infrastructure — three full ANIP services with guided comparison scenarios. Try the playground.
How ANIP compares
ANIP is not a replacement for HTTP, gRPC, or MCP. It adds the execution context layer that those protocols don't provide.
| Capability | REST / OpenAPI | MCP | ANIP |
|---|---|---|---|
| Tool / endpoint discovery | OpenAPI spec | Yes | Yes |
| Side-effect declaration | No | No | read / write / transactional / irreversible |
| Permission discovery before invoke | No | No | available / restricted / denied |
| Scoped delegation (not just auth) | No | No | JWT delegation chains with scope + budget |
| Cost declaration + actual cost | No | No | Declared range + actual returned |
| Structured failure + recovery | HTTP status codes | Error codes | Type, detail, resolution, grantable_by, retry |
| Audit logging | App-specific | No | Protocol-level with retention + classification |
| Signed manifests + checkpoints | No | No | JWKS + Merkle checkpoints |