Skip to content

fix(mcp): native reflection gaps and an honest job status - #11

Merged
mrmx merged 2 commits into
mainfrom
api-feedback-mcp-fixes
Oct 24, 2026
Merged

mrmx merged 2 commits into
mainfrom
api-feedback-mcp-fixes

Conversation

@mrmx

@mrmx mrmx commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

What

Three bugs reported against the MCP server by an external user, each reproduced against the released 0.20.0 / 0.21.0 binaries.

  • list_exchanges failed with a bare HTTP 0 on the native binary. segments and liveSegments are the only uniqueItems arrays of the API contract, so they are the only Set fields. Jackson fills a Set with a HashSet it builds reflectively, and that class was not in reflect-config.json. Every other collection is a List, which is why nothing else broke. HashSet and LinkedHashSet are now registered.
  • get_dataset_import answered "Dataset import not found" for every finished import. DatasetImportState was registered but the DatasetVersion it holds was not, and getDatasetImport turned any RuntimeException into "not found". The type is registered and the exception is no longer swallowed: the tool reports the cause.
  • get_job_status reported a failed run as COMPLETED. The await future was consumed with exceptionally(), which lets the derived future complete normally, and the status read "done" as completed. The failure is now recorded and decides the status first (FAILED, or CANCELED for a cancellation), and the platform's reason is shown as Detail, both for runs submitted by this server and for runs read by exchangeId.

ReflectConfigTest also walks the fields and member types of every pinned type now (before, only the return types of BacktestingService were walked). That found eight more unregistered types (the enums of Dataset and DatasetVersion, EquityCurveOptions, EquityCurveRequest and its mode enum), which are added. It also requires HashSet/LinkedHashSet whenever a serialized type holds a Set.

Not in this PR

  • submit_backtest still cannot request a kline run. BacktestRequest in sdk-java has no type and its workflow fixes ticker, so that needs a change and a release there first. Meanwhile the tool description and README say so, and a kline strategy over a dataset now ends FAILED with the platform's reason instead of looking successful.
  • No version bump and no release notes beyond an [Unreleased] entry in the changelog.

Verification

  • mvn verify (unit tests and the stub integration test) passes: 136 tests, including new tests for the status rule, the Detail rendering, the error propagation of get_dataset_import, and the extended reflection checks.
  • The native image was not built or run for this change. The reflection registrations are checked by name, not by behaviour. The native job only runs on a tag, so the fix for the first two bugs is to be confirmed on the next native build, replaying the reproductions from the issues (list_exchanges, and get_dataset_import on a finished import).

mrmx added 2 commits October 24, 2026 14:43
list_exchanges failed with a bare "HTTP 0" and get_dataset_import answered "Dataset import not
found" for every finished import, on the native binary only.

- The API's segments and liveSegments are the only uniqueItems arrays of the contract, so they are
  the only Set fields; Jackson fills a Set with a HashSet it builds reflectively, and that was not
  registered. Every other collection is a List, which is why nothing else broke.
- DatasetImportState was pinned in ReflectConfigTest but the DatasetVersion it holds was not, so
  its version could not be read and the exception surfaced as "not found".

ReflectConfigTest now also walks the fields and member types of every pinned type, which found
eight more unregistered types (the enums of Dataset and DatasetVersion, EquityCurveOptions and
EquityCurveRequest), and requires HashSet/LinkedHashSet whenever a serialized type holds a Set.

The JVM suite cannot run the native image: the registration is checked by name, and the behaviour
is to be confirmed on the next tagged native build.

Refs api-feedback#66, api-feedback#67.
…a read failed

The await future was consumed with exceptionally(), which logs the failure and lets the derived
future complete normally. SessionJob.status() then read "done" as COMPLETED, so a run whose
preparation the platform rejected showed COMPLETED on every poll with no results behind it.

- The failure is now recorded and decides the status first (FAILED, or CANCELED for a
  cancellation). get_job_status shows the platform's reason as Detail, for runs submitted by this
  server and for runs read off the platform by exchangeId. The status rule is a pure function so
  it can be tested without a platform.
- getDatasetImport no longer swallows every RuntimeException into "not found"; the tool reports
  the cause.
- submit_backtest and the README no longer imply a kline run can be requested. The SDK's
  BacktestRequest has no type yet, so a dataset run still prepares ticker data; it now fails
  visibly instead of looking successful. Adding `type` needs sdk-java first.

Refs api-feedback#67, api-feedback#68.
@mrmx
mrmx marked this pull request as ready for review October 24, 2026 15:18
@mrmx
mrmx merged commit 9f92d53 into main Oct 24, 2026
5 checks passed
@mrmx
mrmx deleted the api-feedback-mcp-fixes branch October 24, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant