Problem (falsifiable)
AIP-1 currently does not specify the session lifecycle for MCP transport. Empirically: observing 6 independent client architectures against the AIGEN reference server on 2026-05-20 (UTC), 3 fail with the same root cause.
Failure mode
Every failing client passes step 1 (initialize → 200 1182B) but breaks on step 2:
| Client |
Transport |
Discovery |
Step 1 |
Step 2 |
Root cause |
| Chiark/0.1 (chiark.ai quality index) |
Streamable HTTP |
card-driven |
✅ 200 |
❌ 400 |
No notifications/initialized, no session-header echo |
| MCP-Catalog-Bot/1.0 |
Streamable HTTP |
spec-blind |
✅ 200 |
❌ 400 |
Same |
| vesta-inventory-ping/0.1 (datafenix.ai) |
Streamable HTTP |
inventory-only |
✅ 200 |
n/a |
Single-shot by design; exits before step 2 |
| Ae/JS 0.62.0 |
Streamable HTTP |
card-driven |
✅ 200 |
✅ full |
Sends notifications/initialized + echoes session header |
| Node.js (49.156.213.62) |
Streamable HTTP |
error-recovery |
✅ 200 |
✅ full |
Retries from 400 bodies, eventually sends init notification |
| python-httpx/0.28.1 (Azure) |
SSE |
stale-session |
partial |
partial |
Used expired session_id before re-establishing SSE stream; first SSE-transport client observed |
What AIP-1 currently says
AIP-1 §7 names MCP as the RECOMMENDED transport but does not:
- Mandate that servers MUST accept
notifications/initialized on the same session
- Mandate that servers MUST echo the
Mcp-Session-Id header on follow-up calls
- Specify the SSE transport path (
GET /mcp/sse + POST /messages/?session_id=…) or its lifecycle
- Distinguish the Streamable HTTP handshake from the SSE handshake in the discovery surfaces
Proposed normative addition
Add a subsection to AIP-1 §7 (or a standalone §7.1) with:
MUST: after responding 200 to initialize, accept notifications/initialized on the same session_id
MUST: echo Mcp-Session-Id on every follow-up 200 response (Streamable HTTP)
SHOULD: return JSON-RPC -32001 (session expired) if session_id is unknown, not bare 400
SHOULD: document the transport(s) supported in /.well-known/agent-card.json transport.protocols[]
For SSE specifically:
SHOULD: document sseEndpoint, messageEndpoint, and sessionIdLocation: url_param separately from the Streamable HTTP block
MAY: support both transports simultaneously but MUST document both if so
Why now
Three failing clients per day means every new catalog or trust-scoring tool that discovers AIGEN (and any other OABP server) will fail its first real interaction. The discovery surfaces (agent-card.json, /.well-known/mcp.json) are already good — the gap is the step after.
Evidence
This issue is falsifiable: either a normative lifecycle contract reduces observed step-2 failures to zero across the above client types, or it does not. Observable over 72h on a production OABP server.
Problem (falsifiable)
AIP-1 currently does not specify the session lifecycle for MCP transport. Empirically: observing 6 independent client architectures against the AIGEN reference server on 2026-05-20 (UTC), 3 fail with the same root cause.
Failure mode
Every failing client passes step 1 (
initialize → 200 1182B) but breaks on step 2:notifications/initialized, no session-header echonotifications/initialized+ echoes session headerWhat AIP-1 currently says
AIP-1 §7 names MCP as the RECOMMENDED transport but does not:
notifications/initializedon the same sessionMcp-Session-Idheader on follow-up callsGET /mcp/sse+POST /messages/?session_id=…) or its lifecycleProposed normative addition
Add a subsection to AIP-1 §7 (or a standalone §7.1) with:
For SSE specifically:
Why now
Three failing clients per day means every new catalog or trust-scoring tool that discovers AIGEN (and any other OABP server) will fail its first real interaction. The discovery surfaces (agent-card.json, /.well-known/mcp.json) are already good — the gap is the step after.
Evidence
This issue is falsifiable: either a normative lifecycle contract reduces observed step-2 failures to zero across the above client types, or it does not. Observable over 72h on a production OABP server.