Skip to main content

ard-kit

Self-hosted Agentic Resource Discovery (ARD) for local and private resources: catalog your own scripts/tools into an ai-catalog.json, then serve it through the two surfaces the spec defines — a static manifest at /.well-known/ard.json and a dynamic POST /search endpoint. python3 selfcheck.py asserts the pipeline end-to-end, and .gitlab-ci.yml runs it plus the official conformance CLI (ards-project/ard-spec) on every push where runner quota allows.

ARD is the discovery layer that sits in front of MCP (tools), Skills (instructions), and A2A (agents). It answers one question: "what capability can help with this task?" — invocation stays with the resource's own mechanism.

Why this exists

The pieces started life as a private in-house integration — a catalogizer over a large pile of local scripts and a registry serving them for intent-based lookup. When the ARD specification was announced (HF blog: Agentic Resource Discovery: Let agents search), the salvageable pieces were pulled out, generalized, and aligned to the spec. The original registry server code was lost in a workspace cleanup; registry.py here is a faithful rebuild against the public shape.

Pieces

File Role
catalogize.py Scans directories for .py/.sh scripts (AST docstrings, argparse flags, shell header comments), SKILL.md agent skills (YAML frontmatter → text/markdown; profile="urn:air:agent-skills" entries) and .mcp.json MCP client configs (→ application/mcp-server-card+json per server; env values never cataloged), emits ARD entries into ai-catalog.json plus an ai-catalog.inspect.json invoke-schema sidecar. Stdlib only.
registry.py Minimal HTTP registry: serves the manifest and POST /search (token-overlap ranking), POST /explore (501 opt-out), optional --upstreams federation fan-out, GET /inspect over the sidecar, optional --token bearer auth. Stdlib only.
mcp_server.py MCP stdio front over the same catalog: ard_search (ranked summaries) and ard_inspect (invoke command + CLI arguments) as MCP tools, so an editor mounts a command instead of being handed a URL. Stdlib only.
selfcheck.py End-to-end pipeline check: catalogize a temp dir, run search, assert ranking.
systemd/ard-registry.service Unit template for running the registry as a user service.

No dependencies beyond Python 3.10+ stdlib.

Install

pipx install agentic-ard-kit  # isolated venv, three commands on PATH
pipx install .         # same, from a checkout

This installs ard-catalogize, ard-registry and ard-mcp — the same entry points as python3 catalogize.py, python3 registry.py and python3 mcp_server.py. Running straight from a clone stays supported and needs no install at all.

Qoder plugin

ard-kit also ships as a self-contained Qoder plugin — the same code plus an agent-facing wrapper:

Component What it gives the agent
skills/ard-registry The discover → inspect → run → discard contract (env-driven endpoint: ARD_REGISTRY_URL, optional ARD_REGISTRY_TOKEN).
/ard-catalogize Slash command: index a script directory into ai-catalog.json and re-verify live.
/ard-serve Slash command: serve a catalog, confirm via /health.
bin/ard-registry, bin/ard-catalogize Entry points added to PATH (stdlib-only, no install step).
qoder plugins install ./ard-kit   # then /plugins reload
qoder plugins validate ./ard-kit  # manifest + component check

Quickstart

# 1. Catalog your scripts and agent skills (default scan dir: ./scripts)
python3 catalogize.py --dir scripts --dir .agents/skills --host myhost.example.com

# 2. Serve it
python3 registry.py --catalog ai-catalog.json --port 8390

# 3. Search (the ARD registry API shape)
curl -s http://127.0.0.1:8390/search \
  -H 'Content-Type: application/json' \
  -d '{"query": {"text": "scan subdomains"}, "pageSize": 5}'

# 4. Inspect before running (invoke command + CLI arguments)
curl -s 'http://127.0.0.1:8390/inspect?identifier=urn:air:myhost.example.com:script:scripts:scan_subdomains'

# 5. Static manifest (for crawlers / federation)
curl -s http://127.0.0.1:8390/.well-known/ard.json

The discover → inspect → run flow mirrors commercial directories like monid.ai, minus the marketplace: POST /search finds the capability, GET /inspect?identifier=<urn> returns its invoke command and parsed argparse flags (404 for unknown identifiers, 501 when the sidecar is absent), and the run itself stays with your shell.

For clients: the registry is stateless and nothing attaches to your session. POST /search returns ranked summaries only; pull a full invoke schema via /inspect for the single entry you actually run. Discard both afterwards — keep the URN if you might reuse the tool, not the payload. Discovery costs a query, not a mounting: there is nothing to unload because nothing was loaded.

Require a bearer token on every endpoint except /health when the registry leaves loopback. For service deployments prefer the ARD_REGISTRY_TOKEN environment variable over --token — the command line is world-readable:

python3 registry.py --catalog ai-catalog.json --port 8390 --token "$(openssl rand -hex 16)"
# or: ARD_REGISTRY_TOKEN=<token> python3 registry.py --catalog ai-catalog.json --port 8390

A token that is set but empty is rejected at startup (fail closed).

Federate with peer registries — with "federation": "auto" (default) queries fan out to --upstreams and results merge (every result names its source registry and carries a clamped score); "federation": "referrals" returns the peers in a referrals array instead; "federation": "none" stays local:

python3 registry.py --catalog ai-catalog.json --port 8390 \
  --upstreams https://peer.example.com --public-url https://me.example.com

Self-check the whole pipeline:

python3 selfcheck.py

MCP front

The registry is HTTP, which means something has to hand the agent a URL first. Editors that speak MCP mount a command instead, so the same catalog is also served over stdio — no server to start, no port, no token:

{
  "mcpServers": {
    "ard": {
      "command": "python3",
      "args": ["/path/to/ard-kit/mcp_server.py",
               "--catalog", "/path/to/ai-catalog.json"]
    }
  }
}

Installed through pipx, the same front is "command": "ard-mcp" with no path to keep in sync.

Two tools, the same discover → inspect → run contract:

Tool Returns
ard_search Ranked summaries (identifier, displayName, description, type, score) for an intent, optionally filtered by media type.
ard_inspect The invoke command and parsed CLI arguments for one urn:air: identifier.

Search deliberately returns summaries only: the invoke schema arrives once, for the single entry the agent actually runs. The catalog is re-read per call, so re-running catalogize.py is picked up without a restart, and the host owns the process lifetime — the server exits when stdin closes.

Entry shape

Each catalog entry carries the fields ARD consumers key on:

{
  "@context": "https://agenticresourcediscovery.org/context/v1",
  "identifier": "urn:air:myhost.example.com:script:scripts:scan_subdomains",
  "displayName": "scan_subdomains",
  "description": "Enumerate subdomains via passive sources",
  "type": "application/vnd.ard-kit.script+json",
  "url": "file:///path/to/scripts/scan_subdomains.py",
  "tags": ["scan", "subdomains", "recon"],
  "aliases": ["scan_subdomains"],
  "representativeQueries": [
    "Enumerate subdomains via passive sources",
    "scan", "subdomains", "recon"
  ],
  "metadata": { "invoke": "python3 scripts/scan_subdomains.py", ... }
}

representativeQueries lead with the natural description phrase and pad with keywords, so both sentence-style and token-style agent queries hit. Every entry carries the field: when a resource offers no keywords, the file or skill name is split to pad the list, which is always 2–5 phrases. Entries keep exactly one of url/data (spec §3.4) and scalar-only metadata values, and the manifest envelope carries only specVersion/host/entries — the shape the official ai-catalog.schema.json validates.

The type media type is free-form per the spec, but entries use a standard name wherever one exists — application/mcp-server-card+json for MCP servers, text/markdown; profile="urn:air:agent-skills" for agent skills — so any conformant registry routes them without a local mapping. Plain local scripts have no standard type yet and keep the vendor one. Identifiers follow the spec's Appendix C form (urn:air:<publisher>:<namespace>:<name>), and the served manifest prepends a self-advert entry of type application/ai-registry+json so peers can discover this registry's search base URL. Search results carry a score in the spec's 0–100 relevance band (relevance only — ARD decouples trust into the trust manifest, §5).

Prior art / positioning

  • HF Discover — reference implementation over the Hugging Face Hub; federated, semantic search.
  • ARD spec — the standard itself (Apache-2.0).
  • monid.ai — commercial take on the same pattern: a CLI/Skill teaching an agent to discover → inspect → run endpoints by intent. The difference: monid is a paid marketplace of third-party data endpoints behind an API key; ard-kit is the self-hosted, no-network, no-account version for resources you already own.

Known limitation: search here is lexical token overlap, not semantic ranking. That is deliberate — zero dependencies, and good enough for a few thousand private entries. The upgrade path is embeddings behind the same endpoint.

License

MIT.

Acknowledgements

Developed and hardened in Qoder — from the ARD v0.91 conformance rebuild through the ultra-review cycle.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agentic_ard_kit-0.10.0.tar.gz (21.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agentic_ard_kit-0.10.0-py3-none-any.whl (23.5 kB view details)

Uploaded Python 3

File details

Details for the file agentic_ard_kit-0.10.0.tar.gz.

File metadata

  • Download URL: agentic_ard_kit-0.10.0.tar.gz
  • Upload date:
  • Size: 21.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for agentic_ard_kit-0.10.0.tar.gz
Algorithm Hash digest
SHA256 d69aa35a22533cc3452b1a366117d7cb5f7b04f75b982c3374fc6c5adacdd72d
MD5 e10a5f30bb261350d71138083121b2f7
BLAKE2b-256 df048bc071c012e73a3facc48a719cc3da4e4df265245e28bd61f22ef37e475d

See more details on using hashes here.

File details

Details for the file agentic_ard_kit-0.10.0-py3-none-any.whl.

File metadata

File hashes

Hashes for agentic_ard_kit-0.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 14b865c25d47e47d257af74fe75e3431c564129ccc86814c32858f87941b08c3
MD5 55467d5c25a306c4721bbf7b21fcd12d
BLAKE2b-256 e8be4ed92093847ff0acae52374fb07a81e3f07412ca5631f1a93ca0d97cb382

See more details on using hashes here.

Release history Release notifications | RSS feed

0.11.0

2 files

0.10.1

2 files

This release

0.10.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page