librarian

One librarian for every API your agents use.

Agents ask librarian for data instead of carrying their own API keys. It learns an API the first time one is needed, asks a person for the key once, serves reads within policy, and holds every write until a person approves it.

pip install librarian-a2a
docker pull ghcr.io/kultar/librarian:0.11.0

Open source, Apache-2.0. Alpha: expect breaking changes before 1.0.

release-notes agent support assistant triage bot A2A or MCP librarian policy engine with the key Jira GitHub internal APIs registry (git)what each API is,which operations are reads secret storekeys people add;agents see references peoplereview the registry,add keys, approve writes

What happens on a request

Nothing is set up per API in advance. The registry fills itself as agents need things, and a person is asked only when a key is missing or data would change.

  1. An agent asks for data from an API librarian doesn't know yet

    Over A2A or MCP, through a gateway such as LiteLLM or directly. The agent names the API and what it wants; it never names a host, so it can't point librarian anywhere else.

  2. librarian learns the API

    From its OpenAPI spec, else its documentation (found by itself if needed, with every extracted operation quote-checked against the page), else the model's own knowledge. Reads work at once; a pull request is opened on your registry repo so a person can review the entry.

  3. If the API needs a key, a person is asked once

    The agent's task waits and approvers get a Slack card. Someone follows the one-time link, signs in and pastes the key. It goes straight to your secret store, never through Slack, an agent or a model, and the task carries on by itself.

  4. Writes wait for a person's approval, every time

    The approval page shows exactly what will be sent: method, path, arguments and body. Approve once, or allow similar writes with a narrow, expiring grant. DELETEs can only ever be approved one at a time.

Why it's safe to put between agents and your APIs

The design assumes that agents can be talked into anything. So nothing an agent, a document or a model says can change what librarian is allowed to do.

The model never decides
A deterministic policy engine with no LLM in it authorises every call. The optional planner can only plan reads and propose writes.
Credentials never travel through agents
Keys enter on a one-time page and go straight to the secret store. Agents, messages, logs and the model only ever see references like jira/readonly.
Writes need a person
A verified registry entry, a separate write credential, and a human approval or a grant pinned to an agent, a person and an operation. Each write is sent once, with no redirects and an idempotency key, and claimed atomically so replicas never run it twice.
Untrusted input is fenced
The API host only ever comes from the caller's base_url, never from documentation or search results. Read versus write is decided by HTTP method. Search results are trust-ranked and third-party sites are skipped by default.
No way out to your network
An SSRF guard with DNS pinning refuses private addresses unless you allow them, redirects stay on the same origin, and response sizes are capped.
Approval pages are locked down
A separate listener behind your SSO proxy, one-time HMAC links that expire, a strict content security policy with no external resources, and every decision recorded with who made it.

The full threat model lists each threat and its mitigation.

Get started

Three paths, depending on where you are. Each one is documented step by step and has been followed end to end.

On your laptop

Ten minutes with Docker. You see an API learned on demand, a key asked for out of band, and a write held for approval.

git clone https://github.com/kultar/librarian
cd librarian/examples/quickstart
docker compose up -d
./ask '{"skill":"capabilities"}'
Getting started

For your team

A Helm chart with oauth2-proxy sign-in, git-sync for the registry, Postgres for shared state and AWS Secrets Manager for keys. Two or more replicas, no volumes, nothing exposed to the internet.

helm install librarian ./deploy/helm/librarian \
  -n librarian -f values.yaml
helm test librarian -n librarian
Deploying for a team

Connect your agents

Behind LiteLLM's agent gateway librarian is both an MCP server and an A2A agent. Any A2A or MCP client can also talk to it directly.

# LiteLLM config.yaml
mcp_servers:
  librarian:
    url: http://librarian.librarian.svc:8080/mcp
    transport: http
    auth_type: bearer_token
    auth_value: os.environ/LIBRARIAN_GATEWAY_KEY
Integrations

What agents can ask for

The same five skills over A2A and as MCP tools. Only fetch uses a model; everything else is plain code.

SkillWhat it does
capabilitiesWhich APIs and read operations this agent may use.
executeRun one read operation, with optional field selection and pagination.
onboardTeach librarian an API: a spec URL, a docs URL, or just a base URL.
writeChange data, after a person approves it or a grant covers it.
fetchPlain language ("open bugs assigned to the payments team"), planned by a model and executed by the policy engine.

Every result carries provenance: which API and operation, the URL with secrets redacted, when, for which agent and person, and which credential reference. The audit log is always on.

Documentation

Roadmap

Done

  • Reads within policy, writes with approval or grants
  • Learning from specs, documentation and model knowledge, with change detection
  • Slack cards, Helm chart, GitHub App for the registry repo
  • MCP endpoint and the LiteLLM gateway
  • Verified principals from your identity provider
  • Replicas with shared state and no volumes
  • Internal APIs learned on demand within the domains you list

Next

  • Rate limits shared across replicas

Later

  • Per-user OAuth for APIs that need the person's own access
  • Vault, GCP Secret Manager and Azure Key Vault
  • A community registry of reviewed, signed entries