# Too-Large Content Breaks MCP `structuredContent` Validation

**Issue**: [HLND2T/CS2_VibeSignatures#171](https://github.com/HLND2T/CS2_VibeSignatures/issues/171)

## Summary

When `vcall_finder` calls the IDA MCP server's `py_eval` tool to dump large functions (disassembly + pseudocode), the response exceeds the server's size limit. The server truncates the output and injects metadata fields into `structuredContent` that violate its own declared `outputSchema`, causing the MCP Python SDK (v1.25.0+) to throw a `RuntimeError` during client-side schema validation.

## Root Cause

### Call chain

1. `ida_vcall_finder.py` calls `session.call_tool(name="py_eval", ...)` with a script generated by `build_function_dump_py_eval()`.
2. The generated script dumps both **disassembly** and **pseudocode** for the target function. For large functions (e.g. `CNetworkSystem_SendNetworkStats`), the JSON result can exceed **225K characters**.
3. The IDA MCP server's `py_eval` tool declares a strict `outputSchema`:

   ```json
   {
     "properties": {
       "result": { "type": "string" },
       "stdout": { "type": "string" },
       "stderr": { "type": "string" }
     },
     "required": ["result", "stdout", "stderr"],
     "additionalProperties": false
   }
   ```

4. When the response is too large, the IDA MCP server **truncates** the output and **injects additional metadata fields** into `structuredContent`:
   - `_output_truncated`
   - `_total_chars`
   - `_output_id`
   - `_download_url`
   - `_download_hint`

5. MCP Python SDK v1.25.0 introduced `ClientSession._validate_tool_result()` (in `mcp/client/session.py`), which validates `structuredContent` against the tool's declared `outputSchema` using `jsonschema.validate()`.

6. Because the injected `_`-prefixed fields are **not declared** in the schema and `additionalProperties` is `false`, validation fails with:

   ```
   RuntimeError: Invalid structured content returned by tool py_eval:
   Additional properties are not allowed
   ('_download_hint', '_download_url', '_output_id', '_output_truncated', '_total_chars' were unexpected)
   ```

### Who is at fault

The **IDA MCP server** is the root cause: it injects truncation metadata fields into `structuredContent` that violate its own `outputSchema`. The MCP SDK's client-side validation (added in v1.25.0) merely exposes this pre-existing schema inconsistency.

## Fix Options

### Option A: Export the detail YAML directly from IDA (recommended)

Keep the object-xref query flow unchanged, but stop returning full function dumps through `py_eval`.
Instead, build the detail payload on the IDA side, serialize it as plain YAML with `PyYAML`,
write it directly to the target absolute path, and return only a small ack payload.

Example ack:

```json
{"ok": true, "output_path": "/abs/path/detail.yaml", "bytes_written": 58280, "format": "yaml"}
```

**Pros**: Preserves full content; avoids MCP `structuredContent` schema-validation failures; provides a reusable pattern for other large `py_eval` outputs.
**Cons**: Requires `PyYAML` in the IDA Python environment; the target absolute path must be writable by the IDA-side process.

### Option B: Fix the IDA MCP server

The IDA MCP server should either:

1. **Not inject** truncation metadata into `structuredContent` (move it to a different response field or a separate notification), or
2. **Update** the `outputSchema` to permit these additional properties (set `additionalProperties: true` or explicitly declare the `_`-prefixed fields).

**Pros**: Fixes the problem for all clients.
**Cons**: Requires an upstream fix in the IDA MCP server.

### Option C: Pin MCP SDK version (temporary workaround)

Downgrade `mcp` to a version before `_validate_tool_result()` was introduced, bypassing the validation entirely.

```toml
# pyproject.toml
dependencies = [
    "mcp<1.25.0",
    ...
]
```

**Pros**: Immediate unblock.
**Cons**: Loses all future SDK improvements and security fixes; does not fix the underlying schema mismatch.
