[PR #6421] [CLOSED] fix(ida): read native metadata with an omitted or variant JSON media type #7348

Closed
opened 2026-11-01 21:47:13 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/6421
Author: @viniciusdsandrade
Created: 10/23/2026
Status: ❌ Closed

Base: main ← Head: fix/5823-ida-native-metadata-json-media-type


📝 Commits (2)

  • 257bc56 fix(ida): read native metadata with an omitted or variant JSON media type
  • bda746d test(ida): read native metadata across JSON media type declarations

📊 Changes

2 files changed (+46 additions, -2 deletions)

View changed files

📝 src/ida/IdaMcpConnection.ts (+15 -1)
📝 tests/boundary/mcp/idaTransport.test.ts (+31 -1)

📄 Description

Summary

Fixes #5823

In the native attached profile, REA reads ida://idb/metadata through resources/read before health and every admitted operation. The connection required each resource entry to declare exactly mimeType: "application/json". MCP leaves mimeType optional and media type tokens are case-insensitive, so a reply that omitted the declaration, or declared application/json; charset=utf-8 or Application/JSON, failed with unreadable_output at contents.0.mimeType before the recorded identity was examined, although the pinned SDK accepted the reply.

A declared media type is now parsed with the connection's existing RFC 9110 parser (parseIdaContentType) and admitted when its essence is application/json. An omitted declaration is admitted. Malformed, ambiguous and non-JSON declarations keep failing, and JSON parsing and the target identity checks are unchanged.

Problem and expected behavior

  • Smallest trigger: a native IDA MCP server whose resources/read reply for ida://idb/metadata carries valid metadata JSON with mimeType omitted, application/json; charset=utf-8 or Application/JSON.
  • Violated invariant: docs/ida-provider.md requires resources/read for ida://idb/metadata and its recorded input SHA-256, not an exact media-type spelling, and the boundary rules ask for format-aware normalization at the owning boundary.
  • Expected: these replies yield the same metadata as the bare application/json control; malformed JSON and identity mismatches still fail.

Change and scope

  • src/ida/IdaMcpConnection.ts: mimeType in the readResource schema is optional and, when present, must have the essence application/json according to parseIdaContentType, the parser this module already owns for HTTP error bodies. Parameters are ignored because the resource text is a string that MCP already delivered decoded; RFC 8259 defines no parameters for application/json. src/server/environment/stateIntake.ts applies the same rule (omitted, or essence application/json) to JSON file parts.
  • tests/boundary/mcp/idaTransport.test.ts: the transport fixture gains a resourceMimeType option (null omits it; the default stays application/json). New cases read metadata for the omitted, parameterized and case-variant declarations, and reject text/plain, application/vnd.ida+json and the malformed application/json; charset at contents.0.mimeType.
  • Not included: accepting +json structured-suffix resources or any non-JSON type, which the issue explicitly leaves out.

Follow the contribution scope.
Scope decision: not applicable (ordinary compatibility fix within the existing read-only IDA adapter).

Contract and boundary impact

  • Semantic owner and earliest changed stage: readResource in src/ida/IdaMcpConnection.ts, the parser of native metadata resource replies.
  • Contribution scope fit and linked maintainer decision: not applicable.
  • CLI and MCP/tool-catalog contract: schemas unchanged. Native IDA health and operations no longer fail on an omitted, parameterized or case-variant JSON declaration.
  • Provider, bridge, target-format, or platform compatibility: native attached IDA MCP over stdio or Streamable HTTP. Legacy and headless profiles do not read this resource and are unchanged.
  • Evidence, artifact, provenance, or reconstruction contract: unchanged; the metadata is parsed and bound to the target exactly as before.
  • Target selection, authority, upstream behavior, and cleanup details (if applicable): identity checks (sha256, path, image base) are unchanged.
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact: none.

Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated: reads native metadata whose optional media type is %s and rejects native metadata declared as %s in tests/boundary/mcp/idaTransport.test.ts, through the pinned SDK client and a loopback Streamable HTTP fixture.
  • Base reproduction or other evidence: source-derived. On the base revision z.literal("application/json") rejects the three accepted cases, so readResource throws and the new read cases fail. The issue reports the same unreadable_output at contents.0.mimeType for health and procedure_pseudo_code through the production session client, with the bare control succeeding.
  • User-visible CLI/MCP output (if applicable): for those replies, health and pseudocode now return their normal metadata-backed results instead of unreadable_output; not replayed here.
  • Remaining proof gaps: no IDA engine or released native plugin was run; whether a released plugin emits these declarations is unknown, as the issue states.

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

  • No local test, build or typecheck commands were run; verification is source-derived and CI executes the test suite. The repository pre-commit hook ran oxlint --fix and oxfmt on the staged files; oxfmt adjusted the layout of the new test cases only.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. Previously accepted replies are still accepted.
  • Real Hopper/Ghidra, browser, or OS coverage: none run.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: the metadata text is still parsed strictly as JSON and must match the selected target's recorded identity; only the media type declaration became tolerant of omission, parameters and case.

Author readiness

Human owner: @viniciusdsandrade

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/6421 **Author:** [@viniciusdsandrade](https://github.com/viniciusdsandrade) **Created:** 10/23/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/5823-ida-native-metadata-json-media-type` --- ### 📝 Commits (2) - [`257bc56`](https://github.com/morluto/rea/commit/257bc56d9e2a780cf09ffacd654456a87f898f5d) fix(ida): read native metadata with an omitted or variant JSON media type - [`bda746d`](https://github.com/morluto/rea/commit/bda746d9c9f9319ab25863b3ed865c0e86c40a77) test(ida): read native metadata across JSON media type declarations ### 📊 Changes **2 files changed** (+46 additions, -2 deletions) <details> <summary>View changed files</summary> 📝 `src/ida/IdaMcpConnection.ts` (+15 -1) 📝 `tests/boundary/mcp/idaTransport.test.ts` (+31 -1) </details> ### 📄 Description ## Summary Fixes #5823 In the native attached profile, REA reads `ida://idb/metadata` through `resources/read` before health and every admitted operation. The connection required each resource entry to declare exactly `mimeType: "application/json"`. MCP leaves `mimeType` optional and media type tokens are case-insensitive, so a reply that omitted the declaration, or declared `application/json; charset=utf-8` or `Application/JSON`, failed with `unreadable_output` at `contents.0.mimeType` before the recorded identity was examined, although the pinned SDK accepted the reply. A declared media type is now parsed with the connection's existing RFC 9110 parser (`parseIdaContentType`) and admitted when its essence is `application/json`. An omitted declaration is admitted. Malformed, ambiguous and non-JSON declarations keep failing, and JSON parsing and the target identity checks are unchanged. ## Problem and expected behavior - Smallest trigger: a native IDA MCP server whose `resources/read` reply for `ida://idb/metadata` carries valid metadata JSON with `mimeType` omitted, `application/json; charset=utf-8` or `Application/JSON`. - Violated invariant: [docs/ida-provider.md](https://github.com/morluto/rea/blob/main/docs/ida-provider.md) requires `resources/read` for `ida://idb/metadata` and its recorded input SHA-256, not an exact media-type spelling, and the boundary rules ask for format-aware normalization at the owning boundary. - Expected: these replies yield the same metadata as the bare `application/json` control; malformed JSON and identity mismatches still fail. ## Change and scope - `src/ida/IdaMcpConnection.ts`: `mimeType` in the `readResource` schema is optional and, when present, must have the essence `application/json` according to `parseIdaContentType`, the parser this module already owns for HTTP error bodies. Parameters are ignored because the resource `text` is a string that MCP already delivered decoded; RFC 8259 defines no parameters for `application/json`. `src/server/environment/stateIntake.ts` applies the same rule (omitted, or essence `application/json`) to JSON file parts. - `tests/boundary/mcp/idaTransport.test.ts`: the transport fixture gains a `resourceMimeType` option (`null` omits it; the default stays `application/json`). New cases read metadata for the omitted, parameterized and case-variant declarations, and reject `text/plain`, `application/vnd.ida+json` and the malformed `application/json; charset` at `contents.0.mimeType`. - Not included: accepting `+json` structured-suffix resources or any non-JSON type, which the issue explicitly leaves out. Follow the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope). Scope decision: not applicable (ordinary compatibility fix within the existing read-only IDA adapter). ## Contract and boundary impact - Semantic owner and earliest changed stage: `readResource` in `src/ida/IdaMcpConnection.ts`, the parser of native metadata resource replies. - Contribution scope fit and linked maintainer decision: not applicable. - CLI and MCP/tool-catalog contract: schemas unchanged. Native IDA health and operations no longer fail on an omitted, parameterized or case-variant JSON declaration. - Provider, bridge, target-format, or platform compatibility: native attached IDA MCP over stdio or Streamable HTTP. Legacy and headless profiles do not read this resource and are unchanged. - Evidence, artifact, provenance, or reconstruction contract: unchanged; the metadata is parsed and bound to the target exactly as before. - Target selection, authority, upstream behavior, and cleanup details (if applicable): identity checks (`sha256`, path, image base) are unchanged. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact: none. Expected effects (check known effects; use documentation-only on its own). Unchecked items do not establish absence; leave uncertainties visible. - [x] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: `reads native metadata whose optional media type is %s` and `rejects native metadata declared as %s` in `tests/boundary/mcp/idaTransport.test.ts`, through the pinned SDK client and a loopback Streamable HTTP fixture. - Base reproduction or other evidence: source-derived. On the base revision `z.literal("application/json")` rejects the three accepted cases, so `readResource` throws and the new read cases fail. The issue reports the same `unreadable_output` at `contents.0.mimeType` for health and `procedure_pseudo_code` through the production session client, with the bare control succeeding. - User-visible CLI/MCP output (if applicable): for those replies, health and pseudocode now return their normal metadata-backed results instead of `unreadable_output`; not replayed here. - Remaining proof gaps: no IDA engine or released native plugin was run; whether a released plugin emits these declarations is unknown, as the issue states. For evidence-bearing changes: - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed - No local test, build or typecheck commands were run; verification is source-derived and CI executes the test suite. The repository pre-commit hook ran `oxlint --fix` and `oxfmt` on the staged files; `oxfmt` adjusted the layout of the new test cases only. ## Compatibility, safety, and release - Breaking changes or migration steps: none. Previously accepted replies are still accepted. - Real Hopper/Ghidra, browser, or OS coverage: none run. - Package or release metadata impact: none. - Security, privacy, process, or containment review: the metadata text is still parsed strictly as JSON and must match the selected target's recorded identity; only the media type declaration became tolerant of omission, parameters and case. ## Author readiness Human owner: @viniciusdsandrade - [ ] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [ ] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [ ] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-01 21:47:13 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#7348
No description provided.