# Declared tools

> Discover what a site lets agents do from /.well-known/agentgate-tools.json, in MCP tool shape, and call a tool with a signed request.

A site can publish the actions agents may perform as **tools**. Each tool
has the shape of an MCP `Tool` plus three AgentGate fields that say where
to send it and how to sign.

## Find the manifest

```http
GET /.well-known/agentgate-tools.json HTTP/1.1
Host: shop.example
```

The site is picked by host, or by `?siteKey=`. The same document is at
`GET /v1/agent-tools/{siteKey}`.

```json
{
  "version": "agentgate-tools/1",
  "site": {"siteKey": "site_demo", "name": "AgentGate demo form"},
  "tools": [{
    "name": "send_message",
    "title": "Send a message",
    "description": "Send a message to the site's inbox. Retrying with the same id and message is safe; …",
    "inputSchema": {"type": "object", "properties": {"id": {"type": "string", "minLength": 8, "maxLength": 128},
                    "message": {"type": "string", "minLength": 1, "maxLength": 1000}},
                    "required": ["id", "message"], "additionalProperties": false},
    "outputSchema": {"type": "object", "properties": {"status": {"type": "string", "enum": ["accepted", "already_accepted"]}}},
    "annotations": {"readOnlyHint": false, "destructiveHint": false, "idempotentHint": true, "openWorldHint": false},
    "action": "agent_submit",
    "endpoint": {"method": "POST", "url": "https://shop.example/agent/submit", "contentType": "application/json"},
    "auth": [{"type": "web-bot-auth", "components": ["@authority", "@method", "@path", "content-digest"], "tag": "web-bot-auth"}]
  }],
  "receipts": {"header": "AgentGate-Receipt", "jwks": ".../.well-known/agentgate-keys.json", "verify": ".../v1/receipts/verify"},
  "handoff": {"poll": ".../v1/handoff/{id}"},
  "payment": {"price": "crawler-price", "offer": ["crawler-exact-price", "crawler-max-price"], "charged": "crawler-charged"}
}
```

| Field | Meaning |
| --- | --- |
| `name`, `title`, `description`, `inputSchema`, `outputSchema`, `annotations` | the MCP `Tool` fields |
| `action` | the site action the tool performs |
| `endpoint` | method, absolute URL and content type, from the site's exact route |
| `auth` | `web-bot-auth` with the signature components to cover, or `shared-key` |
| `receipts`, `handoff`, `payment` | where the agent-native headers and endpoints are |

## Call a tool

Send the arguments as the JSON body to `endpoint.url`, signed with at least
the `auth[0].components`:

```http
POST /agent/submit HTTP/1.1
Host: shop.example
Content-Type: application/json
Content-Digest: sha-256=:…:
Signature-Agent: sig1="https://your-agent.example"
Signature-Input: sig1=("@authority" "@method" "@path" "content-digest" "signature-agent";key="sig1");created=…;expires=…;keyid="…";nonce="…";tag="web-bot-auth"
Signature: sig1=:…:

{"id": "order-7f3a-0001", "message": "hello"}
```

## MCP and WebMCP

- **MCP.** Each tool has the shape of an MCP `Tool` (spec 2026-07-28), so an
  MCP client can list the tools as they are; the call is the signed HTTP
  request to `endpoint`.
- **WebMCP.** The W3C WebML Community Group draft (2026-09-17) registers
  tools from page script with
  `document.modelContext.registerTool({name, title, description, inputSchema, execute, annotations})`
  and has no JSON manifest yet. The fields map one to one, and `execute` is
  the signed call to `endpoint`.
- **Annotations.** `readOnlyHint` means the same in MCP and WebMCP. WebMCP's
  `consequentialHint` and `untrustedContentHint` are passed through when a
  site sets them.

## For site operators

Tools come from the `tools` list of the site's
[agent policy](/docs/agent-policy). A tool must name a site action with an
exact route; browser-only actions and prefix routes are refused.
