Files
operations/tasks/envelope-directionality-serving.md

41 lines
2.7 KiB
Markdown

# Task: Envelope Directionality — Serving Operations via MCP and HTTP
**Priority**: Medium (blocks hub serving operations to spokes)
**Dependencies**: ADR-005 (response envelopes implemented), ADR-006 (unified invocation path)
**Architecture docs**: [response-envelopes.md](../docs/architecture/response-envelopes.md) § Open Questions #4
## Problem
The current design covers **consuming** remote operations (MCP, OpenAPI) and wrapping their results in `ResponseEnvelope`. The reverse direction — **serving** local operations via MCP or OpenAPI — is not yet addressed.
When the hub exposes operations as an MCP server, results must be wrapped in MCP's `CallToolResult` format (`structuredContent` + `content`). When exposing as OpenAPI, results must be serialized as HTTP response bodies. How `ResponseEnvelope` results get converted to these protocol-specific formats is an open design question.
## Design Questions to Answer
1. **Where does the conversion happen?** Does the hub call `registry.execute()`, get a `ResponseEnvelope`, and then convert it? Or does a serving adapter register as a handler that wraps and returns protocol-native types?
2. **What happens to envelope metadata when serving?** A local operation's `ResponseEnvelope` has `meta: { source: "local", operationId, timestamp }`. When served as MCP, should this become `_meta` on the `CallToolResult`? When served as HTTP, should the timestamp become a `X-Operation-Timestamp` header?
3. **Access control direction for serving**: When serving operations, access control is "what operations does this connected spoke have access to?" vs the consuming direction which is "does the caller have scopes for this operation?"
4. **How do subscription (SUBSCRIPTION) operations work in the serving direction?** When a spoke calls an MCP tool that maps to a SUBSCRIPTION operation on the hub, the result is a stream. How does this map to MCP's response model? MCP doesn't natively have streaming tool results.
5. **Relationship to existing adapters**: `from_mcp` and `from_openapi` are currently one-directional (consume external → register operations). Would "to" variants (`to_mcp`, `to_openapi`) be separate modules, or would the existing adapters gain serving capabilities?
## Scope
Design-only task. Produce:
1. A decision document (ADR or architecture section) answering the questions above
2. An API sketch showing the serving adapter interfaces
3. Identification of implementation work needed
## Constraints
- Must work with the existing `ResponseEnvelope` model — don't change the envelope to accommodate serving
- Must handle all three operation types (QUERY, MUTATION, SUBSCRIPTION)
- Runtime-agnostic (same as rest of package)
- Coherent with ADR-005 and ADR-006