From 9fc608efe142e9266154ea821e71a5449d9f6aae Mon Sep 17 00:00:00 2001 From: chaodu-agent Date: Fri, 24 Jul 2026 21:01:32 -0400 Subject: [PATCH 1/3] docs: OAB MCP Facade operator guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Documents the #1448 feature: enablement (broker [mcp] / standalone), the two-tool surface, audit lines, client registration (incl. the kiro --agent config gotcha), trust model, and the pod-vs-fleet positioning relative to octobroker (ADR §4.1). --- docs/oab-mcp-facade.md | 97 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 docs/oab-mcp-facade.md diff --git a/docs/oab-mcp-facade.md b/docs/oab-mcp-facade.md new file mode 100644 index 000000000..9f57880ac --- /dev/null +++ b/docs/oab-mcp-facade.md @@ -0,0 +1,97 @@ +# OAB MCP Facade (`search_capabilities` / `execute_capability`) + +The OAB MCP Facade is a loopback Streamable HTTP MCP server that exposes +exactly **two agent-facing tools** — `search_capabilities` and +`execute_capability` — backed by every MCP server configured in `mcp.json`. +Any MCP-capable coding CLI on the host (Kiro CLI, Claude Code, Codex, …) +connects to `http://127.0.0.1:/mcp` and gets progressive discovery over +the whole provider catalog instead of a flat list of every provider tool. + +Design: [OAB MCP Adapter ADR](adr/oab-mcp-adapter.md) (§6). + +## Two ways to run it + +**In-process in the OAB broker** — presence of `[mcp]` in `config.toml` +starts the listener: + +```toml +[mcp] +listen = "127.0.0.1:8848" # loopback only; non-loopback refused at startup +``` + +**Standalone**: + +```sh +openab-agent mcp-facade --listen 127.0.0.1:8848 +``` + +Both read the same layered provider config: `~/.openab/agent/mcp.json` +(global) and `./.openab/agent/mcp.json` (project). No `[mcp]` section / no +configured servers → no listener / an empty capability catalog. Provider +connections stay in `mcp.json` — `[mcp]` carries listener settings only +(single source of truth, ADR Alternative E). + +## The two tools + +1. `search_capabilities` (optional `query`) — discover authorized provider + tools: name, description, input schema, provider, availability. Filtered + by each server's `tool_filter` **before** anything reaches the agent. +2. `execute_capability` (`name` + `arguments`) — execute an exact capability + returned by discovery. Arguments are validated against the capability's + JSON Schema before dispatch; timeouts, circuit breaking, and secret + redaction apply on the same path the native agent uses. + +An audit line is logged for every dispatch (tool name + args SHA-256 — never +plaintext arguments): + +``` +mcp.audit: mcp call_tool entry server="gmail" tool="search_threads" args_sha256=… +mcp.audit: mcp call_tool exit server="gmail" tool="search_threads" … outcome="ok" +``` + +## Client registration examples + +Kiro CLI (`~/.kiro/settings/mcp.json`, or the agent file — see gotcha): + +```json +{ "mcpServers": { "oab": { "url": "http://127.0.0.1:8848/mcp" } } } +``` + +> **Kiro CLI gotcha:** when kiro runs with `--agent ` (as OAB bot +> deployments do), the MCP server list comes from +> `~/.kiro/agents/.json` (`mcpServers` + `allowedTools`), **not** the +> global settings file. Register there and allowlist the server +> (e.g. `"@oab"`). + +Claude Code: + +```sh +claude mcp add --transport http oab http://127.0.0.1:8848/mcp +``` + +## Trust model + +Loopback-only, **no authentication layer** — the host/pod boundary is the +trust boundary. Any process on the host can invoke every authorized +capability while the facade runs. Do not enable it on hosts that colocate +untrusted processes. Least-privilege is enforced per provider with +`tool_filter` include/exclude lists in `mcp.json`; excluded tools are +invisible to discovery and rejected at execution. + +## Positioning vs octobroker (OBK) + +The facade is **pod-level**: one agent's own capability access, personal +OAuth credentials, host trust boundary. Fleet-level concerns — per-agent +identity/keys, default-deny policy across many agents, centrally minted +short-lived organization credentials, fail-closed audit — belong to +[octobroker](https://github.com/openabdev/octobroker). The two compose: the +facade can list an octobroker endpoint as one of its `mcp.json` downstreams, +and because the facade dispatches native `tools/call` requests, octobroker's +per-tool policy sees real tool names. See ADR §4.1. + +## Providers + +Any Streamable HTTP or stdio MCP server configured in `mcp.json` works, +including OAuth-protected hosted servers (login via +`openab-agent mcp login `). For Gmail on consumer accounts, use the +[native Gmail adapter](gmail-native.md). From e13b6c91529d5d7b9b15564af99a6b88c8afc7a8 Mon Sep 17 00:00:00 2001 From: chaodu-agent Date: Fri, 24 Jul 2026 21:05:56 -0400 Subject: [PATCH 2/3] docs: add mermaid architecture diagram to the facade guide --- docs/oab-mcp-facade.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/docs/oab-mcp-facade.md b/docs/oab-mcp-facade.md index 9f57880ac..811c1c12d 100644 --- a/docs/oab-mcp-facade.md +++ b/docs/oab-mcp-facade.md @@ -9,6 +9,43 @@ the whole provider catalog instead of a flat list of every provider tool. Design: [OAB MCP Adapter ADR](adr/oab-mcp-adapter.md) (§6). +## Architecture + +```mermaid +flowchart LR + subgraph host["Host / Pod (trust boundary)"] + cli["Coding CLI
(Kiro CLI / Claude Code / Codex / …)"] + + subgraph facade["OAB MCP Facade — loopback :8848/mcp"] + tools["search_capabilities
execute_capability"] + end + + subgraph runtime["Shared MCP runtime (openab-mcp)"] + policy["tool_filter (least-privilege)
JSON-Schema arg validation
timeouts · circuit breaker
secret redaction · audit log"] + end + + adapter["gmail-native adapter
loopback :8850/mcp"] + end + + gmail["gmail.googleapis.com
(GA REST)"] + obk["octobroker
(fleet policy / org credentials)"] + hosted["hosted MCP servers
(Notion, …, OAuth)"] + + cli -- "MCP (Streamable HTTP)" --> tools + tools --> policy + policy -- "native tools/call" --> adapter + policy -- "native tools/call" --> obk + policy -- "native tools/call" --> hosted + adapter -- "bearer (auth.json,
offline refresh)" --> gmail +``` + +The agent always sees exactly two tools; providers configured in `mcp.json` +are discovered through `search_capabilities` and invoked through +`execute_capability`. Because the runtime dispatches **native** `tools/call` +requests downstream, per-tool policy at any downstream (for example +octobroker's default-deny allowlists) sees real tool names — the meta-tool +envelope never blinds it. + ## Two ways to run it **In-process in the OAB broker** — presence of `[mcp]` in `config.toml` From 2b14fb6bb49eb13a8be94babe8cdf3126ed6dd0b Mon Sep 17 00:00:00 2001 From: chaodu-agent Date: Fri, 24 Jul 2026 21:34:50 -0400 Subject: [PATCH 3/3] docs: describe facade-only run mode (replaces removed openab-agent mcp-facade) --- docs/oab-mcp-facade.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/oab-mcp-facade.md b/docs/oab-mcp-facade.md index 811c1c12d..7fbee8409 100644 --- a/docs/oab-mcp-facade.md +++ b/docs/oab-mcp-facade.md @@ -56,10 +56,16 @@ starts the listener: listen = "127.0.0.1:8848" # loopback only; non-loopback refused at startup ``` -**Standalone**: +**Facade-only run mode** (no chat adapter anywhere — coding-CLI-only +hosts, dev loops, CI runners): an adapter-less config with `[mcp]` present +is a valid deployment; `openab run` serves just the facade listener: ```sh -openab-agent mcp-facade --listen 127.0.0.1:8848 +cat > facade-only.toml <<'TOML' +[mcp] +listen = "127.0.0.1:8848" +TOML +openab run -c facade-only.toml ``` Both read the same layered provider config: `~/.openab/agent/mcp.json`