Skip to content

marmar9615-cloud/agentbridge-protocol

AgentBridge

An AI-native action layer for the web.

Web apps publish a manifest of structured, permissioned actions. AI agents discover, validate, and call those actions through MCP — instead of clicking around UIs that were designed for humans.

CI License: Apache 2.0 TypeScript Next.js MCP Status: v0.4.0 npm


Status

AgentBridge v0.4.0 is live on npm under the @marmarlabs scope (published via npm Trusted Publishing with SLSA build provenance). The v0.4.0 line ships the opt-in Streamable HTTP MCP transport, adopter quickstart, manifest-pattern catalogue, and OpenAPI regression fixtures. See docs/releases/v0.4.0.md for the full release notes.

v0.5.0 (Signed manifests) is in design — design-first PR landing now, no runtime change yet. Publishers will be able to sign their /.well-known/agentbridge.json with a key set served at /.well-known/agentbridge-keys.json; agents and the MCP server will verify the manifest offline before trusting any action. Verification is additive — confirmation gate, origin pinning, target-origin allowlist, audit redaction, stdio stdout hygiene, and HTTP transport auth/origin checks all continue to enforce on top. See docs/designs/signed-manifests.md and docs/adr/0002-signed-manifests.md for the design and decision record. Tracking issue: #31.

The v0.4.0 line shipped:

No published v0.x release alone is v1.0 production readiness; each is a step toward it. The HTTP transport is experimental in v0.4.0.

npm install @marmarlabs/agentbridge-sdk @marmarlabs/agentbridge-core
npx @marmarlabs/agentbridge-cli scan http://localhost:3000
npx @marmarlabs/agentbridge-mcp-server

AgentBridge is usable today for local development, app prototyping, manifest authoring, scanner workflows, OpenAPI import, and MCP experiments. It is not yet production security infrastructure — signed manifests (v0.5.0, in design), OAuth scope enforcement, and distributed audit storage are roadmap items (see docs/roadmap.md). Destructive demo actions remain simulated.

For release notes, see docs/releases/v0.4.0.md for the latest shipped release, docs/releases/v0.3.0.md for the production-foundations release, docs/releases/v0.2.2.md for the Codex onboarding release, docs/releases/v0.2.1.md for the docs cleanup patch, and docs/releases/v0.2.0.md for the first public release.


Table of contents


Why agent-native interfaces matter

Today's web is built around the assumption that a human will be there — clicking, scrolling, reading visual hierarchy, dismissing modals, recovering from confusing error states. When an AI agent has to operate that same surface, it ends up driving a browser blindly:

  • Inferring intent from button labels and DOM structure
  • Guessing at element selectors that change between deploys
  • Hoping confirmation dialogs don't appear unexpectedly
  • Praying that nothing visual changes mid-flow

The result is brittle, slow, and unsafe. There's no reliable way for an agent — or its operator — to reason about what an action will do before it happens.

The thesis

Apps shouldn't force agents to operate a UI built for human eyes. Apps should publish what they actually do — semantically, with types, with risk metadata, with clear confirmation requirements — so agents can reason about actions before invoking them.


What is AgentBridge?

AgentBridge is a manifest format + SDK + MCP server that lets any web app expose its operations to AI agents safely.

The core unit is a manifest served at a well-known URL:

https://your-app.com/.well-known/agentbridge.json

The manifest declares every action the app supports, with:

Field Purpose
name, title, description Semantic identity an agent can reason about
inputSchema (JSON Schema) Validate inputs before invocation
outputSchema (JSON Schema) Tell agents what to expect back
risk: low | medium | high Triage which actions need human-in-the-loop
requiresConfirmation: bool Force an explicit approval step
humanReadableSummaryTemplate Generate natural-language confirmation prompts
permissions[] Document required scopes
examples[] Teach agents the correct call shape

An MCP server bridges any AgentBridge-enabled site to MCP-speaking agents (OpenAI Codex, Claude Desktop, Cursor, custom MCP clients) with enforcement built in: risky actions never execute without explicit confirmationApproved: true, every call is audited, and outbound requests are pinned to the manifest's origin.


How it works

flowchart LR
    A["🧑 Human user"] --> B["Web app UI<br/>orders.acme.com"]
    C["🤖 AI agent"] --> D["MCP client<br/>Codex / Claude Desktop / Cursor / custom"]
    D <--> E["AgentBridge<br/>MCP server"]
    E -->|fetch manifest| F["/.well-known/<br/>agentbridge.json"]
    E -->|invoke action| G["/api/agentbridge/<br/>actions/:name"]
    F --> B
    G --> B
    E --> H[("Audit log")]

    style A fill:#dbeafe,stroke:#2563eb
    style C fill:#fee2e2,stroke:#dc2626
    style E fill:#fef3c7,stroke:#d97706
    style H fill:#f3f4f6,stroke:#6b7280
Loading

The same web app serves two audiences:

  • Humans see the visual UI, click around, and get rich layout
  • Agents see the manifest, validate inputs, and invoke structured actions

Both flows share the same backend logic. Both write to the same audit log. The only difference is whether the caller is a browser or a programmatic agent.


Architecture

flowchart TB
    subgraph workspace["agentbridge/ (npm workspace)"]
        direction TB

        subgraph packages["packages/"]
            CORE["📦 agentbridge-core<br/><i>schemas, types,<br/>validation, audit</i>"]
            SDK["📦 agentbridge-sdk<br/><i>defineAgentAction,<br/>manifest builder</i>"]
            SCAN["📦 agentbridge-scanner<br/><i>readiness scoring,<br/>structured checks</i>"]
            OAPI["📦 agentbridge-openapi<br/><i>OpenAPI 3.x →<br/>manifest converter</i>"]
            CLI["📦 agentbridge-cli<br/><i>scan, validate, init,<br/>generate, mcp-config</i>"]
        end

        subgraph apps["apps/"]
            DEMO["🛒 demo-app  (:3000)<br/><i>Fake order management.<br/>Serves manifest + actions.</i>"]
            STUDIO["🎛 studio  (:3001)<br/><i>Developer dashboard.<br/>Scan, exercise, audit.</i>"]
            MCP["🔌 mcp-server  (stdio)<br/><i>Tools, resources, prompts.<br/>Confirmation tokens + idempotency.</i>"]
        end

        DATA[("📁 data/<br/>audit · confirmations · idempotency")]
    end

    SDK --> CORE
    SCAN --> CORE
    OAPI --> CORE
    CLI --> CORE
    CLI --> SCAN
    CLI --> OAPI
    DEMO --> SDK
    DEMO --> CORE
    STUDIO --> SCAN
    STUDIO --> CORE
    MCP --> SCAN
    MCP --> CORE

    DEMO -.writes.-> DATA
    STUDIO -.writes.-> DATA
    MCP -.writes.-> DATA
    STUDIO -.reads.-> DATA
    DEMO -.reads.-> DATA

    style CORE fill:#dbeafe,stroke:#2563eb
    style SDK fill:#dbeafe,stroke:#2563eb
    style SCAN fill:#dbeafe,stroke:#2563eb
    style OAPI fill:#dbeafe,stroke:#2563eb
    style CLI fill:#dbeafe,stroke:#2563eb
    style DEMO fill:#dcfce7,stroke:#16a34a
    style STUDIO fill:#dcfce7,stroke:#16a34a
    style MCP fill:#fef3c7,stroke:#d97706
    style DATA fill:#f3f4f6,stroke:#6b7280
Loading

The confirmation flow

This is the heart of the safety story. Risky actions never execute on a single agent call — they require a deliberate, two-step approval.

sequenceDiagram
    autonumber
    participant Agent as 🤖 Agent
    participant MCP as MCP Server
    participant App as Web App
    participant Audit as Audit Log

    Agent->>MCP: call_action(execute_refund_order, input)
    MCP->>App: GET /.well-known/agentbridge.json
    App-->>MCP: manifest (action.risk = "high")
    MCP->>MCP: validate input vs JSON Schema
    Note over MCP: risk=high & no confirmationApproved
    MCP->>Audit: status: confirmation_required
    MCP-->>Agent: { status: "confirmationRequired",<br/>summary: "EXECUTE refund draft xyz",<br/>hint: "re-call with confirmationApproved: true" }

    Note over Agent: Agent presents the<br/>summary to a human

    Agent->>MCP: call_action(..., confirmationApproved: true)
    MCP->>MCP: re-validate, re-fetch manifest
    Note over MCP: confirmation cleared ✓
    MCP->>App: POST /api/agentbridge/actions/execute_refund_order
    App-->>MCP: { simulated: true, simulatedTransactionId: "..." }
    MCP->>Audit: status: completed, confirmationApproved: true
    MCP-->>Agent: { status: "ok", result: { ... } }
Loading

The Studio dashboard enforces the same gate visually — the operator must type CONFIRM in a modal before any medium- or high-risk action runs.


Quick start

git clone https://github.com/marmar9615-cloud/agentbridge-protocol.git
cd agentbridge-protocol

npm install      # pulls Next.js, MCP SDK, Zod, etc.
npm test         # all suites should pass
npm run dev      # demo on :3000, Studio on :3001

Then open:

To run the MCP server (stdio) for an MCP client:

npm run dev:mcp

Requirements: Node 20+, npm 10+. CI runs on Node 20.x and 22.x.


Project layout

agentbridge-protocol/
├── packages/
│   ├── core/             # 📦 schemas, types, validation, audit
│   ├── sdk/              # 📦 defineAgentAction, manifest builder
│   ├── scanner/          # 📦 readiness scoring + structured checks
│   ├── openapi/          # 📦 OpenAPI 3.x → AgentBridge manifest converter
│   └── cli/              # 📦 @marmarlabs/agentbridge-cli — scan, validate, init, generate
├── apps/
│   ├── demo-app/         # 🛒 Next.js order-management demo (port 3000)
│   ├── studio/           # 🎛 Next.js dashboard (port 3001)
│   └── mcp-server/       # 🔌 stdio MCP server: tools + resources + prompts
├── spec/
│   ├── agentbridge-manifest.schema.json   # JSON Schema for the manifest
│   ├── agentbridge-manifest.v0.1.md       # human-readable spec
│   └── examples/                          # 3 example manifests
├── examples/             # nextjs-basic · openapi-store · mcp-client-config · codex-config · codex-plugin
├── docs/                 # quickstart, mcp-client-setup, codex-setup, openapi-import, roadmap
├── data/                 # 📁 local audit/confirmations/idempotency (gitignored)
├── .github/workflows/    # CI
├── AGENTS.md             # model-neutral working notes for AI coding agents
├── CLAUDE.md             # deeper Claude-Code-specific working notes
├── CONTRIBUTING.md / SECURITY.md / CODE_OF_CONDUCT.md / CHANGELOG.md
├── README.md
└── LICENSE               # Apache 2.0

Packages and apps

📦 packages/core

The shared contract. Everything depends on this.

import {
  AgentBridgeManifestSchema,
  validateManifest,
  isRiskyAction,
  summarizeAction,
  createAuditEvent,
  appendAuditEvent,
} from "@marmarlabs/agentbridge-core";

const result = validateManifest(rawJson);
if (result.ok) {
  for (const action of result.manifest.actions) {
    if (isRiskyAction(action)) {
      console.log("Needs confirmation:", action.name);
    }
  }
}

Key exports:

  • Zod schemas for the manifest, actions, resources, permissions, audit events
  • validateManifest(json){ ok, manifest } or { ok: false, errors[] }
  • isRiskyAction(action) — boolean confirmation gate
  • summarizeAction(action, input) — fills humanReadableSummaryTemplate with {{key}} placeholders
  • createAuditEvent, appendAuditEvent, readAuditEvents — JSON-file audit log with PII redaction (strips authorization, cookie, password, token, secret recursively)

📦 packages/sdk

The author's interface. Define actions ergonomically with Zod, get JSON Schema for free.

import { defineAgentAction, createAgentBridgeManifest, z } from "@marmarlabs/agentbridge-sdk";

const refundAction = defineAgentAction({
  name: "draft_refund_order",
  title: "Draft a refund",
  description: "Creates a refund draft. Not executed until confirmed via execute_refund_order.",
  method: "POST",
  endpoint: "/api/agentbridge/actions/draft_refund_order",
  risk: "medium",
  requiresConfirmation: true,
  inputSchema: z.object({
    orderId: z.string().min(1),
    reason: z.string().min(3),
    amount: z.number().positive(),
  }),
  outputSchema: z.object({
    draftId: z.string(),
    summary: z.string(),
  }),
  humanReadableSummaryTemplate:
    "Draft a refund of ${{amount}} on order {{orderId}} (reason: {{reason}})",
  examples: [
    {
      description: "Partial refund for a damaged item",
      input: { orderId: "ORD-1001", reason: "Damaged on arrival", amount: 24 },
    },
  ],
});

export const manifest = createAgentBridgeManifest({
  name: "Acme Order Manager",
  version: "1.0.0",
  baseUrl: "https://acme.com",
  contact: "platform@acme.com",
  actions: [refundAction /* ... */],
});

The SDK converts Zod → JSON Schema (via zod-to-json-schema) automatically, so you get one source of truth for both runtime validation and the published manifest.

📦 packages/scanner

Audit any URL for agent readiness. Returns a 0–100 score plus actionable recommendations.

import { scanUrl } from "@marmarlabs/agentbridge-scanner";

const report = await scanUrl("http://localhost:3000");
// {
//   score: 100,
//   manifestFound: true,
//   validManifest: true,
//   actionCount: 5,
//   riskyActionCount: 3,
//   missingConfirmationCount: 0,
//   issues: [],
//   recommendations: [],
// }

Scoring rubric:

Issue Deduction
No manifest at all → score 0
Manifest invalid against schema → score 10
No actions declared −30
Missing contact field −5
Per action: short/missing description −3
Per action: no examples −2
Per action: no humanReadableSummaryTemplate −2
Per action: no outputSchema −2
Per high-risk action without requiresConfirmation −15
Per medium-risk action without requiresConfirmation −7

Optionally runs a Playwright probe (probe: true) to fall back on visible buttons/forms when no manifest exists yet — useful for "what would an agent see if there were no manifest?" baselines.

🛒 apps/demo-app

A toy order-management Next.js app exposing 5 actions of escalating risk:

Action Risk Confirmation
list_orders low none
get_order low none
draft_refund_order medium required
add_internal_note medium required
execute_refund_order high required

The demo intentionally simulates destructive actions — execute_refund_order mutates an in-memory store and returns { simulated: true, simulatedTransactionId: "..." }. No real payment processor is touched anywhere in this codebase.

🎛 apps/studio

A developer dashboard at :3001 for inspecting and exercising any AgentBridge surface:

  • Scan — fetch + score + recommend
  • Manifest — pretty-printed JSON viewer
  • Actions — list with risk pills, click-through to detail
  • Action detail — auto-generated form from inputSchema, "Try it" button, confirmation modal for risky actions
  • Audit log — cross-source view (demo / studio / mcp)

🔌 apps/mcp-server

A Model Context Protocol server speaking stdio. Exposes 5 tools, 4 resources, and 4 prompts to AI agents (see MCP tools reference below). Enforces the confirmation gate, origin pinning, URL allowlist, confirmation tokens, and idempotency keys before any outbound call.

📦 packages/openapi

OpenAPI 3.x → AgentBridge manifest converter. Used by the CLI; can also be imported directly. Resolves $refs, infers risk from method, merges path/query/body params into the action's inputSchema. See docs/openapi-import.md for limits.

📦 packages/cli

The agentbridge command. See The CLI below.


The CLI

# From the repo root, no install needed:
npm run dev:cli -- scan http://localhost:3000

# After installing the published package, or via npx without install:
npx @marmarlabs/agentbridge-cli scan http://localhost:3000
Command What it does
agentbridge scan <url> Score the URL's AgentBridge readiness. Readable terminal output; --json for machine output.
agentbridge validate <file-or-url> Validate a manifest from disk or a URL against the schema. --json.
agentbridge init Scaffold an agentbridge.config.ts and a starter /.well-known/agentbridge.json. --force to overwrite, --format json for JSON config.
agentbridge generate openapi <src> Generate a draft manifest from an OpenAPI 3.x doc. --out PATH, --base-url URL, --json.
agentbridge mcp-config Print copy-pasteable MCP client configs for OpenAI Codex (CLI + config.toml), Claude Desktop, Cursor, and any other MCP-compatible client.
agentbridge version Print CLI version.

Example: take an existing OpenAPI document and turn it into a draft manifest in one shot:

npx @marmarlabs/agentbridge-cli generate openapi ./your-api.openapi.json \
  --base-url https://api.acme.com \
  --out ./public/.well-known/agentbridge.json

See docs/openapi-import.md for the full guide.


OpenAPI import

The CLI's generate openapi command and the @marmarlabs/agentbridge-openapi package turn an existing OpenAPI 3.x document into a draft AgentBridge manifest.

OpenAPI method Risk inferred requiresConfirmation
GET / HEAD low false
POST / PUT / PATCH medium true
DELETE high true

The generator walks every operation, uses operationId (snake-cased) as the action name, merges path/query params and request body into the action's inputSchema.properties, and resolves $refs against components.schemas.

Review every action after generation — heuristics aren't a substitute for intent. See the example and docs/openapi-import.md.


Manifest spec

The manifest format is a stable, versioned spec — not just whatever @marmarlabs/agentbridge-core happens to validate.

Artifact Path
Human-readable spec spec/agentbridge-manifest.v0.1.md
JSON Schema (Draft 2020-12) spec/agentbridge-manifest.schema.json
Examples spec/examples/ — minimal, e-commerce, support tickets

The example manifests are validated by tests, so they stay in sync with the schema as it evolves. Add a new example by dropping a JSON file into spec/examples/ and the test in packages/core/src/tests/spec-examples.test.ts will pick it up automatically.


Demo walkthrough

  1. Boot it up.

    npm run dev
  2. Browse as a human. Visit http://localhost:3000/orders. Click into an order. Notice this is a normal-looking app.

  3. Inspect the manifest. Visit http://localhost:3000/.well-known/agentbridge.json (or the pretty viewer at /manifest). The same five operations a human can perform are declared as structured actions an agent can call.

  4. Switch to Studio. Visit http://localhost:3001. Hit Scan. You should see a perfect or near-perfect score, with all 5 actions and their risk levels.

  5. Run a low-risk action. Open list_orders from the Actions list. The form has a single optional status enum. Submit — runs immediately, returns the order list.

  6. Run a risky action. Open add_internal_note. Fill in orderId: ORD-1001 and a note. Click Review & confirm. The modal blocks until you type CONFIRM. Then it runs. Refresh the order detail page in the demo — the note is there.

  7. See the audit trail. Visit /audit in either app. Both invocations appear, with the source (studio here), the input, and timestamps.

  8. Try refusing. Try to invoke execute_refund_order from the MCP server without confirmationApproved:

    echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}
    {"jsonrpc":"2.0","method":"notifications/initialized"}
    {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"call_action","arguments":{"url":"http://localhost:3000","actionName":"execute_refund_order","input":{"draftId":"x","confirmationText":"CONFIRM"}}}}' \
      | npm run dev:mcp 2>/dev/null

    You'll get back { "status": "confirmationRequired", "summary": "EXECUTE refund draft x (irreversible in real life)", ... } — the action endpoint is not called.


Wire it to an MCP client

The AgentBridge MCP server speaks stdio. Same launcher (npx -y @marmarlabs/agentbridge-mcp-server) works in every MCP-compatible client below — only the surrounding config syntax differs. For everything beyond the snippets below see docs/mcp-client-setup.md and (for Codex specifically) docs/codex-setup.md.

Works with MCP clients

  • OpenAI Codex — CLI (codex mcp add) or ~/.codex/config.toml. See docs/codex-setup.md.
  • Claude Desktop — JSON config under ~/Library/Application Support/Claude/.
  • Cursor — Settings → MCP, same JSON shape as Claude Desktop.
  • Custom or other MCP clients — anything that can launch a stdio MCP server runs the same npx -y @marmarlabs/agentbridge-mcp-server entry.

npx @marmarlabs/agentbridge-cli mcp-config prints copy-pasteable snippets for all of the above.

OpenAI Codex (one-liner)

codex mcp add agentbridge -- npx -y @marmarlabs/agentbridge-mcp-server

Verify with /mcp inside Codex. Walkthrough, project-scoped config, and troubleshooting are in docs/codex-setup.md.

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "agentbridge": {
      "command": "npx",
      "args": ["-y", "@marmarlabs/agentbridge-mcp-server"]
    }
  }
}

Restart Claude Desktop. You should see agentbridge show up in the tools panel with 5 tools available.

Cursor

Settings → MCP → Add server. Same command/args shape as Claude Desktop. Or paste:

{
  "mcpServers": {
    "agentbridge": {
      "command": "npx",
      "args": ["-y", "@marmarlabs/agentbridge-mcp-server"]
    }
  }
}

Conversation example

The dialogue below uses Claude Desktop, but the same flow works with Codex, Cursor, or any other MCP-compatible client — only the surrounding chrome differs.

You: What can the app at http://localhost:3000 do?

Agent: (uses discover_manifest) It's a Demo Order Manager v0.1.0 with 5 actions: list_orders (low risk), get_order (low), draft_refund_order (medium, needs confirmation), execute_refund_order (high, needs confirmation), and add_internal_note (medium, needs confirmation).

You: Refund order ORD-1001 for $24 because the customer reported damage.

Agent: (uses call_action for draft_refund_order) I've drafted the refund. Draft id draft_xxx. To execute it, I need explicit approval — should I proceed?

You: Yes, go ahead.

Agent: (uses call_action for execute_refund_order with confirmationApproved: true) Done. Simulated transaction sim_tx_yyy. Order ORD-1001 is now in refunded status.


Manifest schema reference

A complete example manifest:

{
  "name": "Demo Order Manager",
  "description": "A fake order management app exposing structured AgentBridge actions for AI agents.",
  "version": "0.1.0",
  "baseUrl": "http://localhost:3000",
  "contact": "demo@agentbridge.local",
  "auth": { "type": "none", "description": "Demo only — no auth." },
  "resources": [
    {
      "name": "orders",
      "description": "Customer orders with items, status, notes, and refund history.",
      "url": "/orders"
    }
  ],
  "actions": [
    {
      "name": "execute_refund_order",
      "title": "Execute a drafted refund",
      "description": "Executes a previously drafted refund. SIMULATED.",
      "method": "POST",
      "endpoint": "/api/agentbridge/actions/execute_refund_order",
      "risk": "high",
      "requiresConfirmation": true,
      "inputSchema": {
        "type": "object",
        "required": ["draftId", "confirmationText"],
        "properties": {
          "draftId": { "type": "string", "minLength": 1 },
          "confirmationText": { "type": "string", "minLength": 1 }
        }
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "simulated": { "const": true },
          "simulatedTransactionId": { "type": "string" }
        }
      },
      "permissions": [],
      "examples": [
        {
          "description": "Execute the refund draft after confirmation",
          "input": { "draftId": "draft_xxx", "confirmationText": "CONFIRM" }
        }
      ],
      "humanReadableSummaryTemplate": "EXECUTE refund draft {{draftId}} (irreversible in real life)"
    }
  ],
  "generatedAt": "2026-04-27T02:05:06.203Z"
}

Top-level fields: name, description, version, baseUrl, resources[], actions[], auth, contact, generatedAt.

Action fields: name, title, description, inputSchema (JSON Schema), outputSchema (JSON Schema), method, endpoint, risk (low | medium | high), requiresConfirmation, permissions[], examples[], humanReadableSummaryTemplate.


MCP tools reference

The MCP server exposes 5 tools, 4 resources, and 4 prompts. All accept a target url (the origin of an AgentBridge-enabled app).

Tools

Tool Purpose
discover_manifest Fetch + summarize a manifest. Use first to understand what an app supports.
scan_agent_readiness Run the full scanner; returns 0–100 score, structured checks[], grouped recommendations.
list_actions Compact list of actions with name, title, risk, confirmation flag, permissions.
call_action Invoke an action. Risky actions return confirmationRequired plus a confirmationToken; the second call must include confirmationApproved: true AND the same token. Optional idempotencyKey replays prior results.
get_audit_log Read recent audit events; filter by url.

Resources

URIs the agent can fetch directly:

URI What it returns
agentbridge://manifest?url=<encoded> The validated manifest at the given URL.
agentbridge://readiness?url=<encoded> Full scanner report (score, checks, recommendations).
agentbridge://audit-log?url=<encoded>&limit=N Recent audit events, optionally filtered.
agentbridge://spec/manifest-v0.1 Bundled human-readable manifest spec (markdown).

Prompts

Reusable agent prompts:

Prompt Use case
scan_app_for_agent_readiness Audit + write up findings for an AgentBridge surface.
generate_manifest_from_api Turn an OpenAPI doc or API description into a draft manifest.
explain_action_confirmation Translate an action for a human reviewer about to approve it.
review_manifest_for_security Safety-focused review of an existing manifest.

Example: full call_action transaction (with token + idempotency)

// First call — no confirmation, no token yet
{
  "tool": "call_action",
  "arguments": {
    "url": "http://localhost:3000",
    "actionName": "execute_refund_order",
    "input": { "draftId": "draft_xxx", "confirmationText": "CONFIRM" }
  }
}

// Response: gated, no upstream call made; token returned
{
  "status": "confirmationRequired",
  "summary": "EXECUTE refund draft draft_xxx (irreversible in real life)",
  "action": { "name": "execute_refund_order", "risk": "high", "requiresConfirmation": true },
  "confirmationToken": "f1c2…",
  "confirmationExpiresInSeconds": 300,
  "hint": "Re-call this tool with confirmationApproved: true AND the same confirmationToken after a human reviews the summary."
}

// Second call — explicit approval + token (single-use, input-bound)
{
  "tool": "call_action",
  "arguments": {
    "url": "http://localhost:3000",
    "actionName": "execute_refund_order",
    "input": { "draftId": "draft_xxx", "confirmationText": "CONFIRM" },
    "confirmationApproved": true,
    "confirmationToken": "f1c2…",
    "idempotencyKey": "ord-1001-refund-2026-04-27"
  }
}

// Response: action ran, simulated
{
  "status": "ok",
  "result": {
    "simulated": true,
    "simulatedTransactionId": "sim_tx_1777255529536",
    "executedAt": "2026-04-27T02:05:29.536Z"
  },
  "idempotent": { "key": "ord-1001-refund-2026-04-27", "replayed": false }
}

A repeat call with the same idempotencyKey and same input returns the cached result without re-invoking the upstream endpoint. A repeat with the same key and different input is rejected as a conflict.


Security model

This is an MVP — but security is not an afterthought, because the entire value of the project is letting agents act safely.

Enforced today

Control Where it lives What it does
URL allowlist mcp-server/src/safety.ts, scanner/src/scanner.ts Loopback only by default. Production-recommended: set AGENTBRIDGE_ALLOWED_TARGET_ORIGINS to a comma-separated list of exact origins. Broad escape hatch: AGENTBRIDGE_ALLOW_REMOTE=true (with a one-time stderr warning).
Configurable bounds mcp-server/src/config.ts AGENTBRIDGE_ACTION_TIMEOUT_MS, AGENTBRIDGE_MAX_RESPONSE_BYTES, AGENTBRIDGE_CONFIRMATION_TTL_SECONDS — out-of-range values are clamped with a stderr warning. See docs/security-configuration.md.
Stdout hygiene apps/mcp-server/src/tests/stdio-hygiene.test.ts Stdout carries only JSON-RPC. Warnings/diagnostics go to stderr. Verified by an MCP subprocess test.
Origin pinning mcp-server/src/safety.ts:assertSameOrigin Action endpoints must share origin with manifest.baseUrl. A poisoned manifest cannot redirect calls elsewhere.
Confirmation gate mcp-server/src/tools.ts:callAction, studio/api/call/route.ts Risky actions return confirmationRequired unless caller passes confirmationApproved: true.
Confirmation tokens mcp-server/src/confirmations.ts Tokens are bound to (url, actionName, hash(input)), single-use, expire in 5 minutes. Reuse with different input is rejected.
Idempotency keys mcp-server/src/idempotency.ts Optional per-call key replays prior result; same key + different input is a conflict.
Outbound timeout + size cap mcp-server/src/tools.ts 10s timeout on action calls; 1MB response body cap.
Schema validation mcp-server/src/tools.ts (Ajv), SDK (Zod) Inputs validated against the action's JSON Schema before any upstream call.
Audit redaction core/src/audit.ts:redact Strips authorization, cookie, password, token, secret, api_key recursively before persisting.
Simulated destructive actions demo-app/lib/orders.ts No real payment processor is wired anywhere. All "destructive" demo actions return { simulated: true, ... }.
Bounded audit log core/src/audit.ts Capped at 500 most recent events; atomic write (tmp + rename) to prevent corruption.

Not yet implemented (search for // PROD: in the source)

  • Real OAuth/bearer auth on the MCP server and on action endpoints
  • Per-action RBAC and tenant isolation
  • Signed manifests so agents can verify the publisher
  • Policy engine integration (OPA / Cedar) for action-level allow/deny
  • Rate limiting and cost accounting
  • Distributed audit storage (the MVP uses a local JSON file)

Threat model summary

Threat Mitigation today Long-term mitigation
Agent misclicks a destructive action Confirmation gate + risk metadata Same + signed policy contracts
Poisoned manifest redirects calls to attacker host Origin pinning to baseUrl Same + signed manifests + cert pinning
SSRF via attacker-supplied URL Loopback-only by default Same + outbound-host allowlist per agent
Audit log leaks secrets Recursive redaction of common keys Same + structured logging w/ tagged sensitive fields
Agent DOS's the upstream app (none today) Per-tool rate limiting + cost accounting

Testing

npm test          # all suites
npm run typecheck # per-package tsc --noEmit
npm run build     # tsup build for publishable packages
npm run pack:dry-run # validate published-tarball contents

Coverage:

  • packages/core — manifest validation, risk classification, summary template rendering, audit log persistence + redaction, spec example validation.
  • packages/scanner — scoring, structured checks, URL allowlist enforcement, cross-origin baseUrl, destructive-method detection.
  • packages/openapi — OpenAPI parsing, risk inference, name normalization, $ref resolution, full fixture conversion.
  • packages/cli — arg parsing, exit codes, validate/init/generate behaviour, file system side effects.
  • apps/mcp-server — confirmation gate, token issuance + binding + single-use, idempotency replay + conflict, origin pinning, JSON Schema validation, low-risk pass-through.

CI runs npm install, typecheck, all tests, and Next.js builds on Node 20.x and 22.x — see .github/workflows/ci.yml.


Documentation

Doc What it covers
docs/quickstart.md Five-minute walkthrough from clone to running stack.
docs/codex-setup.md Hooking AgentBridge MCP into OpenAI Codex (CLI + config.toml + project-scoped).
docs/mcp-client-setup.md Hooking AgentBridge MCP into Codex, Claude Desktop, Cursor, custom clients.
docs/openapi-import.md Generating manifests from OpenAPI 3.x.
docs/v1-readiness.md The v1.0.0 readiness checklist — what "production-ready" means and where we stand.
docs/production-readiness.md Practical "what is AgentBridge safe for today?" assessment plus a pre-flight checklist.
docs/threat-model.md Full threat catalogue with current mitigations and v1.0 targets.
docs/security-configuration.md Every env var the MCP server honors, with defaults, ranges, and recipes.
docs/trusted-publishing.md npm Trusted Publishing plan and the draft release-publish.yml workflow.
docs/designs/http-mcp-transport-auth.md v0.4.0 HTTP MCP transport + auth design.
docs/adr/0001-http-mcp-transport.md ADR for adding the opt-in HTTP MCP transport.
docs/designs/signed-manifests.md v0.5.0 signed-manifest design (in progress).
docs/adr/0002-signed-manifests.md ADR for adding optional signed AgentBridge manifests.
docs/roadmap.md What's shipped, what's next.
spec/agentbridge-manifest.v0.1.md The manifest specification.
AGENTS.md Short, model-neutral working notes for any AI coding agent (Codex, Claude, Cursor, custom).
CLAUDE.md Deeper Claude-Code-specific working notes for this repo.
CONTRIBUTING.md, SECURITY.md, CODE_OF_CONDUCT.md Community + reporting.
CHANGELOG.md Per-release notes.

Roadmap

Near-term, in rough priority order:

  • Signed manifests (v0.5.0, in design). A published manifest carries an inline publisher signature (Ed25519 by default, RFC 8785 canonicalization) an agent can verify offline against the publisher's key set at /.well-known/agentbridge-keys.json. Optional in v0.5.0; mandatory at v1.0 after a documented migration. Design: docs/designs/signed-manifests.md. ADR: docs/adr/0002-signed-manifests.md. Tracking: #31.
  • Standardized risk taxonomy. Move from low | medium | high to a richer model: read, write-self, write-others, financial, irreversible. Lets agents reason about action consequences more precisely.
  • Policy primitives. First-class support for cost caps, rate limits, business-hours gating, and N-of-M approver workflows declared in the manifest.
  • HTTP MCP transport. Stdio works for desktop clients; hosted/centralized agents need an authenticated HTTP transport. Implemented as opt-in in v0.4.0 behind AGENTBRIDGE_TRANSPORT=http with bearer-token auth, exact-origin allowlist, and loopback-by-default bind. Design: docs/designs/http-mcp-transport-auth.md. Recipe: examples/http-client-config.
  • Cross-app workflows. Let an agent compose actions from multiple AgentBridge surfaces with consistent confirmation semantics across them.
  • Browser fallback + auto-generation. When a site doesn't publish a manifest, run a Playwright probe and generate a starter manifest from visible buttons and forms — give app teams a one-click on-ramp.
  • Manifest registry. Optional public index of manifests so agents can discover what surfaces exist for a given task ("find me an app that can refund a Stripe charge").

Contributing

This is a prototype, and the most valuable contributions are about the interface contract between agents and apps — not the demo Next.js plumbing.

High-leverage places to start:

  1. packages/core/src/schemas.ts — the manifest schema is the entire contract. Field additions, deprecations, and tightening live here.
  2. packages/scanner/src/score.ts — the readiness rubric. What does a "good" agent-ready app look like? Should missing examples cost more than missing output schemas?
  3. apps/mcp-server/src/tools.ts — the enforcement surface. The confirmation gate and origin pinning are critical paths.

Please open an issue before starting on any PR larger than a small fix, so we can align on direction.


License

Apache License 2.0 — see LICENSE.


Built as an MVP exploration of the agent-native interface layer for the web.

If this resonates, open an issue and let's talk.

About

An AI-native action layer that helps apps expose structured, permissioned actions for agents through manifests, MCP tools, confirmations, and audit logs.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors