symfonic.capabilities.extensions.mcp_reader¶
mcp_reader ¶
Reading MCP wire payloads (T4.2.2).
The adapter next door decides what to do with an MCP server; this module decides what a payload says, and it is separate because those two failures have different fixes. An adapter bug is ours. A payload that fails to parse here belongs to whoever runs the server, and the message has to be good enough for them to act on without our source in front of them.
Two readings, one rule each.
:func:read_tool_payload refuses. A tool advertisement drives argument
binding and routing, so a payload that is malformed in name or schema yields no
tool at all — the caller records the refusal and moves to the next entry.
:func:read_result_text degrades. A result is content; a shape we do not
understand is a result we did not get, and raising there would turn one
confused server response into an exception inside the agent loop.
ToolDraft
dataclass
¶
ToolDraft(raw_name: str, description: str = '', input_schema: dict[str, Any] = dict(), truncated: bool = False)
One validated tool advertisement, before it is named and bound.
read_result_text ¶
Read a tools/call result into bounded text.
Only type == "text" parts are read. The rest of the MCP content
vocabulary (images, embedded resources) is dropped rather than
stringified: a resource reference rendered into the transcript as its repr
is a URL the model may act on, and integration output influences context,
never targets (AS-INT-1).
A non-mapping payload, or one whose content is not a list, yields the
empty string with no exception.
Both the part count and the running length are bounded as the parts are
read, rather than only the finished join. Capping each part and joining an
unbounded number of them still materialises their product first, which is
the ceiling argument (AS-ING-6) applied one step too late. Whatever the
bounds drop, the result carries :data:~.trust.TRUNCATION_MARKER, so a
shortened answer never reads as a complete one.
Source code in src/symfonic/capabilities/extensions/mcp_reader.py
read_tool_payload ¶
Validate one tools/list entry.
Raises:
| Type | Description |
|---|---|
UntrustedPayloadError
|
If the entry is not an object, its name is missing / mistyped / out of charset / over length, or its schema is not a bounded JSON object. |