You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: drop top-level anyOf from webhook tool input schemas
webhooks_verify_signature, webhooks_parse_payload, and webhooks_triage_event
wrapped their object schema in a top-level anyOf to express "payload or
payload_base64". The Anthropic API rejects top-level oneOf/anyOf/allOf in a
tool input_schema even with type:object, so every sub-agent (Explore, Plan,
teammates) failed with HTTP 400 since 2.4.0. The either/or constraint is
already enforced at runtime in the handlers, so the schema hint was redundant.
Also strip top-level composition centrally in ToolMetadataPolicy as a safety
net, and add a regression test forbidding it across all tool schemas.
Copy file name to clipboardExpand all lines: Sources/asc-mcp/Workers/WebhooksWorker/WebhooksWorker+ToolDefinitions.swift
+33-54Lines changed: 33 additions & 54 deletions
Original file line number
Diff line number
Diff line change
@@ -129,62 +129,53 @@ extension WebhooksWorker {
129
129
func verifySignatureTool()->Tool{
130
130
Tool(
131
131
name:"webhooks_verify_signature",
132
-
description:"Verify an App Store Connect webhook x-apple-signature HMAC against the exact raw request body. This is local and does not call Apple.",
133
-
inputSchema:schemaRequiringAnyOf(
134
-
baseSchema(
135
-
properties:[
136
-
"secret":stringSchema("Webhook secret configured in App Store Connect"),
137
-
"signature":stringSchema("x-apple-signature header value, for example hmacsha256=<hex>"),
138
-
"payload":stringSchema("Exact raw UTF-8 request body received by your webhook endpoint"),
139
-
"payload_base64":stringSchema("Base64-encoded exact raw request body bytes; use this when byte-for-byte preservation matters")
140
-
],
141
-
required:["secret","signature"]
142
-
),
143
-
alternatives:[["payload"],["payload_base64"]]
132
+
description:"Verify an App Store Connect webhook x-apple-signature HMAC against the exact raw request body. This is local and does not call Apple. Provide the body via either `payload` (raw UTF-8) or `payload_base64`.",
133
+
inputSchema:baseSchema(
134
+
properties:[
135
+
"secret":stringSchema("Webhook secret configured in App Store Connect"),
136
+
"signature":stringSchema("x-apple-signature header value, for example hmacsha256=<hex>"),
137
+
"payload":stringSchema("Exact raw UTF-8 request body received by your webhook endpoint"),
138
+
"payload_base64":stringSchema("Base64-encoded exact raw request body bytes; use this when byte-for-byte preservation matters")
139
+
],
140
+
required:["secret","signature"]
144
141
)
145
142
)
146
143
}
147
144
148
145
func parsePayloadTool()->Tool{
149
146
Tool(
150
147
name:"webhooks_parse_payload",
151
-
description:"Parse and normalize a raw App Store Connect webhook payload, including nested event payload JSON when Apple sends it as a string. This is local and read-only.",
152
-
inputSchema:schemaRequiringAnyOf(
153
-
baseSchema(
154
-
properties:[
155
-
"payload":stringSchema("Exact raw UTF-8 request body received by your webhook endpoint"),
156
-
"payload_base64":stringSchema("Base64-encoded exact raw request body bytes"),
157
-
"secret":stringSchema("Optional webhook secret used to verify the signature while parsing"),
158
-
"signature":stringSchema("Optional x-apple-signature header value used with secret")
159
-
],
160
-
required:[]
161
-
),
162
-
alternatives:[["payload"],["payload_base64"]]
148
+
description:"Parse and normalize a raw App Store Connect webhook payload, including nested event payload JSON when Apple sends it as a string. This is local and read-only. Provide the body via either `payload` (raw UTF-8) or `payload_base64`.",
149
+
inputSchema:baseSchema(
150
+
properties:[
151
+
"payload":stringSchema("Exact raw UTF-8 request body received by your webhook endpoint"),
152
+
"payload_base64":stringSchema("Base64-encoded exact raw request body bytes"),
153
+
"secret":stringSchema("Optional webhook secret used to verify the signature while parsing"),
154
+
"signature":stringSchema("Optional x-apple-signature header value used with secret")
155
+
],
156
+
required:[]
163
157
)
164
158
)
165
159
}
166
160
167
161
func triageEventTool()->Tool{
168
162
Tool(
169
163
name:"webhooks_triage_event",
170
-
description:"Turn a webhook event or failed delivery context into an actionable MCP triage plan with recommended read-only lookup tools.",
171
-
inputSchema:schemaRequiringAnyOf(
172
-
baseSchema(
173
-
properties:[
174
-
"payload":stringSchema("Optional exact raw UTF-8 webhook request body"),
175
-
"payload_base64":stringSchema("Optional base64-encoded exact raw request body bytes"),
176
-
"event_type":enumSchema("Webhook event type when raw payload is not available", values:ASCWebhookEventTypes.all),
177
-
"resource_type":stringSchema("Optional affected App Store Connect resource type from the webhook payload"),
178
-
"resource_id":stringSchema("Optional affected App Store Connect resource ID from the webhook payload"),
179
-
"delivery_id":stringSchema("Optional webhook delivery ID for redelivery recommendations"),
180
-
"webhook_id":stringSchema("Optional webhook configuration ID for ping/delivery recommendations"),
181
-
"delivery_state":enumSchema("Optional delivery state from webhooks_list_deliveries", values:["SUCCEEDED","FAILED","PENDING"]),
182
-
"http_status_code":integerSchema("Optional receiver HTTP status code from the delivery response"),
description:"Turn a webhook event or failed delivery context into an actionable MCP triage plan with recommended read-only lookup tools. Provide at least one of: `event_type`, `payload`, or `payload_base64`.",
165
+
inputSchema:baseSchema(
166
+
properties:[
167
+
"payload":stringSchema("Optional exact raw UTF-8 webhook request body"),
168
+
"payload_base64":stringSchema("Optional base64-encoded exact raw request body bytes"),
169
+
"event_type":enumSchema("Webhook event type when raw payload is not available", values:ASCWebhookEventTypes.all),
170
+
"resource_type":stringSchema("Optional affected App Store Connect resource type from the webhook payload"),
171
+
"resource_id":stringSchema("Optional affected App Store Connect resource ID from the webhook payload"),
172
+
"delivery_id":stringSchema("Optional webhook delivery ID for redelivery recommendations"),
173
+
"webhook_id":stringSchema("Optional webhook configuration ID for ping/delivery recommendations"),
174
+
"delivery_state":enumSchema("Optional delivery state from webhooks_list_deliveries", values:["SUCCEEDED","FAILED","PENDING"]),
175
+
"http_status_code":integerSchema("Optional receiver HTTP status code from the delivery response"),
0 commit comments