Context
PR #517 (feat: wire service_domains and operations through CATE webhook) added tool metadata to the webhook payloads sent to contextual access servers. The tool object in pre/post hook requests and the ToolVersionInfo in access hook requests now include an optional metadata field with classification, behavior, and extras.
The canonical OpenAPI schema and the generated Go types are already updated — the interactive API Reference page auto-updates from the schema. But the prose documentation on the Build Your Own page still describes the tool field as only having name, toolkit, version.
File to update
app/en/guides/contextual-access/build-your-own/page.mdx
Changes needed
1. Pre-Execution Hook request table — update tool row
Current:
| Field |
Type |
Description |
tool |
object |
name, toolkit, version |
New:
| Field |
Type |
Description |
tool |
object |
name, toolkit, version, and optional metadata (see Tool Metadata) |
2. Post-Execution Hook request table — same update to tool row
Same change as #1. The PostHookRequest.Tool field is the same ToolInfo type.
3. Access Hook request table — update toolkits description
Current:
| Field |
Type |
Description |
toolkits |
object |
Map of toolkit name → toolkit info (tools, versions, requirements) |
New:
| Field |
Type |
Description |
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) |
4. New "Tool Metadata" section
Add a new ## Tool Metadata section before the existing "Response codes" section. It should contain:
Structure table
| Field |
Type |
Description |
metadata |
object | absent |
Container for tool metadata. Omitted when the tool has no metadata set. |
metadata.classification |
object |
Classification information. |
metadata.classification.service_domains |
string[] |
Service domains this tool interfaces with (e.g., "email", "calendar", "crm"). |
metadata.behavior |
object |
Behavioral characteristics. |
metadata.behavior.operations |
string[] |
Operations this tool performs (e.g., "read", "create", "update", "delete", "opaque"). |
metadata.behavior.read_only |
boolean |
Whether the tool only reads data. |
metadata.behavior.destructive |
boolean |
Whether the tool can delete or irreversibly modify data. |
metadata.behavior.idempotent |
boolean |
Whether repeated calls with the same inputs produce the same result. |
metadata.behavior.open_world |
boolean |
Whether the tool can affect state outside its defined outputs. |
metadata.extras |
object |
Arbitrary additional metadata set by the toolkit author (e.g., {"IdP": "entra_id"}). |
Cross-link to Add Tool Metadata for valid service_domains and operations values.
Note backward compatibility: all fields are optional and omitted from the JSON when empty.
Example: pre/post hook request with metadata
{
"execution_id": "exec_abc123",
"tool": {
"name": "ListEmails",
"toolkit": "Gmail",
"version": "1.0.0",
"metadata": {
"classification": {
"service_domains": ["email"]
},
"behavior": {
"operations": ["read"],
"read_only": true,
"destructive": false,
"idempotent": true,
"open_world": false
},
"extras": {
"IdP": "entra_id"
}
}
},
"inputs": { "query": "from:boss@company.com" },
"context": { "user_id": "user_123" }
}
Example: access hook request with metadata
{
"user_id": "user_123",
"toolkits": {
"Gmail": {
"tools": {
"ListEmails": [
{
"version": "1.0.0",
"metadata": {
"classification": {
"service_domains": ["email"]
},
"behavior": {
"operations": ["read"],
"read_only": true
}
},
"requirements": {
"authorization": [{ "provider_type": "oauth2" }]
}
}
]
}
}
}
}
Use cases
Webhook servers can use tool metadata to make more granular decisions:
- Block destructive operations — Deny tools where
metadata.behavior.destructive is true for certain users
- Restrict by service domain — Only allow tools in the
"email" domain for a particular project
- Audit read vs. write — Log or rate-limit tools based on their
operations array
- Route by IdP — Use
metadata.extras.IdP to apply provider-specific policies
Reference files
- Canonical schema.yaml — the
ToolVersionInfoMetadata, ToolClassification, and ToolBehavior schemas
- monorepo PR #517 — the engine changes that wire metadata through
apps/engine/pkg/plugins/webhook/schema.gen.go in the monorepo — generated Go types showing exact JSON field names
Context
PR #517 (
feat: wire service_domains and operations through CATE webhook) added tool metadata to the webhook payloads sent to contextual access servers. Thetoolobject in pre/post hook requests and theToolVersionInfoin access hook requests now include an optionalmetadatafield with classification, behavior, and extras.The canonical OpenAPI schema and the generated Go types are already updated — the interactive API Reference page auto-updates from the schema. But the prose documentation on the Build Your Own page still describes the
toolfield as only havingname,toolkit,version.File to update
app/en/guides/contextual-access/build-your-own/page.mdxChanges needed
1. Pre-Execution Hook request table — update
toolrowCurrent:
toolname,toolkit,versionNew:
toolname,toolkit,version, and optionalmetadata(see Tool Metadata)2. Post-Execution Hook request table — same update to
toolrowSame change as #1. The
PostHookRequest.Toolfield is the sameToolInfotype.3. Access Hook request table — update
toolkitsdescriptionCurrent:
toolkitsNew:
toolkitstoolsmap of tool name → version info arrays. Each version info includesversion,requirements, and optionalmetadata(see Tool Metadata)4. New "Tool Metadata" section
Add a new
## Tool Metadatasection before the existing "Response codes" section. It should contain:Structure table
metadatametadata.classificationmetadata.classification.service_domains"email","calendar","crm").metadata.behaviormetadata.behavior.operations"read","create","update","delete","opaque").metadata.behavior.read_onlymetadata.behavior.destructivemetadata.behavior.idempotentmetadata.behavior.open_worldmetadata.extras{"IdP": "entra_id"}).Cross-link to Add Tool Metadata for valid
service_domainsandoperationsvalues.Note backward compatibility: all fields are optional and omitted from the JSON when empty.
Example: pre/post hook request with metadata
{ "execution_id": "exec_abc123", "tool": { "name": "ListEmails", "toolkit": "Gmail", "version": "1.0.0", "metadata": { "classification": { "service_domains": ["email"] }, "behavior": { "operations": ["read"], "read_only": true, "destructive": false, "idempotent": true, "open_world": false }, "extras": { "IdP": "entra_id" } } }, "inputs": { "query": "from:boss@company.com" }, "context": { "user_id": "user_123" } }Example: access hook request with metadata
{ "user_id": "user_123", "toolkits": { "Gmail": { "tools": { "ListEmails": [ { "version": "1.0.0", "metadata": { "classification": { "service_domains": ["email"] }, "behavior": { "operations": ["read"], "read_only": true } }, "requirements": { "authorization": [{ "provider_type": "oauth2" }] } } ] } } } }Use cases
Webhook servers can use tool metadata to make more granular decisions:
metadata.behavior.destructiveistruefor certain users"email"domain for a particular projectoperationsarraymetadata.extras.IdPto apply provider-specific policiesReference files
ToolVersionInfoMetadata,ToolClassification, andToolBehaviorschemasapps/engine/pkg/plugins/webhook/schema.gen.goin the monorepo — generated Go types showing exact JSON field names