API Reference

A search engine for AI-agent-callable capabilities — import it into your framework, copy a tool definition, or call POST /search / POST /resolve directly.

Connect this to your agent

Five ways to plug this in, in order of how little code you have to write.

1. Zero code — import the OpenAPI spec

Point your framework's tool-calling / plugin importer at the spec below. Most modern agent frameworks (and a growing number of LLM providers' own tool-use setup flows) can ingest an OpenAPI document directly and generate a working tool with no hand-written integration code.

GET /openapi.json

2. Copy-paste a ready-made tool definition

Same source of truth as the OpenAPI spec — generated from the actual request/response schemas, not hand-maintained, so it can't drift from what the API really does.

GET /tools/openai.json      // OpenAI Chat Completions / Responses API `tools` array
GET /tools/anthropic.json   // Claude Messages API `tools` array
// Example: OpenAI
const tools = await fetch("https://agent-capability-search-api.shamarwebsterrb.workers.dev/tools/openai.json")
  .then((r) => r.json());
// pass `tools` directly as the `tools` param on your Chat Completions call

3. Connect as an MCP server

If your agent already speaks MCP, add this as a server directly — no HTTP code to write, just config. It's a thin local passthrough to the same /search and /resolve endpoints below, using your own API key, so tiering/rate limits/billing all work exactly like calling the REST API yourself. (Runs locally via npx, not a remote hosted server — see packages/mcp-server/README.md in the repo for why, if you're curious.)

{
  "mcpServers": {
    "agent-capability-search": {
      "command": "npx",
      "args": ["-y", "@acs/mcp-server"],
      "env": { "ACS_API_KEY": "<your key>" }
    }
  }
}

Exposes two tools: search_capabilities and resolve_capability.

4. Use a client SDK

Typed request/response, an error type that carries the API's own status and body instead of a bare HTTP error, and a couple of function calls instead of raw fetch/requests boilerplate. TypeScript and Python are both built and live-verified against this API today, but not yet published to a registry — install straight from the repo for now (packages/sdk-ts, sdk/python), npm/PyPI publishing is a pending decision.

// TypeScript — packages/sdk-ts
import { AcsClient } from "@acs/sdk-ts";
const client = new AcsClient({ apiKey: "<your key>" });
const { results } = await client.search({ query: "weather", limit: 5 });
# Python — sdk/python
from acs_client import AcsClient
client = AcsClient(api_key="<your key>")
results = client.search("weather", limit=5)["results"]

5. Call the REST API directly

POST /search and POST /resolve, documented below — works from any language, any framework, zero dependencies.

Local-first agent orchestrators

Compatible out of the box with local-first agent platforms — the emerging class of orchestrator that runs its planning model on-device (often a swappable open-weight model) and only escalates to cloud tools with the user's explicit, per-step consent. Perplexity's "Portable Computer" is one concrete example; the same applies to any local orchestrator that escalates to MCP tools or OpenAI-format function-calling.

The MCP server above (option 3) is the recommended integration path for this audience: it's the same thin passthrough everyone else uses, but its two tool descriptions explicitly state that calling them sends your query or capability ID over the network to this hosted API — nothing runs or is processed on-device. That disclosure isn't decorative. A local-first orchestrator's consent UI has no way to inspect what a tool actually does before calling it; the description text is the only signal it has to tell the user "this step is about to leave your device." Tools that stay silent about being a network call make that UI lie to the user by omission. Ours doesn't.

Same billing, tiering, and rate limits as calling the REST API directly — see Authentication below.

Authentication

Pass your key as x-api-key. /search allows a small unauthenticated demo quota; /resolve always requires a key.

Tier /search /resolve
Free (no key) Limited demo quota Not allowed
Free (with key) Allowed 20 / day
Starter+ Allowed Higher limits, plus payment-hint detail and verified-only filtering

POST /search

Find capabilities matching a natural-language query.

Request

{
  "query": "get the current weather for a city",
  "protocol": ["mcp_tool", "rest_api"],   // optional
  "constraints": {                          // optional
    "verifiedOnly": true,
    "authType": "api_key",
    "paymentMethod": "free"
  },
  "limit": 10,                              // 1-50, default 10
  "cursor": null                            // optional pagination cursor
}

Response

{
  "results": [
    {
      "capabilityId": "b6f1a2b0-1c2d-4e3f-8a9b-000000000002",
      "name": "get_weather",
      "description": "Returns current weather for a city.",
      "protocol": "mcp_tool",
      "provider": { "id": "...", "name": "Acme Weather" },
      "score": 0.94,
      "verificationStatus": "scanned_clean",
      "paymentHintSummary": ["free"]
    }
  ],
  "nextCursor": null
}

Example

curl -X POST https://api.example.com/search \
  -H "content-type: application/json" \
  -d '{"query":"weather"}'

POST /resolve

Get everything needed to invoke a capability returned by /search.

Request

{
  "capabilityId": "b6f1a2b0-1c2d-4e3f-8a9b-000000000002",
  "intentContext": "user is asking about weather in Berlin"  // optional
}

Response

{
  "capabilityId": "b6f1a2b0-1c2d-4e3f-8a9b-000000000002",
  "protocol": "mcp_tool",
  "endpoint": { "url": "https://...", "method": "streamable-http" },
  "auth": { "type": "none" },
  "schema": { "input": { ... }, "output": { ... } },
  "payment": { "accepted": ["free"], "providerDeclared": true, "verified": false },
  "safety": { "verificationStatus": "scanned_clean", "lastScannedAt": "2026-08-01T00:00:00Z" },
  "expiresAt": "2026-08-29T00:10:00Z"
}

Example

curl -X POST https://api.example.com/resolve \
  -H "content-type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{"capabilityId":"b6f1a2b0-1c2d-4e3f-8a9b-000000000002"}'

Safety

Every capability is scanned before listing. verificationStatus tells you what stage it's at — only scanned_clean and manual_reviewed capabilities are ever returned by /search or /resolve. Flagged or delisted capabilities are excluded automatically.