[GH-ISSUE #7537] [Bug] inspect_byte_entropy omits its absolute-path requirement from the MCP request schema #4480

Open
opened 2026-10-31 00:50:10 +00:00 by bsakaguchi · 1 comment
Owner

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

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

The stdio MCP server advertises an input schema that accepts inspect_byte_entropy with {"path":"sample.bin"}, but that request returns invalid_request requiring an absolute filesystem path. The file exists in the server's working directory. Selecting the same file by its absolute path returns successful Evidence for all 512 bytes. Both compact and full input profiles exhibit this mismatch. The canonical producer and MCP request schemas also accept the relative value, so this is not solely an advertised JSON Schema conversion discrepancy.

Reproduction

  1. Use the built baseline and its installed locked dependencies with Node.js 24.22.1. From the checkout root, run the following. The fixture and server state are disposable; the SDK client is loaded from the checkout's dependencies.
node --input-type=module <<'JS'
import { Client } from '@modelcontextprotocol/client';
import { StdioClientTransport } from '@modelcontextprotocol/client/stdio';
import { Ajv2020 } from 'ajv/dist/2020.js';
import { mkdir, mkdtemp, writeFile } from 'node:fs/promises';
import { join, resolve } from 'node:path';
import { tmpdir } from 'node:os';
import { inspectByteEntropyInputSchema } from './dist/domain/native/byteEntropy.js';
import { inspectByteEntropyRequestSchema } from './dist/contracts/native/binaryDiagnosticsToolContracts.js';
const work = await mkdtemp(join(tmpdir(), 'entropy-path-'));
const cwd = join(work, 'files');
await mkdir(cwd);
await writeFile(join(cwd, 'sample.bin'), Buffer.alloc(512));
const env = { PATH: process.env.PATH, REA_LOG_LEVEL: 'silent' };
for (const key of ['HOME', 'XDG_CONFIG_HOME', 'XDG_DATA_HOME', 'XDG_CACHE_HOME', 'XDG_STATE_HOME', 'TMPDIR']) {
  env[key] = join(work, key);
  await mkdir(env[key]);
}
console.log('canonical schemas:', inspectByteEntropyInputSchema.safeParse({path: 'sample.bin'}).success,
  inspectByteEntropyRequestSchema.safeParse({path: 'sample.bin'}).success);
for (const profile of ['compact', 'full']) {
  const transport = new StdioClientTransport({ command: process.execPath,
    args: [resolve('scripts/rea.mjs'), 'mcp'], cwd,
    env: {...env, REA_MCP_INPUT_SCHEMA_PROFILE: profile}, stderr: 'pipe' });
  transport.stderr?.on('data', () => {});
  const client = new Client({name: 'entropy-path-verifier', version: '1'});
  try {
    await client.connect(transport);
    const tool = (await client.listTools()).tools.find(t => t.name === 'inspect_byte_entropy');
    const validate = new Ajv2020({strict: false, validateFormats: false}).compile(tool.inputSchema);
    console.log(profile, 'path schema:', JSON.stringify(tool.inputSchema.properties.path));
    for (const path of ['sample.bin', join(cwd, 'sample.bin')]) {
      const reply = await client.callTool({name: tool.name, arguments: {path}});
      const body = reply.structuredContent ?? JSON.parse(reply.content[0].text);
      console.log(JSON.stringify({profile, input: path === 'sample.bin' ? 'relative' : 'absolute',
        schemaValid: validate({path}), isError: reply.isError ?? false,
        code: body.error?.code ?? 'Evidence', issues: body.error?.details?.issues,
        bytes: body.normalized_result?.artifact?.bytes}));
    }
  } finally { await client.close(); }
}
JS
  1. Compare schema acceptance with the tool result. Each profile prints schemaValid:true for both requests, but only the absolute selection succeeds. The two canonical-schema checks print true true.

The initial independent verification and a reduced replay each reproduced this in both profiles. The final inline reproduction was also replayed successfully; all relative requests failed and all absolute controls succeeded.

Expected behavior

The MCP request contract should express the host-absolute path requirement already enforced by this operation, rejecting relative selections during request validation while continuing to admit absolute selections. The full-profile field guidance should state that requirement. Preserve documented relative CLI selection. The relevant owning contract, service guard, path-schema helper and existing MCP path-contract tests are identified below.

This expectation concerns a missing path-shape constraint. Schema acceptance does not promise that a file exists or that later analysis succeeds; the fixture and absolute control exclude those later conditions here.

Impact and scope

P2: a caller constructing requests from the advertised schema can send an accepted path shape that the operation refuses, requiring correction and retry. The error directs the caller to read the declared input schema or refresh tools/list, which still omits the constraint. Supplying the absolute path is a demonstrated safe practical workaround. No incorrect successful entropy result, target mutation, data loss or security-boundary crossing was observed.

Verified scope is this MCP operation, compact and full input profiles, on one macOS host. Windows and Linux execution were not tested. No external analysis provider was needed.

REA version

Exact node scripts/rea.mjs --version stdout: 6.8.0 followed by a newline.

Source baseline: 65f1c447344a423fa2785847dbcea1e9a9e2454a.

Runtime and platform

Node.js v24.22.1; macOS 27.0.1; Darwin 27.0.0; arm64. The existing built runtime and locked dependencies were used.

Target and artifact context

One generated regular file containing 512 zero bytes, read statically. The server's working directory contains the file; its HOME, XDG directories and TMPDIR are isolated.

Interface

MCP

Earliest failure stage

Request parsing or validation

Relevant output or evidence

The executed reproduction prints the following canonical check and compact path property:

canonical schemas: true true
compact path schema: {"type":"string","minLength":1,"pattern":"^[^\\x00]*$"}

The full property adds only "description":"Local filesystem path used by this operation.". Both profiles return these reduced results:

{"input":"relative","schemaValid":true,"isError":true,"code":"invalid_request","issues":[{"path":["path"],"reason":"invalid_value","message":"Expected an absolute filesystem path on this host."}]}
{"input":"absolute","schemaValid":true,"isError":false,"code":"Evidence","bytes":512}

Source evidence at the baseline:

  • src/contracts/native/binaryDiagnosticsToolContracts.ts:67-69,155-166 defines the MCP request schema and binds the named tool to it.
  • src/domain/native/byteEntropy.ts:12-25 declares the producer input; src/domain/localPath.ts:19-20 defines the nonempty, NUL-free path shape it uses. src/domain/localPath.ts:30-34 separately provides the host-absolute schema.
  • src/application/binaryDiagnostics/ByteEntropyService.ts:100-111 parses the producer schema and then refuses a relative path with the observed message.
  • tests/boundary/mcp/absoluteLocalPathSchema.test.ts:76-97 enumerates sibling standalone operations for advertised absolute-path checks, without byte entropy.
  • docs/binary-diagnostics.md:275-285 shows relative CLI input and an absolute MCP example. docs/mcp-contracts.md:1246-1308 documents specific compatibility projections that can widen advertisement; this mismatch already exists in the canonical MCP request schema.

Typed outcome or recovery expected

Reject {"path":"sample.bin"} as violating the absolute-path request constraint. The advertised schema should reject it too. Preserve the successful absolute-file control in both profiles. No repaired build was executed.

Analysis or suspected cause

Source-derived: the MCP request extends the shared producer schema only with detail, retaining a path type that permits relative values. The application service separately checks whether the path is absolute. Consequently both canonical and advertised request validation accept a value the service rejects. An MCP-specific path constraint could express the requirement while retaining CLI behavior; implementation was not attempted.

Additional context

Open #7437 reports the same defect class for five explicitly enumerated other tools. Their canonical producer schemas also accept relative values; an independent schema check and stdio Apple IPS control confirmed this. The distinguishing closure signal is the additional operation, not a different canonical-validation mechanism: PR #7449, which targets #7437, adds overlays and regression cases for those five tools but visibly leaves inspectByteEntropyRequestSchema unchanged. This conclusion comes from reading its complete diff, not executing that PR. Fixing those five tools as proposed would leave the byte-entropy request constraint absent.

Closed #5493 fixed advertisement of existing canonical absolute-path constraints. Both entropy schemas accept this relative input, so this reproduction does not establish a regression of that fixed conversion. Open #7279 concerns cleanup provider identity; open #7376 concerns CLI numeric-token syntax; closed #6482 concerns an out-of-file window diagnostic. Their fixes do not supply this missing MCP constraint. Bounded searches of open and closed issues and PRs found no report specifically covering this operation's mismatch.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: Schema-driven callers can submit a path shape accepted by both declared validators but refused by the MCP operation in both profiles, requiring a corrected request.
  • Workaround status: available
  • Workaround basis: Absolute selection of the same 512-byte file returned successful Evidence in every executed profile/control without code or configuration changes.
Originally created by @coygeek on GitHub (Oct 27, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/7537 ### 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 The stdio MCP server advertises an input schema that accepts `inspect_byte_entropy` with `{"path":"sample.bin"}`, but that request returns `invalid_request` requiring an absolute filesystem path. The file exists in the server's working directory. Selecting the same file by its absolute path returns successful Evidence for all 512 bytes. Both compact and full input profiles exhibit this mismatch. The canonical producer and MCP request schemas also accept the relative value, so this is not solely an advertised JSON Schema conversion discrepancy. ### Reproduction 1. Use the built baseline and its installed locked dependencies with Node.js 24.22.1. From the checkout root, run the following. The fixture and server state are disposable; the SDK client is loaded from the checkout's dependencies. ```sh node --input-type=module <<'JS' import { Client } from '@modelcontextprotocol/client'; import { StdioClientTransport } from '@modelcontextprotocol/client/stdio'; import { Ajv2020 } from 'ajv/dist/2020.js'; import { mkdir, mkdtemp, writeFile } from 'node:fs/promises'; import { join, resolve } from 'node:path'; import { tmpdir } from 'node:os'; import { inspectByteEntropyInputSchema } from './dist/domain/native/byteEntropy.js'; import { inspectByteEntropyRequestSchema } from './dist/contracts/native/binaryDiagnosticsToolContracts.js'; const work = await mkdtemp(join(tmpdir(), 'entropy-path-')); const cwd = join(work, 'files'); await mkdir(cwd); await writeFile(join(cwd, 'sample.bin'), Buffer.alloc(512)); const env = { PATH: process.env.PATH, REA_LOG_LEVEL: 'silent' }; for (const key of ['HOME', 'XDG_CONFIG_HOME', 'XDG_DATA_HOME', 'XDG_CACHE_HOME', 'XDG_STATE_HOME', 'TMPDIR']) { env[key] = join(work, key); await mkdir(env[key]); } console.log('canonical schemas:', inspectByteEntropyInputSchema.safeParse({path: 'sample.bin'}).success, inspectByteEntropyRequestSchema.safeParse({path: 'sample.bin'}).success); for (const profile of ['compact', 'full']) { const transport = new StdioClientTransport({ command: process.execPath, args: [resolve('scripts/rea.mjs'), 'mcp'], cwd, env: {...env, REA_MCP_INPUT_SCHEMA_PROFILE: profile}, stderr: 'pipe' }); transport.stderr?.on('data', () => {}); const client = new Client({name: 'entropy-path-verifier', version: '1'}); try { await client.connect(transport); const tool = (await client.listTools()).tools.find(t => t.name === 'inspect_byte_entropy'); const validate = new Ajv2020({strict: false, validateFormats: false}).compile(tool.inputSchema); console.log(profile, 'path schema:', JSON.stringify(tool.inputSchema.properties.path)); for (const path of ['sample.bin', join(cwd, 'sample.bin')]) { const reply = await client.callTool({name: tool.name, arguments: {path}}); const body = reply.structuredContent ?? JSON.parse(reply.content[0].text); console.log(JSON.stringify({profile, input: path === 'sample.bin' ? 'relative' : 'absolute', schemaValid: validate({path}), isError: reply.isError ?? false, code: body.error?.code ?? 'Evidence', issues: body.error?.details?.issues, bytes: body.normalized_result?.artifact?.bytes})); } } finally { await client.close(); } } JS ``` 2. Compare schema acceptance with the tool result. Each profile prints `schemaValid:true` for both requests, but only the absolute selection succeeds. The two canonical-schema checks print `true true`. The initial independent verification and a reduced replay each reproduced this in both profiles. The final inline reproduction was also replayed successfully; all relative requests failed and all absolute controls succeeded. ### Expected behavior The MCP request contract should express the host-absolute path requirement already enforced by this operation, rejecting relative selections during request validation while continuing to admit absolute selections. The full-profile field guidance should state that requirement. Preserve documented relative CLI selection. The relevant owning contract, service guard, path-schema helper and existing MCP path-contract tests are identified below. This expectation concerns a missing path-shape constraint. Schema acceptance does not promise that a file exists or that later analysis succeeds; the fixture and absolute control exclude those later conditions here. ### Impact and scope P2: a caller constructing requests from the advertised schema can send an accepted path shape that the operation refuses, requiring correction and retry. The error directs the caller to read the declared input schema or refresh `tools/list`, which still omits the constraint. Supplying the absolute path is a demonstrated safe practical workaround. No incorrect successful entropy result, target mutation, data loss or security-boundary crossing was observed. Verified scope is this MCP operation, compact and full input profiles, on one macOS host. Windows and Linux execution were not tested. No external analysis provider was needed. ### REA version Exact `node scripts/rea.mjs --version` stdout: `6.8.0` followed by a newline. Source baseline: `65f1c447344a423fa2785847dbcea1e9a9e2454a`. ### Runtime and platform Node.js `v24.22.1`; macOS `27.0.1`; Darwin `27.0.0`; `arm64`. The existing built runtime and locked dependencies were used. ### Target and artifact context One generated regular file containing 512 zero bytes, read statically. The server's working directory contains the file; its HOME, XDG directories and TMPDIR are isolated. ### Interface MCP ### Earliest failure stage Request parsing or validation ### Relevant output or evidence The executed reproduction prints the following canonical check and compact path property: ```text canonical schemas: true true compact path schema: {"type":"string","minLength":1,"pattern":"^[^\\x00]*$"} ``` The full property adds only `"description":"Local filesystem path used by this operation."`. Both profiles return these reduced results: ```json {"input":"relative","schemaValid":true,"isError":true,"code":"invalid_request","issues":[{"path":["path"],"reason":"invalid_value","message":"Expected an absolute filesystem path on this host."}]} {"input":"absolute","schemaValid":true,"isError":false,"code":"Evidence","bytes":512} ``` Source evidence at the baseline: - `src/contracts/native/binaryDiagnosticsToolContracts.ts:67-69,155-166` defines the MCP request schema and binds the named tool to it. - `src/domain/native/byteEntropy.ts:12-25` declares the producer input; `src/domain/localPath.ts:19-20` defines the nonempty, NUL-free path shape it uses. `src/domain/localPath.ts:30-34` separately provides the host-absolute schema. - `src/application/binaryDiagnostics/ByteEntropyService.ts:100-111` parses the producer schema and then refuses a relative path with the observed message. - `tests/boundary/mcp/absoluteLocalPathSchema.test.ts:76-97` enumerates sibling standalone operations for advertised absolute-path checks, without byte entropy. - `docs/binary-diagnostics.md:275-285` shows relative CLI input and an absolute MCP example. `docs/mcp-contracts.md:1246-1308` documents specific compatibility projections that can widen advertisement; this mismatch already exists in the canonical MCP request schema. ### Typed outcome or recovery expected Reject `{"path":"sample.bin"}` as violating the absolute-path request constraint. The advertised schema should reject it too. Preserve the successful absolute-file control in both profiles. No repaired build was executed. ### Analysis or suspected cause Source-derived: the MCP request extends the shared producer schema only with `detail`, retaining a path type that permits relative values. The application service separately checks whether the path is absolute. Consequently both canonical and advertised request validation accept a value the service rejects. An MCP-specific path constraint could express the requirement while retaining CLI behavior; implementation was not attempted. ### Additional context Open [#7437](https://github.com/morluto/rea/issues/7437) reports the same defect class for five explicitly enumerated other tools. Their canonical producer schemas also accept relative values; an independent schema check and stdio Apple IPS control confirmed this. The distinguishing closure signal is the additional operation, not a different canonical-validation mechanism: [PR #7449](https://github.com/morluto/rea/pull/7449), which targets #7437, adds overlays and regression cases for those five tools but visibly leaves `inspectByteEntropyRequestSchema` unchanged. This conclusion comes from reading its complete diff, not executing that PR. Fixing those five tools as proposed would leave the byte-entropy request constraint absent. Closed [#5493](https://github.com/morluto/rea/issues/5493) fixed advertisement of existing canonical absolute-path constraints. Both entropy schemas accept this relative input, so this reproduction does not establish a regression of that fixed conversion. Open [#7279](https://github.com/morluto/rea/issues/7279) concerns cleanup provider identity; open [#7376](https://github.com/morluto/rea/issues/7376) concerns CLI numeric-token syntax; closed [#6482](https://github.com/morluto/rea/issues/6482) concerns an out-of-file window diagnostic. Their fixes do not supply this missing MCP constraint. Bounded searches of open and closed issues and PRs found no report specifically covering this operation's mismatch. ## Triage assessment - Impact level: P2 - Assessment status: supported - Impact basis: Schema-driven callers can submit a path shape accepted by both declared validators but refused by the MCP operation in both profiles, requiring a corrected request. - Workaround status: available - Workaround basis: Absolute selection of the same 512-byte file returned successful Evidence in every executed profile/control without code or configuration changes.
Author
Owner

@z2Ace0107 commented on GitHub (Oct 28, 2026):

I would like to take this one.

On the direction: the report notes that the canonical producer schema and the
MCP request schema both accept a relative path while the runtime refuses it
with invalid_request. That mismatch is the defect, and I read the intended
design as the schema being wrong rather than the runtime: the CLI input helper
documents that shared MCP contracts reject relative paths and that CLI
workflows resolve operator-relative values before validation, so a relative
path is expected to fail over MCP. The advertised schema should say so, instead
of inviting an agent to send a value that cannot succeed.

My plan is therefore to constrain the advertised inspect_byte_entropy request
schema's path to an absolute local path, following the existing
absoluteLocalPathStringSchema owner in src/domain/localPath.ts that sibling
contracts already use (decompileDirectory,
applicationWorkflowInputContracts, electronToolContracts), and to keep the
description explicit about the requirement so an agent does not have to infer
it from a refusal. Both the compact and full input profiles need to agree, and
the CLI path stays unaffected because it resolves operator-relative values
before validation.

Scope: this is a schema and description correction at the existing contract
owner, not a change to what the runtime accepts. I am not relaxing the
absolute-path requirement.

I have not started implementation yet; I will post the report's own
reproduction output alongside my own before/after evidence in the pull request.

<!-- gh-comment-id:6464453142 --> @z2Ace0107 commented on GitHub (Oct 28, 2026): I would like to take this one. On the direction: the report notes that the canonical producer schema and the MCP request schema both accept a relative `path` while the runtime refuses it with `invalid_request`. That mismatch is the defect, and I read the intended design as the schema being wrong rather than the runtime: the CLI input helper documents that shared MCP contracts reject relative paths and that CLI workflows resolve operator-relative values before validation, so a relative path is expected to fail over MCP. The advertised schema should say so, instead of inviting an agent to send a value that cannot succeed. My plan is therefore to constrain the advertised `inspect_byte_entropy` request schema's `path` to an absolute local path, following the existing `absoluteLocalPathStringSchema` owner in `src/domain/localPath.ts` that sibling contracts already use (`decompileDirectory`, `applicationWorkflowInputContracts`, `electronToolContracts`), and to keep the description explicit about the requirement so an agent does not have to infer it from a refusal. Both the compact and full input profiles need to agree, and the CLI path stays unaffected because it resolves operator-relative values before validation. Scope: this is a schema and description correction at the existing contract owner, not a change to what the runtime accepts. I am not relaxing the absolute-path requirement. I have not started implementation yet; I will post the report's own reproduction output alongside my own before/after evidence in the pull request.
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#4480
No description provided.