Plug-and-play ARD (Agentic Resource Discovery) publisher & registry middleware for FastAPI, FastMCP and AG2 backends.
Project description
ardkit (Python)
Plug-and-play ARD (Agentic Resource Discovery) publisher & registry middleware for Python backends.
ARD lets AI clients discover your agents, MCP servers and skills before they
invoke them — instead of every tool description being crammed into the model's
context window. ardkit turns any FastAPI / FastMCP / AG2 backend into an ARD
publisher (and, optionally, a search registry) in a few lines.
pip install "ardkit-ai[fastapi]" # import name stays `ardkit`
The PyPI distribution is
ardkit-ai(the bare nameardkitwas already taken); the import package isardkit.
Quickstart — one call
If your app already mounts its MCP server(s), publish finds them and exposes the
lot — no manual catalog needed:
from fastapi import FastAPI
from ardkit.integrations.fastapi import publish
app = FastAPI()
app.mount("/mcp/billing", billing_mcp.http_app()) # your FastMCP, as usual
publish(app, host="Acme AI", publisher="acme.com", base_url="https://app.acme.com")
publish never mounts anything — it reads the route table, maps each mounted
FastMCP back to its instance (identity-based, via fastmcp's app state), introspects
its tools into capabilities, and builds the correct public URL from base_url +
the mount path. Pass mcps=[billing_mcp, ...] to expose specific servers
(unmounted instances are ignored), and introspect=False to expose only those.
That serves:
| Route | What |
|---|---|
GET /.well-known/ai-catalog.json |
the manifest (application/json, Access-Control-Allow-Origin: *) |
GET /robots.txt |
with an Agentmap: directive pointing at the manifest |
Or build the catalog by hand
from ardkit import Catalog
from ardkit.integrations.fastapi import mount_ard
catalog = Catalog(host="Acme AI", publisher="acme.com", identifier="did:web:acme.com")
catalog.add_mcp_server(
name="Billing",
url="https://acme.com/mcp",
capabilities=["create_invoice", "list_invoices"],
representative_queries=["create an invoice", "show unpaid invoices"],
)
mount_ard(app, catalog)
Validate a manifest any time from Python:
from ardkit.validation import validate_manifest
errors = validate_manifest(catalog.to_dict()) # [] when it conforms to ai-catalog v1.0
Catalog as a cacheable document origin
When discovery is published on an apex host but the catalog's source of truth is a
backend on another host, expose the manifest as a cacheable JSON document on the
backend and have the apex consume it (see ardkit-ts remoteCatalog):
from ardkit.integrations.fastapi import add_catalog_route
add_catalog_route(app, catalog, path="/api/ard/ai-catalog.json")
add_catalog_route (and mount_ard) emit a weak ETag + Cache-Control and
answer conditional If-None-Match with 304, so the document is efficiently
cacheable by the apex/edge.
Auto-derive entries from your frameworks
from ardkit.adapters import from_mcp_server, from_ag2_agent
# Introspect a FastMCP / mcp-SDK server -> mcp-server-card entry (capabilities = tool names)
catalog.add(from_mcp_server(my_mcp_server, url="https://acme.com/mcp", publisher="acme.com"))
# Map an AG2 / AutoGen agent -> a2a-agent-card entry
catalog.add(from_ag2_agent(my_agent, url="https://acme.com/a2a/agent", publisher="acme.com"))
Optional: be a registry (bring your own search)
ardkit owns the ARD wire contract (request parsing, filters, pagination,
federation, error codes, response shaping). You own ranking by implementing
SearchProvider — or use the bundled InMemorySearchProvider for tests/demos.
from ardkit.registry import RegistryService
from ardkit.registry.memory import InMemorySearchProvider
service = RegistryService(
InMemorySearchProvider(catalog.entries), # swap for your search engine
source="https://registry.acme.com/ard/",
)
mount_ard(app, catalog, registry=service, registry_prefix="/ard")
# -> POST /ard/search, POST /ard/explore, GET /ard/agents
Implement your own backend by satisfying the protocol:
from ardkit.registry import SearchQuery
from ardkit.registry.models import SearchPage, ScoredEntry
class MySearch: # SearchProvider (structural typing)
async def search(self, query: SearchQuery, *, page_size, page_token) -> SearchPage:
hits = await my_vector_db.query(query.text, filters=query.filter, k=page_size)
return SearchPage(items=[ScoredEntry(entry=h.card, score=h.score) for h in hits])
explore and list_agents are optional — omit them and the endpoints return
HTTP 501 as the spec allows.
What's in the box
- Spec models (
ardkit.models) — Pydantic v2, mirroringai-catalog.schema.json(URN validation,urlXORdata,representativeQueries2–5, trust manifest). - Builder (
ardkit.Catalog) — mints URNs, sets media types, dynamic catalogs. - Adapters (
ardkit.adapters) — FastMCP / mcp-SDK / AG2. - FastAPI integration (
ardkit.integrations.fastapi) —publish(one call, reads your mounted MCPs),mount_ard,add_catalog_route. - Registry (
ardkit.registry) — BYO-search service + FastAPI router + in-memory provider. - Discovery helpers (
ardkit.discovery) — robotsAgentmap,<link>, DNS records. - Validation (
ardkit.validation) — conformance against the vendored JSON Schema.
Install extras
| Extra | Adds | For |
|---|---|---|
validation |
jsonschema |
ardkit.validation |
fastapi |
fastapi, starlette |
mount_ard, registry router |
mcp |
mcp |
typing-only convenience for MCP adapters |
ag2 |
ag2 |
typing-only convenience for AG2 adapter |
all |
the above | everything |
The adapters duck-type framework objects, so you can use them without the matching extra installed.
Development
uv sync --group testing --group lint
uv run pytest
uv run ruff check src tests && uv run ruff format src tests --check
uv run pyright src/ardkit
The ARD schemas under src/ardkit/schemas/ are vendored from
ards-project/ard-spec; refresh them
with python scripts/vendor_schemas.py.
License
Apache-2.0 — matching the ARD specification. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ardkit_ai-0.1.0.tar.gz.
File metadata
- Download URL: ardkit_ai-0.1.0.tar.gz
- Upload date:
- Size: 38.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8da464b2c75541c6983f9b4a0a4969edd999274a83a0bcd953c530b57796c01f
|
|
| MD5 |
4c8d2e0a1e6255626834fafaf4e53320
|
|
| BLAKE2b-256 |
ba747ab5ea50a7a9a550ff753fb750fb831945f396d8d66b280aaaf1fa8a2891
|
Provenance
The following attestation bundles were made for ardkit_ai-0.1.0.tar.gz:
Publisher:
release_pypi.yaml on arterialist/ardkit-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ardkit_ai-0.1.0.tar.gz -
Subject digest:
8da464b2c75541c6983f9b4a0a4969edd999274a83a0bcd953c530b57796c01f - Sigstore transparency entry: 2031755457
- Sigstore integration time:
-
Permalink:
arterialist/ardkit-py@af90f2eb32b13d25f977fa8ce1e09e2b92f176f9 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/arterialist
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release_pypi.yaml@af90f2eb32b13d25f977fa8ce1e09e2b92f176f9 -
Trigger Event:
release
-
Statement type:
File details
Details for the file ardkit_ai-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ardkit_ai-0.1.0-py3-none-any.whl
- Upload date:
- Size: 43.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e5e8e5f89c1be151bce1de1e88ddb9ca7fcee1e9fa87d672b103fdce37571b2f
|
|
| MD5 |
4e0863de4917fc26f86ba2cd8c735c5f
|
|
| BLAKE2b-256 |
9ed084cd3e61a89bd8a70698c121315d9a686b0fb065140cef341cca9b4fb6da
|
Provenance
The following attestation bundles were made for ardkit_ai-0.1.0-py3-none-any.whl:
Publisher:
release_pypi.yaml on arterialist/ardkit-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ardkit_ai-0.1.0-py3-none-any.whl -
Subject digest:
e5e8e5f89c1be151bce1de1e88ddb9ca7fcee1e9fa87d672b103fdce37571b2f - Sigstore transparency entry: 2031755847
- Sigstore integration time:
-
Permalink:
arterialist/ardkit-py@af90f2eb32b13d25f977fa8ce1e09e2b92f176f9 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/arterialist
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release_pypi.yaml@af90f2eb32b13d25f977fa8ce1e09e2b92f176f9 -
Trigger Event:
release
-
Statement type: