Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Serve Your Agent Card

The current exporter uses the legacy A2A v0.4.0 card shape. Interoperability with current released A2A peers remains unproven.

Registry status (observed 2026-07-11): npm serves @hai.ai/jacs@0.10.1, while these pages describe source 0.11.4. The registry package does not expose every method shown here. Pin the version and inspect its exports; use a source build only when that is an explicit deployment choice.

Make your JACS agent discoverable by other A2A agents.

These helpers serve discovery documents only. They do not implement message/task handlers or the legacy optional /jacs/sign and /jacs/verify host examples in the extension descriptor. Configure the signed public interface for a service your host actually implements; a local discovery listener does not create that service or grant remote signing access.

Prerequisites: pip install jacs[a2a-server] (Python) or npm install @hai.ai/jacs express (Node.js).

from jacs.a2a import JACSA2AIntegration

JACSA2AIntegration.quickstart(name="my-agent", domain="my-agent.example.com").serve(port=8080)

Your agent is now discoverable at http://localhost:8080/.well-known/agent-card.json.

This local listener does not rewrite the card's signed public interface URL.

Production: Mount into Your Own FastAPI App

from fastapi import FastAPI
from jacs.client import JacsClient
from jacs.a2a_server import jacs_a2a_routes

app = FastAPI()
client = JacsClient.quickstart(name="my-agent", domain="my-agent.example.com")
router = jacs_a2a_routes(client)
app.include_router(router)
const express = require('express');
const { JacsClient } = require('@hai.ai/jacs/client');
const { jacsA2AMiddleware } = require('@hai.ai/jacs/a2a-server');

const client = await JacsClient.quickstart({
  name: 'my-agent',
  domain: 'my-agent.example.com',
});
const app = express();
app.use(jacsA2AMiddleware(client));
app.listen(8080);

Your agent is now discoverable at http://localhost:8080/.well-known/agent-card.json.

What Gets Served

The native generator serves six .well-known endpoints automatically:

EndpointPurpose
/.well-known/agent-card.jsonA2A Agent Card with JWS signature
/.well-known/jwks.jsonStable ES256 compatibility JWK used by the Agent Card
/.well-known/jacs-compat-binding.jsonNative-root-signed binding from the ES256 key to the claimed JACS identity
/.well-known/jacs-agent.jsonJACS agent descriptor
/.well-known/jacs-pubkey.jsonJACS public key
/.well-known/jacs-extension.jsonJACS provenance extension descriptor

The Agent Card includes the urn:jacs:provenance-v1 extension in capabilities.extensions, signaling to other JACS agents that your agent supports cryptographic provenance.

The card and JWKS reuse the persisted ES256 compatibility key across calls and restarts. The card references /.well-known/jacs-compat-binding.json by both fixed path and content hash; strict verification checks that native-root-signed artifact before treating the card as the explicitly trusted JACS identity. Existing pre-compatibility agents must run jacs agent add-compat-key once before serving. Local loopback trust tests additionally require JACS_ALLOW_PRIVATE_JWKS=true; private-address JWKS fetching is otherwise denied.

Strict verifiers accept a compatibility binding for at most seven days after its signed issuedAt, with five minutes of future clock skew. Generating the well-known set refreshes an authentic binding after six days under the shared issuance lock, preserving its scopes and any explicit expiresAt. The FastAPI and Express mounts call the generator lazily at that six-day boundary. HTTP freshness ends by renewal or earlier expiry; failed renewal can serve a still-valid snapshot with no-store, while hard expiry returns 503. Finite expiry requires renewed authorization and remounting. Separate resource fetches can straddle replacement; verify the card/JWKS/binding together and refetch if their references differ.

Next Steps