Skip to content

Latest commit

 

History

History
147 lines (104 loc) · 10.5 KB

CHANGELOG.md

File metadata and controls

147 lines (104 loc) · 10.5 KB

Changelog

All notable changes to com.qtsurfer:mcp-java are documented here.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

[0.7.1] — 2026-07-27

Changed 🔄

  • Bumped com.qtsurfer:sdk to 0.8.1, which fixes the execute poll ending early when the API answers 202 — the status it returns when a job is known but its result is not readable yet. Nothing in this repo changed: the SDK's Backtest abstraction absorbs that distinction, so a backtest driven through the MCP tools could previously report an empty result for a run that had actually completed, and now polls until the result is readable.

Changed 🔄

  • Bumped com.qtsurfer:sdk-java to 0.8.0 (API spec 0.99.1, 16 operationId renames — no request/response shape, field, or endpoint changes). sdk-java's own entry point is renamed as part of that: QTSurfer.auth(...) → QTSurfer.authenticate(...). Updated the server's single auth-mint call site (Main.authenticate(...), internal) accordingly. No change to any MCP tool's input or output contract.
  • Registered the renamed generated model classes in the GraalVM reflect-config.json (CancelExecution200Response→CancelBacktest200Response, GetStrategyStatus200Response→GetStrategy200Response, PostStrategy200Response→CompileStrategy200Response, ExecuteBacktestingRequest→ExecuteBacktestRequest, PrepareBacktestingRequest→PrepareRequest, plus their nested enums) so the native binary keeps deserializing/instantiating these types after the rename.

[0.6.0] — 2026-07-11

Changed 🔄

  • Bumped com.qtsurfer:sdk-java to 0.7.0 (API spec 0.98.0). The single-instrument preparation endpoint now returns PrepareJobState (with coverageRatio and a per-hour coverage breakdown), and Partial is gone from the job status enum. No change to any MCP tool's input or output contract.
  • Registered PrepareJobState (and its nested coverage types) in the GraalVM reflect-config.json so the native binary can deserialize the new preparation-status response.

[0.5.0] — 2026-07-10

Changed 🔄

  • Bumped com.qtsurfer:sdk-java to 0.6.1 (API spec 0.97.0). InstrumentDetail replaced its flat dataFrom/dataTo fields with per-data-type coverage, so the list_instruments tool now derives each instrument's data: <from> → <to> window from coverage (preferring the tickers window, falling back to klines, and omitting the suffix when unavailable). No change to the tool's input or output contract.

[0.4.0] — 2026-06-16

Added ✨

  • Equity curve access — backtest results now expose the equity curve, which was previously fetched from the backend but silently discarded by the MCP layer.
    • New get_equity_curve tool returns the curve of a COMPLETED job as compact JSON (parallel arrays t[] = epoch-millis timestamps, equity[] = account equity). Curves longer than maxPoints (default 500, max 5000) are downsampled, always preserving the first/last points and the global min and max (worst drawdown and peak).
    • get_job_status gains an optional includeEquityCurve flag (default false) that appends the curve, downsampled to ~200 points, to the status summary.

[0.3.3] — 2026-06-13

Fixed 🐛

  • Native binary was non-functional beyond --help — root cause of the auth() failed: HTTP 0 errors finally identified: it was never TLS. GraalVM native images need reflection metadata for every Jackson-(de)serialized type; without it, deserializing the auth response throws InvalidDefinitionException (an IOException subclass), which the OpenAPI client wraps as ApiException with code 0. The MCP layer was equally broken: McpSchema record components were not registered, so even a stdio initialize crashed with UnsupportedFeatureError.
    • Added reflect-config.json generated with the GraalVM tracing agent across full MCP sessions (stub + live API), plus wholesale registration of all McpSchema$*, api.client.model.*, and mcp.model.* types.
    • Replaced reachability-metadata.json (the unified format, ignored by GraalVM for JDK 21) with classic-format reflect-config.json/resource-config.json, which all GraalVM versions process.
    • logback.xml is now included in the image: native binary logs went to stdout with the default pattern, corrupting the MCP stdio protocol; they now go to stderr as configured.
  • Verified end-to-end on macOS arm64: authentication, tools/list, and live tool calls against the production API.

[0.3.2] — 2026-06-13

Fixed 🐛

  • Native binary TLS on macOS/Linux: auth() failed: HTTP 0 — api.qtsurfer.net omits the WE1 intermediate CA from its TLS handshake. GraalVM native images cannot AIA-chase at runtime, causing the TLS handshake to fail silently. The WE1 certificate (Google Trust Services, valid until 2029) is now bundled as a classpath resource and injected as a trust anchor at startup via a composite X509TrustManager set as the JVM default SSLContext, before the first outbound connection. The fat JAR is unaffected (JVM AIA-chases automatically).

[0.3.1] — 2026-06-12

Added ✨

  • version MCP tool — returns the server version and API endpoint in use. Useful for diagnosing which build is running inside a client session.
  • Installer scripts — one-liner install for all platforms:
    • install.sh (Linux · macOS): detects OS/arch, downloads the native binary or fat JAR, removes macOS quarantine automatically. Falls back to fat JAR on Intel Mac and Linux ARM64; offers to install Java 21 via SDKMAN if missing.
    • install.ps1 (Windows): downloads qtsurfer-mcp-windows-amd64.exe, adds to user PATH; offers to install Java 21 via winget on unsupported architectures.
  • Versionless fat JAR asset — each release now includes qtsurfer-mcp-java.jar alongside the versioned qtsurfer-mcp-java-x.y.z.jar, so the installation URL never needs updating.
  • --help banner — QTSurfer ASCII banner + version, git commit hash, and build timestamp printed on --help.

Fixed 🐛

  • Native binary TLS trust on macOS — GraalVM native images embed CA certificates at compile time and cannot chase AIA URLs at runtime. The CI build now syncs OS root CAs into the GraalVM JDK and explicitly downloads any intermediate CAs omitted by the server's TLS handshake (via AIA CA Issuers), so the baked-in trust store is complete. Fixes auth() failed: HTTP 0 errors on macOS Apple Silicon against hosts using Google Trust Services intermediates.

Changed 🔄

  • Version sourced from build.properties — the server version is no longer a hardcoded string in McpServerRunner. It is read from a filtered build.properties resource populated by Maven (${project.version}) and git-commit-id-maven-plugin (git.commit.id.abbrev, git.build.time). Falls back to "dev" when running from IDE sources without a Maven build.

[0.3.0] — 2026-05-26

Changed (BREAKING)

  • Auth model swapped from JWT-in-env to apikey-via-SDK. The MCP server now reads a long-lived API key from QTSURFER_APIKEY (or the new --apikey flag) and uses com.qtsurfer:sdk-java 0.5.0 QTSurfer.auth(apikey) to mint and transparently refresh a short-lived JWT for the lifetime of the process. MCP servers can now run for days under a desktop client without manual token rotation.
  • Removed: the QTS_TOKEN env var and the --token CLI flag. There is no backwards-compatibility shim — adopters must update their MCP client config to pass QTSURFER_APIKEY instead.
  • Fail-fast startup: if QTSURFER_APIKEY is missing or the initial JWT exchange returns 401, the server logs a clear error to stderr and exits non-zero before exposing any tools. Better than silently exposing tools that all 401 on first call.
  • Maven coordinates: <artifactId> renamed from mcp to mcp-java to match the GitHub repository name. This affects the on-disk JAR name (mcp-java-0.3.0.jar instead of mcp-0.2.1.jar); distribution to end users is unchanged — the GitHub Release asset is still qtsurfer-mcp-java-0.3.0.jar.

Upgrade guide

Replace QTS_TOKEN with QTSURFER_APIKEY in every MCP client config snippet:

 {
   "mcpServers": {
     "qtsurfer": {
       "command": "/path/to/qtsurfer-mcp",
-      "args": ["--url", "https://api.qtsurfer.com/v1"],
-      "env": { "QTS_TOKEN": "<your-jwt>" }
+      "env": { "QTSURFER_APIKEY": "<your-api-key>" }
     }
   }
 }

Issue a new long-lived API key via the QTSurfer web app — the server handles JWT minting and refresh for you.

[0.2.0] — 2026-05-17

Changed

  • Maven coordinates migrated to com.qtsurfer:mcp-java via JitPack custom domain (git.qtsurfer.com). Consumers should replace com.github.QTSurfer:mcp-java with com.qtsurfer:mcp-java:0.2.0.
  • Java packages renamed from net.qtsurfer.mcp to com.qtsurfer.mcp throughout.
  • Dependency on com.qtsurfer:sdk-java:0.4.1.
  • Tags no longer use the v prefix; CI release workflow updated accordingly.

[0.1.0] — 2026-05-17

Added

  • MCP server over stdio — JSON-RPC 2.0 transport compatible with Claude Code, Codex, and any MCP-capable client.
  • Five tools exposed:
    • list_exchanges — list available exchanges on the QTSurfer platform.
    • list_instruments — list instruments for a given exchange with data-availability windows, last price, and 24 h volume.
    • submit_backtest — compile a Java strategy and queue a backtesting run; returns the job ID immediately.
    • get_job_status — poll a job and retrieve full execution metrics (P&L, trades, win rate, Sharpe, Sortino, CAGR, max drawdown) once completed.
    • list_jobs — list jobs submitted in the current session, with optional status filter.
  • Fat JAR distribution — java -jar qtsurfer-mcp-java-vX.Y.Z.jar with all dependencies bundled; no installation required beyond JDK 21+.
  • GraalVM native binary — ~17 ms startup, ~44 MB, no JVM required. Pre-built for Linux, macOS, and Windows via the CI release workflow. Build locally with mvn -Pnative -DskipTests package native:compile-no-fork or via Dockerfile.native.
  • Docker support — Dockerfile (fat JAR, eclipse-temurin:21-jre) and Dockerfile.native (GraalVM CE 25 → distroless/cc, ~65 MB).
  • --stub mode — in-memory stub for local testing without a backend token.
  • Backed by com.qtsurfer:sdk-java for all API interaction.