Skip to content

Commit 77c458b

Browse files
evantahlerclaude
andauthored
docs: add tool metadata documentation to webhook payload guides (#873)
* docs: add tool metadata documentation to webhook payload guides Updated both "Build Your Own" pages (contextual-access and logic-extensions) to document the new optional metadata field in webhook payloads (PR #517). Added comprehensive Tool Metadata section including structure table, examples for pre/post/access hooks, and use cases. Updated external GitHub URLs to canonical repositories (oapi-codegen and openapi-ts). Fixes #872. * style: remove spaces around em dashes per Vale Google style Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 90614de commit 77c458b

File tree

2 files changed

+198
-12
lines changed
  • app/en/guides

2 files changed

+198
-12
lines changed

app/en/guides/contextual-access/build-your-own/page.mdx

Lines changed: 99 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ Use the OpenAPI spec with standard code generators to scaffold your server:
2121

2222
| Language | Generator |
2323
| --- | --- |
24-
| **Go** | [oapi-codegen](https://github.com/deepmap/oapi-codegen), [ogen](https://github.com/ogen-go/ogen) |
24+
| **Go** | [oapi-codegen](https://github.com/oapi-codegen/oapi-codegen), [ogen](https://github.com/ogen-go/ogen) |
2525
| **Python** | [openapi-generator](https://openapi-generator.tech/), [datamodel-code-generator](https://github.com/koxudaxi/datamodel-code-generator) |
26-
| **TypeScript** | [openapi-typescript](https://github.com/drwpow/openapi-typescript), [openapi-generator](https://openapi-generator.tech/) |
26+
| **TypeScript** | [openapi-typescript](https://github.com/openapi-ts/openapi-typescript), [openapi-generator](https://openapi-generator.tech/) |
2727

2828
**Example (Go with oapi-codegen):**
2929

@@ -55,7 +55,7 @@ You do not need to implement all endpoints. Only implement the ones you configur
5555
| Field | Type | Description |
5656
| --- | --- | --- |
5757
| `execution_id` | string | Correlates request/response across hooks |
58-
| `tool` | object | `name`, `toolkit`, `version` |
58+
| `tool` | object | `name`, `toolkit`, `version`, and optional `metadata` (see [Tool Metadata](#tool-metadata)) |
5959
| `inputs` | object | Tool inputs (name → value) |
6060
| `context` | object | `authorization` (OAuth per provider), `secrets` (key names only), `metadata`, `user_id` |
6161

@@ -76,7 +76,7 @@ You do not need to implement all endpoints. Only implement the ones you configur
7676
| Field | Type | Description |
7777
| --- | --- | --- |
7878
| `execution_id` | string | Correlates with pre-execution hook |
79-
| `tool` | object | `name`, `toolkit`, `version` |
79+
| `tool` | object | `name`, `toolkit`, `version`, and optional `metadata` (see [Tool Metadata](#tool-metadata)) |
8080
| `inputs` | object | Tool inputs |
8181
| `success` | boolean | Whether the tool call succeeded |
8282
| `output` | any | The execution output (any JSON type) |
@@ -101,7 +101,7 @@ You do not need to implement all endpoints. Only implement the ones you configur
101101
| Field | Type | Description |
102102
| --- | --- | --- |
103103
| `user_id` | string | User to check |
104-
| `toolkits` | object | Map of toolkit name → toolkit info (tools, versions, requirements) |
104+
| `toolkits` | object | Map of toolkit name → toolkit info. Each toolkit contains a `tools` map of tool name → version info arrays. Each version info includes `version`, `requirements`, and optional `metadata` (see [Tool Metadata](#tool-metadata)) |
105105

106106
### Response
107107

@@ -112,7 +112,100 @@ Return either an allow list or a deny list (not both):
112112
| `only` | object | If present, **only** these tools are allowed (deny list ignored) |
113113
| `deny` | object | Tools listed here are denied (ignored if `only` is present) |
114114

115-
If you return neither field, the Arcade treats it as "no change" — all tools remain allowed at this hook.
115+
If you return neither field, the Arcade treats it as "no change"—all tools remain allowed at this hook.
116+
117+
## Tool Metadata
118+
119+
Tools can include an optional `metadata` field with classification, behavioral, and custom information. Webhook servers can use this metadata to make more granular access and filtering decisions.
120+
121+
All metadata fields are optional and omitted from the JSON when empty, so existing webhook servers continue to work without changes.
122+
123+
For the full list of valid `service_domains` and `operations` values, see [Add Tool Metadata](/guides/create-tools/tool-basics/add-tool-metadata).
124+
125+
### Structure
126+
127+
| Field | Type | Description |
128+
| --- | --- | --- |
129+
| `metadata` | object \| absent | Container for tool metadata. Omitted when the tool has no metadata set. |
130+
| `metadata.classification` | object | Classification information. |
131+
| `metadata.classification.service_domains` | string[] | Service domains this tool interfaces with (for example, `"email"`, `"calendar"`, `"crm"`). |
132+
| `metadata.behavior` | object | Behavioral characteristics. |
133+
| `metadata.behavior.operations` | string[] | Operations this tool performs (for example, `"read"`, `"create"`, `"update"`, `"delete"`, `"opaque"`). |
134+
| `metadata.behavior.read_only` | boolean | Whether the tool only reads data. |
135+
| `metadata.behavior.destructive` | boolean | Whether the tool can delete or irreversibly modify data. |
136+
| `metadata.behavior.idempotent` | boolean | Whether repeated calls with the same inputs produce the same result. |
137+
| `metadata.behavior.open_world` | boolean | Whether the tool can affect state outside its defined outputs. |
138+
| `metadata.extras` | object | Arbitrary additional metadata set by the toolkit author (for example, `{"IdP": "entra_id"}`). |
139+
140+
### Example: pre/post hook request with metadata
141+
142+
```json
143+
{
144+
"execution_id": "exec_abc123",
145+
"tool": {
146+
"name": "ListEmails",
147+
"toolkit": "Gmail",
148+
"version": "1.0.0",
149+
"metadata": {
150+
"classification": {
151+
"service_domains": ["email"]
152+
},
153+
"behavior": {
154+
"operations": ["read"],
155+
"read_only": true,
156+
"destructive": false,
157+
"idempotent": true,
158+
"open_world": false
159+
},
160+
"extras": {
161+
"IdP": "entra_id"
162+
}
163+
}
164+
},
165+
"inputs": { "query": "from:boss@company.com" },
166+
"context": { "user_id": "user_123" }
167+
}
168+
```
169+
170+
### Example: access hook request with metadata
171+
172+
```json
173+
{
174+
"user_id": "user_123",
175+
"toolkits": {
176+
"Gmail": {
177+
"tools": {
178+
"ListEmails": [
179+
{
180+
"version": "1.0.0",
181+
"metadata": {
182+
"classification": {
183+
"service_domains": ["email"]
184+
},
185+
"behavior": {
186+
"operations": ["read"],
187+
"read_only": true
188+
}
189+
},
190+
"requirements": {
191+
"authorization": [{ "provider_type": "oauth2" }]
192+
}
193+
}
194+
]
195+
}
196+
}
197+
}
198+
}
199+
```
200+
201+
### Use cases
202+
203+
Webhook servers can use tool metadata to make more granular decisions:
204+
205+
- **Block destructive operations**—Deny tools where `metadata.behavior.destructive` is `true` for certain users
206+
- **Restrict by service domain**—Only allow tools in the `"email"` domain for a particular project
207+
- **Audit read vs. write**—Log or rate-limit tools based on their `operations` array
208+
- **Route by IdP**—Use `metadata.extras.IdP` to apply provider-specific policies
116209

117210
## Response codes (pre and post)
118211

app/en/guides/logic-extensions/build-your-own/page.mdx

Lines changed: 99 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ Use the OpenAPI spec with standard code generators to scaffold your server:
2121

2222
| Language | Generator |
2323
| --- | --- |
24-
| **Go** | [oapi-codegen](https://github.com/deepmap/oapi-codegen), [ogen](https://github.com/ogen-go/ogen) |
24+
| **Go** | [oapi-codegen](https://github.com/oapi-codegen/oapi-codegen), [ogen](https://github.com/ogen-go/ogen) |
2525
| **Python** | [openapi-generator](https://openapi-generator.tech/), [datamodel-code-generator](https://github.com/koxudaxi/datamodel-code-generator) |
26-
| **TypeScript** | [openapi-typescript](https://github.com/drwpow/openapi-typescript), [openapi-generator](https://openapi-generator.tech/) |
26+
| **TypeScript** | [openapi-typescript](https://github.com/openapi-ts/openapi-typescript), [openapi-generator](https://openapi-generator.tech/) |
2727

2828
**Example (Go with oapi-codegen):**
2929

@@ -55,7 +55,7 @@ You do not need to implement all endpoints. Only implement the ones you configur
5555
| Field | Type | Description |
5656
| --- | --- | --- |
5757
| `execution_id` | string | Correlates request/response across hooks |
58-
| `tool` | object | `name`, `toolkit`, `version` |
58+
| `tool` | object | `name`, `toolkit`, `version`, and optional `metadata` (see [Tool Metadata](#tool-metadata)) |
5959
| `inputs` | object | Tool inputs (name → value) |
6060
| `context` | object | `authorization` (OAuth per provider), `secrets` (key names only), `metadata`, `user_id` |
6161

@@ -76,7 +76,7 @@ You do not need to implement all endpoints. Only implement the ones you configur
7676
| Field | Type | Description |
7777
| --- | --- | --- |
7878
| `execution_id` | string | Correlates with pre-execution hook |
79-
| `tool` | object | `name`, `toolkit`, `version` |
79+
| `tool` | object | `name`, `toolkit`, `version`, and optional `metadata` (see [Tool Metadata](#tool-metadata)) |
8080
| `inputs` | object | Tool inputs |
8181
| `success` | boolean | Whether the tool call succeeded |
8282
| `output` | any | The execution output (any JSON type) |
@@ -101,7 +101,7 @@ You do not need to implement all endpoints. Only implement the ones you configur
101101
| Field | Type | Description |
102102
| --- | --- | --- |
103103
| `user_id` | string | User to check |
104-
| `toolkits` | object | Map of toolkit name → toolkit info (tools, versions, requirements) |
104+
| `toolkits` | object | Map of toolkit name → toolkit info. Each toolkit contains a `tools` map of tool name → version info arrays. Each version info includes `version`, `requirements`, and optional `metadata` (see [Tool Metadata](#tool-metadata)) |
105105

106106
### Response
107107

@@ -112,7 +112,100 @@ Return either an allow list or a deny list (not both):
112112
| `only` | object | If present, **only** these tools are allowed (deny list ignored) |
113113
| `deny` | object | Tools listed here are denied (ignored if `only` is present) |
114114

115-
If you return neither field, the Arcade treats it as "no change" — all tools remain allowed at this hook.
115+
If you return neither field, the Arcade treats it as "no change"—all tools remain allowed at this hook.
116+
117+
## Tool Metadata
118+
119+
Tools can include an optional `metadata` field with classification, behavioral, and custom information. Webhook servers can use this metadata to make more granular access and filtering decisions.
120+
121+
All metadata fields are optional and omitted from the JSON when empty, so existing webhook servers continue to work without changes.
122+
123+
For the full list of valid `service_domains` and `operations` values, see [Add Tool Metadata](/guides/create-tools/tool-basics/add-tool-metadata).
124+
125+
### Structure
126+
127+
| Field | Type | Description |
128+
| --- | --- | --- |
129+
| `metadata` | object \| absent | Container for tool metadata. Omitted when the tool has no metadata set. |
130+
| `metadata.classification` | object | Classification information. |
131+
| `metadata.classification.service_domains` | string[] | Service domains this tool interfaces with (for example, `"email"`, `"calendar"`, `"crm"`). |
132+
| `metadata.behavior` | object | Behavioral characteristics. |
133+
| `metadata.behavior.operations` | string[] | Operations this tool performs (for example, `"read"`, `"create"`, `"update"`, `"delete"`, `"opaque"`). |
134+
| `metadata.behavior.read_only` | boolean | Whether the tool only reads data. |
135+
| `metadata.behavior.destructive` | boolean | Whether the tool can delete or irreversibly modify data. |
136+
| `metadata.behavior.idempotent` | boolean | Whether repeated calls with the same inputs produce the same result. |
137+
| `metadata.behavior.open_world` | boolean | Whether the tool can affect state outside its defined outputs. |
138+
| `metadata.extras` | object | Arbitrary additional metadata set by the toolkit author (for example, `{"IdP": "entra_id"}`). |
139+
140+
### Example: pre/post hook request with metadata
141+
142+
```json
143+
{
144+
"execution_id": "exec_abc123",
145+
"tool": {
146+
"name": "ListEmails",
147+
"toolkit": "Gmail",
148+
"version": "1.0.0",
149+
"metadata": {
150+
"classification": {
151+
"service_domains": ["email"]
152+
},
153+
"behavior": {
154+
"operations": ["read"],
155+
"read_only": true,
156+
"destructive": false,
157+
"idempotent": true,
158+
"open_world": false
159+
},
160+
"extras": {
161+
"IdP": "entra_id"
162+
}
163+
}
164+
},
165+
"inputs": { "query": "from:boss@company.com" },
166+
"context": { "user_id": "user_123" }
167+
}
168+
```
169+
170+
### Example: access hook request with metadata
171+
172+
```json
173+
{
174+
"user_id": "user_123",
175+
"toolkits": {
176+
"Gmail": {
177+
"tools": {
178+
"ListEmails": [
179+
{
180+
"version": "1.0.0",
181+
"metadata": {
182+
"classification": {
183+
"service_domains": ["email"]
184+
},
185+
"behavior": {
186+
"operations": ["read"],
187+
"read_only": true
188+
}
189+
},
190+
"requirements": {
191+
"authorization": [{ "provider_type": "oauth2" }]
192+
}
193+
}
194+
]
195+
}
196+
}
197+
}
198+
}
199+
```
200+
201+
### Use cases
202+
203+
Webhook servers can use tool metadata to make more granular decisions:
204+
205+
- **Block destructive operations**—Deny tools where `metadata.behavior.destructive` is `true` for certain users
206+
- **Restrict by service domain**—Only allow tools in the `"email"` domain for a particular project
207+
- **Audit read vs. write**—Log or rate-limit tools based on their `operations` array
208+
- **Route by IdP**—Use `metadata.extras.IdP` to apply provider-specific policies
116209

117210
## Response codes (pre and post)
118211

0 commit comments

Comments
 (0)