@openwop/spec-artifacts 2.35.1 → 2.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CORPUS-STAMP.json +103 -89
- package/api/openapi.yaml +325 -4
- package/api/seams-v2.yaml +342 -1
- package/api/v2/asyncapi.yaml +1 -1
- package/api/v2/openapi.yaml +564 -8
- package/package.json +1 -1
- package/schemas/a2a-task-state.schema.json +3 -3
- package/schemas/artifact-type-pack-manifest.schema.json +3 -3
- package/schemas/capabilities.schema.json +34 -1
- package/schemas/connection-pack-manifest.schema.json +14 -0
- package/schemas/debug-bundle.schema.json +20 -0
- package/schemas/dispatch-config.schema.json +1 -1
- package/schemas/localized-content-language-settings.schema.json +3 -3
- package/schemas/localized-content-page.schema.json +2 -2
- package/schemas/localized-content-section.schema.json +3 -3
- package/schemas/run-event-payloads.schema.json +4 -2
- package/schemas/suspend-request.schema.json +61 -4
- package/schemas/v2/a2a-task-state.schema.json +10 -9
- package/schemas/v2/agent-deployment-transition.schema.json +4 -4
- package/schemas/v2/agent-deployment.schema.json +7 -7
- package/schemas/v2/agent-eval-suite.schema.json +10 -10
- package/schemas/v2/agent-inventory-response.schema.json +8 -2
- package/schemas/v2/artifact-type-pack-manifest.schema.json +3 -3
- package/schemas/v2/artifact.schema.json +84 -0
- package/schemas/v2/capabilities.schema.json +82 -8
- package/schemas/v2/certification-bundle.schema.json +1 -1
- package/schemas/v2/channel-presence-payload.schema.json +3 -3
- package/schemas/v2/connection-pack-manifest.schema.json +14 -0
- package/schemas/v2/conversation-event.schema.json +9 -2
- package/schemas/v2/conversation-turn.schema.json +19 -12
- package/schemas/v2/dispatch-config.schema.json +1 -1
- package/schemas/v2/envelopes/ui.a2ui-surface.schema.json +920 -22
- package/schemas/v2/error-envelope.schema.json +11 -1
- package/schemas/v2/eval-summary.schema.json +1 -2
- package/schemas/v2/goal.schema.json +4 -4
- package/schemas/v2/localized-content-language-settings.schema.json +3 -3
- package/schemas/v2/localized-content-page.schema.json +2 -2
- package/schemas/v2/localized-content-section.schema.json +3 -3
- package/schemas/v2/node-pack-manifest.schema.json +105 -0
- package/schemas/v2/part.schema.json +81 -0
- package/schemas/v2/proposal.schema.json +6 -6
- package/schemas/v2/run-event-payloads.schema.json +5 -3
- package/schemas/v2/self-hosted-runner-dispatch-frame.schema.json +2 -2
- package/schemas/v2/self-hosted-runner-result-frame.schema.json +1 -1
- package/schemas/v2/suspend-request.schema.json +251 -6
- package/schemas/v2/tool-descriptor.schema.json +246 -2
- package/schemas/v2/trigger-event.schema.json +1 -2
- package/schemas/v2/trigger-subscription.schema.json +1 -2
- package/schemas/v2/webhook-verification.schema.json +22 -0
- package/schemas/v2/workflow-definition.schema.json +25 -25
- package/spec/v1/alias-detectors.json +13 -1
- package/spec/v1/core-standard-manifest.json +2 -2
- package/spec/v1/deprecations.json +45 -1
- package/spec/v1/deprecations.schema.json +119 -4
- package/spec/v1/gaps.json +1925 -4
- package/spec/v2/README.md +5 -2
- package/spec/v2/core/capabilities.md +13 -26
- package/spec/v2/core/conformance.md +5 -8
- package/spec/v2/core/connection-packs.md +1 -1
- package/spec/v2/core/conversation.md +1 -1
- package/spec/v2/core/errors.md +8 -3
- package/spec/v2/core/events.md +8 -20
- package/spec/v2/core/form-content-packs.md +2 -2
- package/spec/v2/core/headers.md +5 -4
- package/spec/v2/core/host-services.md +6 -2
- package/spec/v2/core/idempotency.md +1 -1
- package/spec/v2/core/identity.md +23 -12
- package/spec/v2/core/interop.md +34 -4
- package/spec/v2/core/interrupt.md +6 -3
- package/spec/v2/core/node-pack-runtimes.md +20 -0
- package/spec/v2/core/oauth.md +32 -0
- package/spec/v2/core/overview.md +19 -6
- package/spec/v2/core/packs.md +4 -6
- package/spec/v2/core/persistence.md +20 -55
- package/spec/v2/core/replay.md +5 -11
- package/spec/v2/core/runs.md +9 -8
- package/spec/v2/core/security-defaults.md +18 -20
- package/spec/v2/core/tool-catalog.md +22 -0
- package/spec/v2/core/versioning.md +10 -28
- package/spec/v2/core/webhooks.md +16 -4
- package/spec/v2/core/workflow-chain-packs.md +1 -1
- package/spec/v2/corrections.json +32 -0
- package/spec/v2/corrections.schema.json +49 -0
- package/spec/v2/declaration.json +18 -13
- package/spec/v2/declaration.schema.json +3 -1
- package/spec/v2/errors.json +46 -1
- package/spec/v2/ext/a2uiSurface/README.md +131 -17
- package/spec/v2/ext/dataIntegration/README.md +5 -0
- package/spec/v2/facets/a2a.schema.json +4 -0
- package/spec/v2/facets/auth.schema.json +24 -0
- package/spec/v2/facets/mcp.schema.json +4 -0
- package/spec/v2/facets/oauth.schema.json +70 -0
- package/spec/v2/facets/webhooks.schema.json +23 -2
- package/spec/v2/id-field-bindings.json +2 -0
- package/spec/v2/interop-map.json +639 -0
- package/spec/v2/interop-map.schema.json +458 -0
- package/spec/v2/migrations.json +7 -0
- package/spec/v2/migrations.schema.json +58 -0
- package/spec/v2/path-manifest.json +6 -1
- package/spec/v2/release.json +3 -3
- package/spec/v2/surface-baseline.json +7981 -0
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./interop-map.schema.json",
|
|
3
|
+
"$comment": "RFC 0208 (RFC 0198 adds mcp.tasks). Normative: spec/v2/core/interop.md §\"The operation mappings\" incorporates every row. Hand-maintained; checked by scripts/check-interop-map.mjs against api/v2/openapi.yaml operationIds, spec/v2/errors.json codes, the RunSnapshot.status enum and the spec/v2/facets/ schemas. Upstream names are verbatim; `v2Operation` is an operationId in api/v2/openapi.yaml or null when no v2 operation serves the row. Ships in @openwop/spec-artifacts.",
|
|
4
|
+
"version": 1,
|
|
5
|
+
"updated": "2026-09-22",
|
|
6
|
+
"pins": {
|
|
7
|
+
"a2a": {
|
|
8
|
+
"release": "1.0.1",
|
|
9
|
+
"negotiated": "1.0",
|
|
10
|
+
"spec": "https://github.com/a2aproject/A2A/blob/v1.0.1/docs/specification.md",
|
|
11
|
+
"proto": "https://github.com/a2aproject/A2A/blob/v1.0.1/specification/a2a.proto"
|
|
12
|
+
},
|
|
13
|
+
"mcp": {
|
|
14
|
+
"revision": "2026-07-28",
|
|
15
|
+
"spec": "https://modelcontextprotocol.io/specification/2026-07-28",
|
|
16
|
+
"schema": "https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/2026-07-28/schema.ts"
|
|
17
|
+
},
|
|
18
|
+
"mcpTasks": {
|
|
19
|
+
"extension": "io.modelcontextprotocol/tasks",
|
|
20
|
+
"revision": "2026-07-28",
|
|
21
|
+
"spec": "https://github.com/modelcontextprotocol/ext-tasks/blob/main/specification/2026-07-28/tasks.md",
|
|
22
|
+
"schema": "https://github.com/modelcontextprotocol/ext-tasks/blob/main/schema/2026-07-28/schema.ts"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"a2a": {
|
|
26
|
+
"operations": [
|
|
27
|
+
{
|
|
28
|
+
"upstream": "SendMessage",
|
|
29
|
+
"http": "POST /message:send",
|
|
30
|
+
"when": "no taskId",
|
|
31
|
+
"v2Operation": "createRun",
|
|
32
|
+
"requires": [],
|
|
33
|
+
"rule": "Starts a run of the workflow whose id is the resolved skill id. Blocks until terminal, INPUT_REQUIRED or the host's request timeout, then answers the current Task; with configuration.returnImmediately it answers once the run is accepted, which requires a2a.durableTasks (else UnsupportedOperationError). message.messageId is the idempotency seed: a repeat from the same peer principal MUST NOT create a second run."
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"upstream": "SendMessage",
|
|
37
|
+
"http": "POST /message:send",
|
|
38
|
+
"when": "taskId, run waiting-approval | waiting-input | waiting-external",
|
|
39
|
+
"v2Operation": "resolveInterruptByRun",
|
|
40
|
+
"requires": [],
|
|
41
|
+
"rule": "The message resolves the open interrupt as its resumeValue (approval actions via metadata.openwop.interrupt), with the eligibility interrupt.md requires."
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"upstream": "SendMessage",
|
|
45
|
+
"http": "POST /message:send",
|
|
46
|
+
"when": "taskId, run not suspended and not terminal",
|
|
47
|
+
"v2Operation": null,
|
|
48
|
+
"requires": [],
|
|
49
|
+
"rule": "Delivered through a declared input path, else UnsupportedOperationError. MUST NOT be silently dropped."
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"upstream": "SendMessage",
|
|
53
|
+
"http": "POST /message:send",
|
|
54
|
+
"when": "taskId, run terminal and retained",
|
|
55
|
+
"v2Operation": null,
|
|
56
|
+
"requires": [],
|
|
57
|
+
"rule": "UnsupportedOperationError (A2A §3.1.1). No event is appended."
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"upstream": "SendStreamingMessage",
|
|
61
|
+
"http": "POST /message:stream",
|
|
62
|
+
"when": "as SendMessage",
|
|
63
|
+
"v2Operation": "streamRunEvents",
|
|
64
|
+
"requires": [
|
|
65
|
+
"a2a.streaming"
|
|
66
|
+
],
|
|
67
|
+
"rule": "As SendMessage, with the run's events projected as StreamResponse (the StreamResponse field row). Ends after the terminal statusUpdate."
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"upstream": "GetTask",
|
|
71
|
+
"http": "GET /tasks/{id}",
|
|
72
|
+
"when": "",
|
|
73
|
+
"v2Operation": "getRun",
|
|
74
|
+
"requires": [],
|
|
75
|
+
"rule": "Task projected by taskState; historyLength truncates the response only."
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"upstream": "ListTasks",
|
|
79
|
+
"http": "GET /tasks",
|
|
80
|
+
"when": "",
|
|
81
|
+
"v2Operation": "listRuns",
|
|
82
|
+
"requires": [],
|
|
83
|
+
"rule": "The result set is the set listRuns returns to the same Subject, whether or not runList is advertised, filtered by contextId (A2ATaskState.contextId), status (taskState inverse) and statusTimestampAfter; ordered by status timestamp, newest first; pageSize 1-100, default 50; nextPageToken always present, empty on the last page; artifacts omitted unless includeArtifacts."
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"upstream": "CancelTask",
|
|
87
|
+
"http": "POST /tasks/{id}:cancel",
|
|
88
|
+
"when": "",
|
|
89
|
+
"v2Operation": "cancelRun",
|
|
90
|
+
"requires": [],
|
|
91
|
+
"rule": "Answers the Task at TASK_STATE_WORKING while cancelling, TASK_STATE_CANCELED once cancelled; a terminal run is TaskNotCancelableError."
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"upstream": "SubscribeToTask",
|
|
95
|
+
"http": "POST /tasks/{id}:subscribe",
|
|
96
|
+
"when": "",
|
|
97
|
+
"v2Operation": "streamRunEvents",
|
|
98
|
+
"requires": [
|
|
99
|
+
"a2a.streaming",
|
|
100
|
+
"a2a.durableTasks"
|
|
101
|
+
],
|
|
102
|
+
"rule": "First event is the current Task; read-only re-attachment that MUST NOT re-execute or re-accept a message; a terminal task is UnsupportedOperationError."
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"upstream": "CreateTaskPushNotificationConfig",
|
|
106
|
+
"http": "POST /tasks/{id}/pushNotificationConfigs",
|
|
107
|
+
"when": "",
|
|
108
|
+
"v2Operation": null,
|
|
109
|
+
"requires": [
|
|
110
|
+
"a2a.pushNotifications"
|
|
111
|
+
],
|
|
112
|
+
"rule": "Persists A2ATaskState.pushConfig. url MUST pass the webhooks.md egress guard, scheme and address arms both; token and authentication.credentials are secrets held by reference and MUST NOT enter the event log, the persisted A2ATaskState or a debug bundle. Unadvertised: PushNotificationNotSupportedError."
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"upstream": "GetTaskPushNotificationConfig | ListTaskPushNotificationConfigs | DeleteTaskPushNotificationConfig",
|
|
116
|
+
"http": "GET | GET | DELETE /tasks/{id}/pushNotificationConfigs[/{configId}]",
|
|
117
|
+
"when": "",
|
|
118
|
+
"v2Operation": null,
|
|
119
|
+
"requires": [
|
|
120
|
+
"a2a.pushNotifications"
|
|
121
|
+
],
|
|
122
|
+
"rule": "Reads or deletes the persisted configs of a task the caller can read; secrets are never returned."
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"upstream": "GetExtendedAgentCard",
|
|
126
|
+
"http": "GET /extendedAgentCard",
|
|
127
|
+
"when": "",
|
|
128
|
+
"v2Operation": null,
|
|
129
|
+
"requires": [],
|
|
130
|
+
"rule": "Authorized at the OpenWOP boundary; MUST NOT disclose skills, interfaces or security requirements the caller cannot use. Not configured: ExtendedAgentCardNotConfiguredError."
|
|
131
|
+
}
|
|
132
|
+
],
|
|
133
|
+
"card": [
|
|
134
|
+
{
|
|
135
|
+
"element": "supportedInterfaces[]",
|
|
136
|
+
"rule": "Only interfaces the host routes. The set of protocolVersion values equals a2a.versions; the preferredVersion interface is listed first. Claiming profile a2a-1.0 requires a JSONRPC interface at 1.0; HTTP+JSON and GRPC are optional."
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"element": "capabilities",
|
|
140
|
+
"rule": "streaming and pushNotifications equal the a2a facets; extendedAgentCard is true iff GetExtendedAgentCard is served; extensions[] lists only extensions the host implements."
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"element": "skills[]",
|
|
144
|
+
"rule": "One skill per invocable workflow from the registry runtime routing uses; skills[].id is the routed workflowId; no skill the host does not route."
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"element": "securitySchemes | securityRequirements",
|
|
148
|
+
"rule": "Exactly the authentication the endpoint enforces; they describe how a peer authenticates, never what it may do."
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"element": "provider",
|
|
152
|
+
"rule": "Names the organization operating the endpoint; its url SHOULD equal implementation.url when both are present."
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"element": "supportedInterfaces[].tenant",
|
|
156
|
+
"rule": "A routing hint that never selects the tenant of record. Per-agent routing values (a2aTenant) are specified by interop.md §Per-agent cards (RFC 0202)."
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"element": "signatures[]",
|
|
160
|
+
"rule": "A host SHOULD sign its card; a consuming host SHOULD verify before invoking and MAY refuse an unsigned card."
|
|
161
|
+
}
|
|
162
|
+
],
|
|
163
|
+
"taskState": [
|
|
164
|
+
{
|
|
165
|
+
"runStatus": "pending",
|
|
166
|
+
"stored": "submitted",
|
|
167
|
+
"wire": "TASK_STATE_SUBMITTED"
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"runStatus": "running",
|
|
171
|
+
"stored": "working",
|
|
172
|
+
"wire": "TASK_STATE_WORKING"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"runStatus": "paused",
|
|
176
|
+
"stored": "working",
|
|
177
|
+
"wire": "TASK_STATE_WORKING"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"runStatus": "cancelling",
|
|
181
|
+
"stored": "working",
|
|
182
|
+
"wire": "TASK_STATE_WORKING"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"runStatus": "waiting-approval",
|
|
186
|
+
"stored": "input-required",
|
|
187
|
+
"wire": "TASK_STATE_INPUT_REQUIRED",
|
|
188
|
+
"carrier": "metadata.openwop.interrupt.kind"
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"runStatus": "waiting-input",
|
|
192
|
+
"stored": "input-required",
|
|
193
|
+
"wire": "TASK_STATE_INPUT_REQUIRED",
|
|
194
|
+
"carrier": "metadata.openwop.interrupt.kind"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"runStatus": "waiting-input",
|
|
198
|
+
"interruptKind": "credential",
|
|
199
|
+
"stored": "auth-required",
|
|
200
|
+
"wire": "TASK_STATE_AUTH_REQUIRED",
|
|
201
|
+
"carrier": "metadata.openwop.interrupt.kind; the status message names the provider and carries connectUrl (RFC 0199 §D.1)"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"runStatus": "waiting-external",
|
|
205
|
+
"stored": "input-required",
|
|
206
|
+
"wire": "TASK_STATE_INPUT_REQUIRED",
|
|
207
|
+
"carrier": "metadata.openwop.interrupt.kind"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
"runStatus": "completed",
|
|
211
|
+
"stored": "completed",
|
|
212
|
+
"wire": "TASK_STATE_COMPLETED"
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"runStatus": "failed",
|
|
216
|
+
"stored": "failed",
|
|
217
|
+
"wire": "TASK_STATE_FAILED"
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"runStatus": "cancelled",
|
|
221
|
+
"stored": "canceled",
|
|
222
|
+
"wire": "TASK_STATE_CANCELED"
|
|
223
|
+
}
|
|
224
|
+
],
|
|
225
|
+
"taskStateReverse": [
|
|
226
|
+
{
|
|
227
|
+
"wire": "TASK_STATE_SUBMITTED",
|
|
228
|
+
"runStatus": "pending"
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"wire": "TASK_STATE_WORKING",
|
|
232
|
+
"runStatus": "running"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"wire": "TASK_STATE_INPUT_REQUIRED",
|
|
236
|
+
"runStatus": "waiting-input"
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"wire": "TASK_STATE_AUTH_REQUIRED",
|
|
240
|
+
"runStatus": "waiting-input",
|
|
241
|
+
"note": "reverse: an external agent's AUTH_REQUIRED projects to waiting-input with metadata.subkind auth; a host MAY instead raise a credential interrupt when it can obtain the peer's credential through oauth (RFC 0199 §D.1). The forward source is the credential interrupt (the a2a.taskState override row)."
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"wire": "TASK_STATE_COMPLETED",
|
|
245
|
+
"runStatus": "completed"
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"wire": "TASK_STATE_FAILED",
|
|
249
|
+
"runStatus": "failed"
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"wire": "TASK_STATE_CANCELED",
|
|
253
|
+
"runStatus": "cancelled"
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
"wire": "TASK_STATE_REJECTED",
|
|
257
|
+
"runStatus": "failed",
|
|
258
|
+
"note": "reason rejected_by_remote"
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"wire": "TASK_STATE_UNSPECIFIED",
|
|
262
|
+
"runStatus": "pending",
|
|
263
|
+
"note": "never emitted; read with a warning"
|
|
264
|
+
}
|
|
265
|
+
],
|
|
266
|
+
"errors": [
|
|
267
|
+
{
|
|
268
|
+
"upstream": "TaskNotFoundError",
|
|
269
|
+
"jsonrpc": -32001,
|
|
270
|
+
"grpc": "NOT_FOUND",
|
|
271
|
+
"http": 404,
|
|
272
|
+
"serverWhen": "unknown, purged, or not readable by the caller (identically, including a tenant mismatch)",
|
|
273
|
+
"clientProjection": "not_found"
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"upstream": "TaskNotCancelableError",
|
|
277
|
+
"jsonrpc": -32002,
|
|
278
|
+
"grpc": "FAILED_PRECONDITION",
|
|
279
|
+
"http": 400,
|
|
280
|
+
"serverWhen": "CancelTask on a terminal run",
|
|
281
|
+
"clientProjection": "run_terminal"
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
"upstream": "PushNotificationNotSupportedError",
|
|
285
|
+
"jsonrpc": -32003,
|
|
286
|
+
"grpc": "FAILED_PRECONDITION",
|
|
287
|
+
"http": 400,
|
|
288
|
+
"serverWhen": "push config without a2a.pushNotifications",
|
|
289
|
+
"clientProjection": "capability_required"
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
"upstream": "UnsupportedOperationError",
|
|
293
|
+
"jsonrpc": -32004,
|
|
294
|
+
"grpc": "FAILED_PRECONDITION",
|
|
295
|
+
"http": 400,
|
|
296
|
+
"serverWhen": "an unimplemented operation or option; a message to a retained terminal task; SubscribeToTask on a terminal task",
|
|
297
|
+
"clientProjection": "capability_required"
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
"upstream": "ContentTypeNotSupportedError",
|
|
301
|
+
"jsonrpc": -32005,
|
|
302
|
+
"grpc": "INVALID_ARGUMENT",
|
|
303
|
+
"http": 400,
|
|
304
|
+
"serverWhen": "a part mediaType or acceptedOutputModes entry the skill cannot handle, at request time",
|
|
305
|
+
"clientProjection": "validation_error"
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
"upstream": "InvalidAgentResponseError",
|
|
309
|
+
"jsonrpc": -32006,
|
|
310
|
+
"grpc": "INTERNAL",
|
|
311
|
+
"http": 500,
|
|
312
|
+
"serverWhen": null,
|
|
313
|
+
"clientProjection": "validation_error",
|
|
314
|
+
"note": "the malformed body MUST NOT enter run state"
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
"upstream": "ExtendedAgentCardNotConfiguredError",
|
|
318
|
+
"jsonrpc": -32007,
|
|
319
|
+
"grpc": "FAILED_PRECONDITION",
|
|
320
|
+
"http": 400,
|
|
321
|
+
"serverWhen": "GetExtendedAgentCard with capabilities.extendedAgentCard not true",
|
|
322
|
+
"clientProjection": "not_found"
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"upstream": "ExtensionSupportRequiredError",
|
|
326
|
+
"jsonrpc": -32008,
|
|
327
|
+
"grpc": "FAILED_PRECONDITION",
|
|
328
|
+
"http": 400,
|
|
329
|
+
"serverWhen": "only for a required:true extension the client did not declare",
|
|
330
|
+
"clientProjection": "validation_error"
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
"upstream": "VersionNotSupportedError",
|
|
334
|
+
"jsonrpc": -32009,
|
|
335
|
+
"grpc": "FAILED_PRECONDITION",
|
|
336
|
+
"http": 400,
|
|
337
|
+
"serverWhen": "an A2A-Version the interface does not serve",
|
|
338
|
+
"clientProjection": "interop_version_unsupported"
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
"upstream": "(invalid parameters)",
|
|
342
|
+
"jsonrpc": -32602,
|
|
343
|
+
"grpc": "INVALID_ARGUMENT",
|
|
344
|
+
"http": 400,
|
|
345
|
+
"serverWhen": "a message whose contextId is not its task's (A2A §3.4.3); no run state changes",
|
|
346
|
+
"clientProjection": "validation_error"
|
|
347
|
+
}
|
|
348
|
+
],
|
|
349
|
+
"fields": [
|
|
350
|
+
{
|
|
351
|
+
"element": "Message.contextId",
|
|
352
|
+
"rule": "Opaque correlation key persisted as A2ATaskState.contextId. Inferred from the task when only taskId is given."
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
"element": "Message.role",
|
|
356
|
+
"rule": "Recorded; both roles enter the run contentTrust untrusted and confer no authority."
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
"element": "Message.extensions[]",
|
|
360
|
+
"rule": "Opaque unless the card lists the extension; a host listing none MUST NOT raise ExtensionSupportRequiredError."
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
"element": "Message.referenceTaskIds[]",
|
|
364
|
+
"rule": "Hints; grant no read access and are not dereferenced into prompt or tool context."
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
"element": "Part",
|
|
368
|
+
"rule": "Discriminated by member presence (text | raw | url | data), never a kind field. raw bytes are stored by reference, not inlined in the event log; a url is a reference and fetching it is an egress decision."
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
"element": "Artifact.artifactId",
|
|
372
|
+
"rule": "Stable across GetTask reads and across TaskArtifactUpdateEvent chunks of one artifact."
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
"element": "Task.history[]",
|
|
376
|
+
"rule": "Only the A2A Messages exchanged on the task; never run-internal model transcripts, tool I/O or agent.* events."
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
"element": "Task.metadata",
|
|
380
|
+
"rule": "metadata.openwop.interrupt and metadata.openwop.permittedPurposes are the only named keys."
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
"element": "StreamResponse",
|
|
384
|
+
"rule": "task first, then statusUpdate per status change and artifactUpdate per published artifact chunk; never agent.*, provider-usage or tool I/O events."
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
"element": "error message",
|
|
388
|
+
"rule": "Carries no stack trace, provider body, credential, or the other side's raw error body; relayed peer details reduce to the error type and, for version errors, supportedVersions[]."
|
|
389
|
+
}
|
|
390
|
+
]
|
|
391
|
+
},
|
|
392
|
+
"mcp": {
|
|
393
|
+
"features": [
|
|
394
|
+
{
|
|
395
|
+
"id": "server-discover",
|
|
396
|
+
"requiredFor": [
|
|
397
|
+
"mcp-2026-07-28"
|
|
398
|
+
],
|
|
399
|
+
"meaning": "The host serves server/discover."
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
"id": "mrtr",
|
|
403
|
+
"requiredFor": [
|
|
404
|
+
"mcp-2026-07-28"
|
|
405
|
+
],
|
|
406
|
+
"meaning": "The host answers and consumes InputRequiredResult (mrtr rows)."
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
"id": "cacheable-lists",
|
|
410
|
+
"requiredFor": [
|
|
411
|
+
"mcp-2026-07-28"
|
|
412
|
+
],
|
|
413
|
+
"meaning": "List and read results carry ttlMs and cacheScope."
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
"id": "extensions",
|
|
417
|
+
"requiredFor": [],
|
|
418
|
+
"meaning": "The host advertises and honours capabilities.extensions; the extensions it serves are listed in server/discover."
|
|
419
|
+
}
|
|
420
|
+
],
|
|
421
|
+
"methods": [
|
|
422
|
+
{
|
|
423
|
+
"upstream": "server/discover",
|
|
424
|
+
"v2Operation": "getCapabilities",
|
|
425
|
+
"requires": [],
|
|
426
|
+
"rule": "supportedVersions[] MUST equal mcp.revisions; capabilities.extensions lists exactly the extensions served."
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
"upstream": "tools/list",
|
|
430
|
+
"v2Operation": null,
|
|
431
|
+
"requires": [
|
|
432
|
+
"mcp.serverMount"
|
|
433
|
+
],
|
|
434
|
+
"rule": "The workflows the host exposes to the caller, from its tenant-scoped registry; identical for every connection of one caller; sorted by name; cacheScope private whenever the list depends on the caller."
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
"upstream": "tools/call",
|
|
438
|
+
"v2Operation": "createRun",
|
|
439
|
+
"requires": [
|
|
440
|
+
"mcp.serverMount"
|
|
441
|
+
],
|
|
442
|
+
"rule": "arguments validated against the tool's inputSchema before any run is created (else -32602); the run starts with trust boundary untrusted and run.started.transport mcp. completed is CallToolResult isError false; failed and cancelled are CallToolResult isError true; waiting-approval and waiting-input are InputRequiredResult (mrtr rows)."
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
"upstream": "prompts/get | resources/read",
|
|
446
|
+
"v2Operation": null,
|
|
447
|
+
"requires": [
|
|
448
|
+
"mcp.serverMount"
|
|
449
|
+
],
|
|
450
|
+
"rule": "Prompt arguments render as text without template evaluation; resource URIs are normalized with no traversal and no scheme outside the host allowlist."
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
"upstream": "initialize | Mcp-Session-Id",
|
|
454
|
+
"v2Operation": null,
|
|
455
|
+
"requires": [],
|
|
456
|
+
"rule": "MUST NOT be required for a current-profile request; cross-call state is an explicit server-minted tool argument, never a session."
|
|
457
|
+
}
|
|
458
|
+
],
|
|
459
|
+
"headers": [
|
|
460
|
+
{
|
|
461
|
+
"element": "MCP-Protocol-Version",
|
|
462
|
+
"rule": "MUST equal the _meta io.modelcontextprotocol/protocolVersion; a mismatch is 400 HeaderMismatchError (-32020), checked before version selection."
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
"element": "Mcp-Method | Mcp-Name",
|
|
466
|
+
"rule": "MUST equal method and params.name (or params.uri, or params.taskId); a mismatch fails closed as MCP-Protocol-Version does."
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
"element": "(no MCP-Protocol-Version)",
|
|
470
|
+
"rule": "At most 2025-03-26 upstream; refused when mcp.revisions lists no such revision."
|
|
471
|
+
}
|
|
472
|
+
],
|
|
473
|
+
"meta": [
|
|
474
|
+
{
|
|
475
|
+
"element": "io.modelcontextprotocol/clientCapabilities",
|
|
476
|
+
"rule": "Required on every request; a capability the request did not declare is MissingRequiredClientCapabilityError (-32021), never assumed."
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
"element": "io.modelcontextprotocol/logLevel",
|
|
480
|
+
"rule": "notifications/message flows on the request's own stream only when the request carried it."
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
"element": "traceparent | tracestate | baggage",
|
|
484
|
+
"rule": "Propagated per observability; never used for authorization. The carrier rule is interop.md §Trace context (RFC 0207 owns this row)."
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
"element": "io.modelcontextprotocol/clientInfo | serverInfo",
|
|
488
|
+
"rule": "Self-reported; never an authorization input."
|
|
489
|
+
}
|
|
490
|
+
],
|
|
491
|
+
"mrtr": [
|
|
492
|
+
{
|
|
493
|
+
"element": "InputRequiredResult (host as server)",
|
|
494
|
+
"rule": "A run reaching waiting-approval or waiting-input answers the in-flight request with inputRequests { <interruptId>: elicitation/create } and a requestState. Form mode (requestedSchema from the interrupt payload) only for a flat object of primitive properties none of which is writeOnly or format password (MCP Elicitation, restated by RFC 0199 §D.2(d)). A credential interrupt, and any other schema, uses mode url (url = the credential interrupt's connectUrl, or a host-owned page that resolves that interrupt for the same Subject) when the request declared _meta[io.modelcontextprotocol/clientCapabilities].elicitation.url; otherwise the request is answered CallToolResult isError naming the provider, the run stays suspended and resolvable through the REST and token surfaces, and the host never falls back to form mode (RFC 0199 §D.2)."
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
"element": "requestState (host as server)",
|
|
498
|
+
"rule": "Integrity-protected and bound to the authenticated principal, a TTL, the originating request digest, the runId and the interrupt; single use: a second retry with it MUST fail."
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
"element": "inputResponses[key] (host as server)",
|
|
502
|
+
"rule": "ElicitResult action accept resumes with content, decline takes the decline path, cancel cancels the interrupt; the resolver MUST be an eligible approver (interrupt.md); content never becomes authority. For a url-mode request, accept carries no content and causes the credential re-check (RFC 0199 §D.2(c)): a credential that now resolves resolves the interrupt and the run continues; otherwise the host answers input_required again with the same url, not an error."
|
|
503
|
+
},
|
|
504
|
+
{
|
|
505
|
+
"element": "InputRequiredResult (host as client)",
|
|
506
|
+
"rule": "The initial request and every retry are one logical invocation; requestState is persisted byte-exact and never parsed; the retry carries a new JSON-RPC id and every key; rounds are bounded by mcp.mrtr.maxRounds; replay MUST NOT re-issue a retry or re-prompt; an interim result is never cached."
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
"element": "sampling/createMessage | roots/list in inputRequests",
|
|
510
|
+
"rule": "Honoured only when the request declared the capability; sampling runs under the run's own provider policy and budget."
|
|
511
|
+
}
|
|
512
|
+
],
|
|
513
|
+
"cache": [
|
|
514
|
+
{
|
|
515
|
+
"element": "cacheScope",
|
|
516
|
+
"rule": "private whenever the result depends on the caller's tenant, workspace, principal or authorization; public only when byte-identical for every caller."
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
"element": "client cache key",
|
|
520
|
+
"rule": "tenant, workspace, principal, server origin, revision and authorization context; a private result never crosses authorization contexts, and an authorization change stales it regardless of ttlMs."
|
|
521
|
+
}
|
|
522
|
+
],
|
|
523
|
+
"authorization": [
|
|
524
|
+
{
|
|
525
|
+
"element": "every tools/*, prompts/*, resources/* request",
|
|
526
|
+
"rule": "Authenticated and authorized at the OpenWOP boundary before a run starts, a resource is read or a prompt renders; unauthenticated only where anonymousActor is advertised."
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
"element": "the mount as an OAuth protected resource (RFC 0200 §A.4)",
|
|
530
|
+
"rule": "A mount that requires oauth2/oidc-lane authentication MUST implement one of upstream's two discovery mechanisms for the mount URL as the resource: resource_metadata in the mount's 401 WWW-Authenticate challenge, or RFC 9728 Protected Resource Metadata at the well-known URI with the mount path inserted. identity.md §2.5 governs the document and the challenge."
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
"element": "the MCP client's token (RFC 0200 §E)",
|
|
534
|
+
"rule": "MUST NOT be attached to any outbound request the mount makes on the peer's behalf; outbound authentication uses only credentials the host holds for that destination (security-defaults.md §Onward hops, oauth.md)."
|
|
535
|
+
}
|
|
536
|
+
],
|
|
537
|
+
"tasks": {
|
|
538
|
+
"status": [
|
|
539
|
+
{
|
|
540
|
+
"runStatus": "pending",
|
|
541
|
+
"taskStatus": "working"
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
"runStatus": "running",
|
|
545
|
+
"taskStatus": "working"
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
"runStatus": "paused",
|
|
549
|
+
"taskStatus": "working"
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
"runStatus": "cancelling",
|
|
553
|
+
"taskStatus": "working"
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
"runStatus": "waiting-external",
|
|
557
|
+
"taskStatus": "working",
|
|
558
|
+
"note": "no client input is outstanding"
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
"runStatus": "waiting-approval",
|
|
562
|
+
"taskStatus": "input_required",
|
|
563
|
+
"note": "inputRequests per the mrtr InputRequiredResult row, one key per open interrupt, keyed by interruptId"
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
"runStatus": "waiting-input",
|
|
567
|
+
"taskStatus": "input_required",
|
|
568
|
+
"note": "as waiting-approval"
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
"runStatus": "completed",
|
|
572
|
+
"taskStatus": "completed",
|
|
573
|
+
"note": "result is the CallToolResult tools/call would have returned, isError false"
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
"runStatus": "failed",
|
|
577
|
+
"taskStatus": "completed",
|
|
578
|
+
"note": "result is CallToolResult isError true; task status failed is reserved for a JSON-RPC error the host itself raises (ext-tasks §Task Execution Errors)"
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
"runStatus": "cancelled",
|
|
582
|
+
"taskStatus": "cancelled"
|
|
583
|
+
}
|
|
584
|
+
],
|
|
585
|
+
"methods": [
|
|
586
|
+
{
|
|
587
|
+
"upstream": "tasks/get",
|
|
588
|
+
"v2Operation": "getRun",
|
|
589
|
+
"requires": [
|
|
590
|
+
"mcp.serverMount"
|
|
591
|
+
],
|
|
592
|
+
"rule": "Projects the run by the status rows. A read: no event is appended. An unknown, purged or unreadable taskId is -32602, identically."
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
"upstream": "tasks/update",
|
|
596
|
+
"v2Operation": "resolveInterruptByRun",
|
|
597
|
+
"requires": [
|
|
598
|
+
"mcp.serverMount"
|
|
599
|
+
],
|
|
600
|
+
"rule": "Each inputResponses[<interruptId>] resolves that interrupt exactly as the mrtr inputResponses row does, with the same approver eligibility. A key already answered, never issued, or no longer open resolves nothing; one interrupt is resolved at most once however often it is answered."
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
"upstream": "tasks/cancel",
|
|
604
|
+
"v2Operation": "cancelRun",
|
|
605
|
+
"requires": [
|
|
606
|
+
"mcp.serverMount"
|
|
607
|
+
],
|
|
608
|
+
"rule": "Acknowledged with an empty result; the run is cancelled as cancelRun would cancel it. On a terminal run it is acknowledged and nothing is appended."
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
"upstream": "notifications/tasks | subscriptions/listen taskIds",
|
|
612
|
+
"v2Operation": null,
|
|
613
|
+
"requires": [
|
|
614
|
+
"mcp.serverMount"
|
|
615
|
+
],
|
|
616
|
+
"rule": "Optional, on subscriptions/listen only; each carries what tasks/get would return at that moment. A requested taskId the caller cannot read is left out of notifications/subscriptions/acknowledged exactly as a nonexistent one, and is never notified."
|
|
617
|
+
}
|
|
618
|
+
],
|
|
619
|
+
"fields": [
|
|
620
|
+
{
|
|
621
|
+
"element": "taskId",
|
|
622
|
+
"rule": "The run's runId in its projected wire form (identity.md §5). Authorization is decided per request, never by possession of the id."
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
"element": "ttlMs",
|
|
626
|
+
"rule": "null, or not shorter than the host's retention for the run. A host MUST NOT fail or cancel a run because a task's TTL elapsed."
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
"element": "statusMessage",
|
|
630
|
+
"rule": "Content-free with respect to run internals: no model transcript, tool I/O or credential."
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
"element": "io.modelcontextprotocol/tasks in clientCapabilities.extensions",
|
|
634
|
+
"rule": "Required on the tools/call for a CreateTaskResult and on every tasks/* request (else -32021)."
|
|
635
|
+
}
|
|
636
|
+
]
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
}
|