[GH-ISSUE #5088] [Bug] inspect_evm_interface loses detail field guidance and advertised default #3126

Closed
opened 2026-10-31 00:36:55 +00:00 by bsakaguchi · 2 comments
Owner

Originally created by @coygeek on GitHub (Oct 18, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/5088

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

MCP or agent integration

Observed behavior

Production EVM tool registration followed by an in-memory MCP SDK tools/list request advertises detail as only {"type":"string","enum":["complete","summary"]}. Its shared field description and default: "complete" are absent. A sibling capture contract retains both annotations through the same SDK registration path.

This is an observed discovery-boundary result with an inert injected provider. No analysis request or real provider execution occurred.

Reproduction

From a source checkout at the revision below with locked dependencies installed, run this reduced probe. It was executed successfully; the injected provider receives zero calls.

WORK=$(mktemp -d)
mkdir -p "$WORK/home" "$WORK/config" "$WORK/cache"
env -i PATH="$PATH" HOME="$WORK/home" XDG_CONFIG_HOME="$WORK/config" XDG_CACHE_HOME="$WORK/cache" node --import tsx --input-type=module <<'JS'
import { Client, InMemoryTransport } from '@modelcontextprotocol/client';
import { EvidenceMcpServer } from './src/server/EvidenceMcpServer.ts';
import { createToolResultDelivery } from './src/server/toolResult.ts';
import { registerEvmTools } from './src/server/registerEvmTools.ts';
import { EvmInterfaceService } from './src/application/evm/EvmInterfaceService.ts';
import { silentLogger } from './src/logger.ts';
let providerCalls = 0;
const server = new EvidenceMcpServer({name:'schema-probe',version:'1'}, {}, undefined, createToolResultDelivery(undefined));
registerEvmTools(server, new EvmInterfaceService({inspect:async()=>{providerCalls++;throw new Error('not expected');}}), silentLogger);
const client = new Client({name:'schema-probe',version:'1'});
const [a,b] = InMemoryTransport.createLinkedPair();
try {
 await server.connect(b); await client.connect(a);
 const tool = (await client.listTools()).tools.find(t=>t.name==='inspect_evm_interface');
 console.log(JSON.stringify({detail:tool.inputSchema.properties.detail, providerCalls}));
} finally {await client.close();await server.close();}
JS

Expected behavior

Preserve the shared field guidance and effective complete default in the advertised EVM detail property. The owning analysisDetailSchema defines both annotations; the capture sibling preserves them. The schema advertisement contract says input descriptions are retained.

Impact and scope

Field-level help and default metadata are missing for callers consuming EVM input schemas. The enum and tool-level prose still expose the choices, including omitted/complete behavior. No analysis-result change, blocked request, or evidence loss was observed. Actual host rendering and user incident frequency: NOT_ENOUGH_INFO. The verified impact is limited to discovery wording/metadata.

REA version

Source SHA 3537e58c1ab29309f06eabf50bc52adba9817a0c, package manifest 6.7.0. Runtime probe used this source checkout, not an installed package.

Runtime and platform

Node v26.12.0; macOS (darwin) arm64. No external provider or chain service used.

Target and artifact context

Not applicable; discovery-only request, no bytecode artifact.

Interface

MCP

Earliest failure stage

Transport or result projection

Relevant output or evidence

The reduced probe returned:

{"detail":{"type":"string","enum":["complete","summary"]},"providerCalls":0}

A separate SDK discovery control registered inspect_web_network_capture using its production contract and registration options; its detail retained default: "complete" and the shared description. This distinguishes EVM schema construction from blanket SDK annotation removal.

The EVM contract unwraps the shared schema and makes its inner enum optional. Production registration passes that contract to the standard metadata projection.

Typed outcome or recovery expected

An advertised optional detail field with its complete/summary explanation and effective default. Reading the existing tool-level description remains an available way to discover the choices.

Analysis or suspected cause

Source-derived cause: .unwrap().optional() removes the wrapper carrying the shared annotations before advertisement. The observed SDK output confirms that later registration does not restore them. The handler branches only on explicit summary; no change in analysis behavior is claimed.

Additional context

Related historical policy: #265, covering an older 84-tool catalog. This EVM field was introduced later in retained EVM summary delivery. No matching report for this new field was found in the supplied complete open/closed issue snapshot.

Relevant source files are unchanged between tag rea-agents-6.7.0 and the tested revision. Stable packaged runtime, compact-schema mode, actual host rendering, and real EVM analysis were not tested.

Freshness review against 29910d16b98fe4b607a7aa15928789a73614b0b9: the EVM detail construction, shared detail schema and production advertisement path remain unchanged. The schema advertisement policy also remains unchanged; only its line numbers moved. This is a source freshness check, not a new SDK or provider runtime reproduction. The original tested SHA and runtime scope above remain unchanged.

Originally created by @coygeek on GitHub (Oct 18, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5088 ## Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ## Area MCP or agent integration ## Observed behavior Production EVM tool registration followed by an in-memory MCP SDK `tools/list` request advertises `detail` as only `{"type":"string","enum":["complete","summary"]}`. Its shared field description and `default: "complete"` are absent. A sibling capture contract retains both annotations through the same SDK registration path. This is an observed discovery-boundary result with an inert injected provider. No analysis request or real provider execution occurred. ## Reproduction From a source checkout at the revision below with locked dependencies installed, run this reduced probe. It was executed successfully; the injected provider receives zero calls. ```sh WORK=$(mktemp -d) mkdir -p "$WORK/home" "$WORK/config" "$WORK/cache" env -i PATH="$PATH" HOME="$WORK/home" XDG_CONFIG_HOME="$WORK/config" XDG_CACHE_HOME="$WORK/cache" node --import tsx --input-type=module <<'JS' import { Client, InMemoryTransport } from '@modelcontextprotocol/client'; import { EvidenceMcpServer } from './src/server/EvidenceMcpServer.ts'; import { createToolResultDelivery } from './src/server/toolResult.ts'; import { registerEvmTools } from './src/server/registerEvmTools.ts'; import { EvmInterfaceService } from './src/application/evm/EvmInterfaceService.ts'; import { silentLogger } from './src/logger.ts'; let providerCalls = 0; const server = new EvidenceMcpServer({name:'schema-probe',version:'1'}, {}, undefined, createToolResultDelivery(undefined)); registerEvmTools(server, new EvmInterfaceService({inspect:async()=>{providerCalls++;throw new Error('not expected');}}), silentLogger); const client = new Client({name:'schema-probe',version:'1'}); const [a,b] = InMemoryTransport.createLinkedPair(); try { await server.connect(b); await client.connect(a); const tool = (await client.listTools()).tools.find(t=>t.name==='inspect_evm_interface'); console.log(JSON.stringify({detail:tool.inputSchema.properties.detail, providerCalls})); } finally {await client.close();await server.close();} JS ``` ## Expected behavior Preserve the shared field guidance and effective complete default in the advertised EVM `detail` property. The [owning analysisDetailSchema](https://github.com/morluto/rea/blob/3537e58c1ab29309f06eabf50bc52adba9817a0c/src/contracts/analysisDetail.ts#L5-L11) defines both annotations; the [capture sibling](https://github.com/morluto/rea/blob/3537e58c1ab29309f06eabf50bc52adba9817a0c/src/contracts/webNetworkCaptureToolContracts.ts#L21-L23) preserves them. The [schema advertisement contract](https://github.com/morluto/rea/blob/3537e58c1ab29309f06eabf50bc52adba9817a0c/docs/mcp-contracts.md#L723-L731) says input descriptions are retained. ## Impact and scope Field-level help and default metadata are missing for callers consuming EVM input schemas. The enum and tool-level prose still expose the choices, including omitted/complete behavior. No analysis-result change, blocked request, or evidence loss was observed. Actual host rendering and user incident frequency: NOT_ENOUGH_INFO. The verified impact is limited to discovery wording/metadata. ## REA version Source SHA `3537e58c1ab29309f06eabf50bc52adba9817a0c`, package manifest 6.7.0. Runtime probe used this source checkout, not an installed package. ## Runtime and platform Node v26.12.0; macOS (`darwin`) arm64. No external provider or chain service used. ## Target and artifact context Not applicable; discovery-only request, no bytecode artifact. ## Interface MCP ## Earliest failure stage Transport or result projection ## Relevant output or evidence The reduced probe returned: ```json {"detail":{"type":"string","enum":["complete","summary"]},"providerCalls":0} ``` A separate SDK discovery control registered `inspect_web_network_capture` using its production contract and registration options; its `detail` retained `default: "complete"` and the shared description. This distinguishes EVM schema construction from blanket SDK annotation removal. The [EVM contract](https://github.com/morluto/rea/blob/3537e58c1ab29309f06eabf50bc52adba9817a0c/src/contracts/evm/evmToolContracts.ts#L13-L18) unwraps the shared schema and makes its inner enum optional. [Production registration](https://github.com/morluto/rea/blob/3537e58c1ab29309f06eabf50bc52adba9817a0c/src/server/registerEvmTools.ts#L56-L59) passes that contract to the standard metadata projection. ## Typed outcome or recovery expected An advertised optional `detail` field with its complete/summary explanation and effective default. Reading the existing tool-level description remains an available way to discover the choices. ## Analysis or suspected cause Source-derived cause: `.unwrap().optional()` removes the wrapper carrying the shared annotations before advertisement. The observed SDK output confirms that later registration does not restore them. The [handler](https://github.com/morluto/rea/blob/3537e58c1ab29309f06eabf50bc52adba9817a0c/src/server/registerEvmTools.ts#L41-L50) branches only on explicit summary; no change in analysis behavior is claimed. ## Additional context Related historical policy: [#265](https://github.com/morluto/rea/issues/265), covering an older 84-tool catalog. This EVM field was introduced later in [retained EVM summary delivery](https://github.com/morluto/rea/commit/f76163c2467db623f9de0bda757c9d8610ca9565). No matching report for this new field was found in the supplied complete open/closed issue snapshot. Relevant source files are unchanged between tag `rea-agents-6.7.0` and the tested revision. Stable packaged runtime, compact-schema mode, actual host rendering, and real EVM analysis were not tested. Freshness review against `29910d16b98fe4b607a7aa15928789a73614b0b9`: the [EVM detail construction](https://github.com/morluto/rea/blob/29910d16b98fe4b607a7aa15928789a73614b0b9/src/contracts/evm/evmToolContracts.ts#L13-L18), shared detail schema and production advertisement path remain unchanged. The [schema advertisement policy](https://github.com/morluto/rea/blob/29910d16b98fe4b607a7aa15928789a73614b0b9/docs/mcp-contracts.md#L733-L761) also remains unchanged; only its line numbers moved. This is a source freshness check, not a new SDK or provider runtime reproduction. The original tested SHA and runtime scope above remain unchanged.
Author
Owner

@xu91102 commented on GitHub (Oct 19, 2026):

I independently reproduced the discovery metadata loss on fresh captured main d6ca7b3f20a273823c50d6253f0b6f34f3876f53 using the actual built scripts/rea.mjs mcp stdio entrypoint and official MCP SDK Client (macOS arm64, pinned Node24.18.0). This used isolated homes/config/cache, with no injected provider and no analysis tool calls.

Two real server sessions completed initialize/tools-list and then closed:

  • REA_MCP_INPUT_SCHEMA_PROFILE=full: all207 tools listed. EVM detail advertised only string/complete/summary; both default and description were absent. The same actual response's inspect_web_network_capture.detail retained default: complete and the full shared description.
  • compact: both fields intentionally advertise only the enum/type. This is the configured compact presentation and is not claimed as a defect.

All five relevant source/entrypoint byte hashes remained unchanged; both owned server PIDs settled. The first probe incorrectly imposed the full-profile control on compact and stopped with a harness assertion; that diagnostic/raw output is retained, and the corrected two-session run above completed. This is a discovery-annotation issue only. No EVM bytecode/engine/chain operation, host/model schema rendering, installed-release or Windows/Linux qualification is claimed.

I read the actual relevant production diffs of the related search results before selecting this root: open #3024 changes Solidity carrier input/prose, not detail annotation preservation; merged #2308 introduced the current unwrap/optional field and #1051 introduced the EVM tool. The other matching PRs do not modify the owning detail/schema registration paths. I am investigating a minimal change at that existing shared-contract boundary; no implementation, upstream PR or CI result is claimed for this issue yet.

Verified local fix and publication status

The shared detail schema is now reused directly in my fork 16c224b381e16121620d5a897a219b2a7a6bb251. The existing MCP/composition regressions pass13 tests; fresh README5 makes18 distinct tests. Full check/docs/discovery/package and explicit pack pass. Actual compiled and installed full/compact stdio discovery matches the intended shared metadata; all207-tool compact catalog bytes remain unchanged, with no analysis tool calls. The tarball and1791 installed package files match. Both independent source-review axes pass.

A normal upstream Draft creation was attempted once and GitHub rejected CreatePullRequest permissions. There is no upstream PR or CI for this fix yet. This does not establish a particular limit or policy, and the fork commit is not counted as a submitted upstream PR. Full native EVM/bytecode, chain/RPC, model/host rendering, Windows/Linux hosts and performance were not run.

Same-core contribution now held

I have now read the complete actual two-file diff of PR5157, head 9df70f0ad63bbd445dadd3ea806dcbc45eb7bc24, by AdityaKharmaleGoat7. Its production change uses the same canonical detail schema at the same EVM contract owner. I am holding my fork branch read-only rather than publishing a duplicate fix. The last readback shows that PR OPEN and unmerged; I did not run its head or establish source adoption/author credit. My local verification remains limited to my own frozen inputs; I have no upstream PR or CI for this issue.

<!-- gh-comment-id:6257782750 --> @xu91102 commented on GitHub (Oct 19, 2026): I independently reproduced the discovery metadata loss on fresh captured main `d6ca7b3f20a273823c50d6253f0b6f34f3876f53` using the actual built `scripts/rea.mjs mcp` stdio entrypoint and official MCP SDK Client (macOS arm64, pinned Node24.18.0). This used isolated homes/config/cache, with no injected provider and no analysis tool calls. Two real server sessions completed initialize/tools-list and then closed: - `REA_MCP_INPUT_SCHEMA_PROFILE=full`: all207 tools listed. EVM `detail` advertised only string/complete/summary; both default and description were absent. The same actual response's `inspect_web_network_capture.detail` retained `default: complete` and the full shared description. - `compact`: both fields intentionally advertise only the enum/type. This is the configured compact presentation and is not claimed as a defect. All five relevant source/entrypoint byte hashes remained unchanged; both owned server PIDs settled. The first probe incorrectly imposed the full-profile control on compact and stopped with a harness assertion; that diagnostic/raw output is retained, and the corrected two-session run above completed. This is a discovery-annotation issue only. No EVM bytecode/engine/chain operation, host/model schema rendering, installed-release or Windows/Linux qualification is claimed. I read the actual relevant production diffs of the related search results before selecting this root: open #3024 changes Solidity carrier input/prose, not detail annotation preservation; merged #2308 introduced the current unwrap/optional field and #1051 introduced the EVM tool. The other matching PRs do not modify the owning detail/schema registration paths. I am investigating a minimal change at that existing shared-contract boundary; no implementation, upstream PR or CI result is claimed for this issue yet. ### Verified local fix and publication status The shared detail schema is now reused directly in my fork [16c224b381e16121620d5a897a219b2a7a6bb251](https://github.com/xu91102/rea/commit/16c224b381e16121620d5a897a219b2a7a6bb251). The existing MCP/composition regressions pass13 tests; fresh README5 makes18 distinct tests. Full check/docs/discovery/package and explicit pack pass. Actual compiled and installed full/compact stdio discovery matches the intended shared metadata; all207-tool compact catalog bytes remain unchanged, with no analysis tool calls. The tarball and1791 installed package files match. Both independent source-review axes pass. A normal upstream Draft creation was attempted once and GitHub rejected CreatePullRequest permissions. There is no upstream PR or CI for this fix yet. This does not establish a particular limit or policy, and the fork commit is not counted as a submitted upstream PR. Full native EVM/bytecode, chain/RPC, model/host rendering, Windows/Linux hosts and performance were not run. ### Same-core contribution now held I have now read the complete actual two-file diff of [PR5157](https://github.com/morluto/rea/pull/5157), head `9df70f0ad63bbd445dadd3ea806dcbc45eb7bc24`, by AdityaKharmaleGoat7. Its production change uses the same canonical detail schema at the same EVM contract owner. I am holding my fork branch read-only rather than publishing a duplicate fix. The last readback shows that PR OPEN and unmerged; I did not run its head or establish source adoption/author credit. My local verification remains limited to my own frozen inputs; I have no upstream PR or CI for this issue.
Author
Owner

@coygeek commented on GitHub (Oct 24, 2026):

Checked the reported fix on main at d87e73f2db.

EVM detail now directly reuses analysisDetailSchema instead of unwrap().optional(), preserving complete/summary guidance and default complete. The actual in-memory SDK discovery regression registers only the production EVM path, requests the advertised schema, asserts the exact detail type/enum/default plus the shared description substring, and asserts zero provider calls. This matches the original discovery-only trigger and avoids conflating compact-profile metadata removal with the reported full-profile defect.

Implementation: evmToolContracts.ts, analysisDetail.ts.

The relevant regression checks in evmInterfaceMcp.test.ts passed in the focused test run on this revision. This closure is based on the current source and those checks; provider fixtures do not establish a real-engine run. Closing as completed on main.

<!-- gh-comment-id:6380708008 --> @coygeek commented on GitHub (Oct 24, 2026): Checked the reported fix on `main` at d87e73f2db50be72d33a4b3c7199af35518b441c. EVM detail now directly reuses analysisDetailSchema instead of unwrap().optional(), preserving complete/summary guidance and default complete. The actual in-memory SDK discovery regression registers only the production EVM path, requests the advertised schema, asserts the exact detail type/enum/default plus the shared description substring, and asserts zero provider calls. This matches the original discovery-only trigger and avoids conflating compact-profile metadata removal with the reported full-profile defect. Implementation: [evmToolContracts.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/contracts/evm/evmToolContracts.ts#L14), [analysisDetail.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/src/contracts/analysisDetail.ts#L5). The relevant regression checks in [evmInterfaceMcp.test.ts](https://github.com/morluto/rea/blob/d87e73f2db50be72d33a4b3c7199af35518b441c/tests/boundary/mcp/evmInterfaceMcp.test.ts) passed in the focused test run on this revision. This closure is based on the current source and those checks; provider fixtures do not establish a real-engine run. Closing as completed on main.
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#3126
No description provided.