Tool
A Tool is anything the agent calls.
Vendor SaaS (
gmail.send,stripe.refund), an internal MCP server (acme-fhir), a custom Python function (LangChain@tooldecorator) — all the same thing at this layer.Each Tool maps to capabilities (e.g.
external_messaging,pci_dss_scope). A single Policy rule about "external messaging" automatically covers every tool with that capability — so authoring scales to many tools at once.
At a glance
Section titled “At a glance”| Called by | the agent (during execution, via the gateway / MCP broker) |
| Maps to | abstract capabilities (external_messaging, pci_dss_scope, …) — the indirection that lets one Policy rule cover many tools |
| Governed by | per-call pipeline checks + capability-token scope (gateway and MCP) |
| If unknown | runtime tool discovery → default-deny + review queue |
What it is, concretely
Section titled “What it is, concretely”Every Tool has three things:
Example for gmail.send | |
|---|---|
| Name | gmail.send |
| Capabilities | external_messaging, persistence_write |
| Slot bindings | destination_param: to, content_param: body |
You don't write rules per-tool ("don't let gmail.send send to *.us after hours" — too granular). You write rules per-capability (external_messaging excludes *.us, *.cn) and the Tool catalog binds capabilities to concrete tools.
If the agent emits a tool the catalog hasn't seen, it lands in the runtime tool discovery queue: default-deny, surfaces in the dashboard, operator approves / refines / denies. No surprise tools.
The catalog ships with ~30 well-known SaaS pre-classified. Customers extend with per-tenant overrides for internal MCP servers, custom Python tools, etc.
What it's made of
Section titled “What it's made of”Tool├── name "gmail.send"├── capabilities [external_messaging, persistence_write]├── slot bindings destination_param: "to", content_param: "body"├── advertised by (which MCP server, if any) — null for built-in├── source builtin | tenant | discovered | mcp_advertised | sdk_declared└── status approved | pending | deniedThe capability abstraction is the bridge between Concerns (regulatory rules) and Tools (concrete invocations): a Concern targets a Capability (external_messaging); the Tool catalog binds Capabilities to specific tools (gmail.send). This means a rule like "GDPR requires external_messaging.destination excludes *.us, *.cn" automatically applies to every tool with external_messaging — no per-tool configuration.
Lifecycle
Section titled “Lifecycle”[catalog-time] Curated tool catalog ships with v1 (~30 well-known SaaS) Per-tenant tool overrides via tools.yaml (Pattern A/B/C) │ ▼ (or, agent emits an unknown tool name)[runtime discovery] Agent emits tool not in catalog → captured as discovered row, status=pending → call BLOCKED (default-deny) → review queue surfaces it │ ▼[review] Operator: approve / refine / deny (or auto-approve if from registered MCP server) │ ▼[approved] status=approved → agent's call passes Per-call enforcement still applies (Layer 4 pipeline) │ ▼ (per call thereafter)[per-call check] Pipeline steps: resource-access-checker (schema_acl) runaway-agent-stopper (loop_guard) capability scope (from keyring) PII / secrets / scan_output detectors │ ▼[forward] Upstream tool proxy connects to the registered MCP server Injects upstream credentials from vault Returns result to agent; emits auditEngines that operate on Tool
Section titled “Engines that operate on Tool”| Engine | What it does | Status |
|---|---|---|
| Tool catalog | Stores curated + per-tenant tool entries | partial (read API shipped; per-tenant write concept) |
| Approved tool-server list | Per-org MCP server allowlist | concept (approved-tool-server-list) |
| Upstream tool proxy | Forwards agent's MCP traffic to approved upstreams | concept (upstream-tool-proxy) |
| Runtime tool discovery | Default-deny + review queue for unknown tools | concept (runtime-tool-discovery.md) |
| Capability binder | Ties abstract capabilities to concrete tools | shipped (within authoring resolver) |
| Resource access checker | Per-call schema/asset ACL (schema_acl) | concept (resource-access-checker) |
| Runaway agent stopper | Per-session loop / pattern detection (loop_guard) | concept (runaway-agent-stopper) |
Quick-starts (curated catalog v1)
Section titled “Quick-starts (curated catalog v1)”~30 well-known tools ship pre-classified with capabilities and slot bindings. The customer doesn't classify these themselves.
| Tool | Capabilities | Owner |
|---|---|---|
gmail.send, slack.send_message | external_messaging, persistence_write | TapPass |
stripe.refund, stripe.create_charge | pci_dss_scope, financial_write | TapPass |
github.create_issue, github.create_pr_comment | external_messaging, code_collaboration | TapPass |
jira.create_issue | internal_messaging, ticketing_write | TapPass |
Bash, Read, Write | code_execution, file_io | TapPass |
WebFetch, WebSearch | network, external_data_in | TapPass |
| (~22 more in intent-to-policy.md §5 L3) |
Customers extend three ways without forking the core catalog:
- Pattern A — add a brand-new tool (per-tenant
tools.yaml) - Pattern B — extend a known tool (
extends: slack.send_message; capabilities: [-external_messaging, +internal_messaging]) - Pattern C — per-agent override (tighten classification for one agent)
Plus: register an internal MCP server with tappass mcp register — tools advertised by registered servers can auto-approve at discovery.
Surfaces
Section titled “Surfaces”| Persona | Surface | What you do |
|---|---|---|
| Operator | tappass mcp register / list / show / update / revoke | manage upstream MCP servers |
| Operator (visual) | Dashboard tool catalog | inspect curated + per-tenant tools |
| Operator (visual) | Dashboard runtime-tool review queue | approve/refine/deny discovered tools |
| Auditor | Dashboard audit views | every tool call surfaces with full args (PII-redacted) |
Related concepts
Section titled “Related concepts”- bound to → Capability (abstract → concrete)
- enforced via → Layer 4 (MCP) — pipeline steps + capability tokens
- discovered via → runtime tool discovery (default-deny)
- proxied via → Sync — keyring carries which tools are in scope this session
Authoritative docs
Section titled “Authoritative docs”| Topic | File |
|---|---|
| Vision | governed-agents-architecture.md §3 (interactions), §7 (catalog) |
| Catalog substrate | intent-to-policy.md §5, §8 |
| Discovery loop | runtime-tool-discovery.md |
| MCP proxy spec | upstream-tool-proxy |
| Per-org registry | approved-tool-server-list |
Status snapshot
Section titled “Status snapshot”| Aspect | Status |
|---|---|
| Curated catalog (~30 tools) | shipped on main |
| Per-tenant overrides (Patterns A/B/C) | partial (substrate shipped; write API concept) |
| Approved tool-server list | concept (Q3 2026) |
| Upstream tool proxy | concept (Q3 2026) |
| Runtime tool discovery (full loop) | partial (capture exists; promotion path concept) |
Common confusions
Section titled “Common confusions”- Tool ≠ Capability. Tools are concrete (
gmail.send); Capabilities are abstract (external_messaging). Concerns target Capabilities; the catalog binds Capabilities to Tools. This indirection is what lets a single rule apply to all tools in a class. - Both directions of MCP. TapPass governs outbound (agent → upstream MCP, via the proxy) and inbound (external system → agent's MCP server). Same catalog; same audit; same governance.
- Internal MCP servers are first-class. Customers running their own MCP servers (proprietary integrations, internal data systems) register via
tappass mcp register. Those servers' tools go through the same discovery + governance loop. Their credentials live in TapPass vault — not in the agent.