Skip to content

Releases: QTSurfer/mcp-java

0.7.0

Choose a tag to compare

@github-actions github-actions released this 18 Jul 15:00

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 (CancelExecution200ResponseCancelBacktest200Response, GetStrategyStatus200ResponseGetStrategy200Response, PostStrategy200ResponseCompileStrategy200Response, ExecuteBacktestingRequestExecuteBacktestRequest, PrepareBacktestingRequestPrepareRequest, plus their nested enums) so the native binary keeps deserializing/instantiating these types after the rename.

0.6.0

Choose a tag to compare

@github-actions github-actions released this 11 Jul 13:20

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

Choose a tag to compare

@github-actions github-actions released this 10 Jul 20:54

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

Choose a tag to compare

@github-actions github-actions released this 15 Jun 23:09

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

Choose a tag to compare

@github-actions github-actions released this 13 Jun 13:31

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

Choose a tag to compare

@github-actions github-actions released this 12 Jun 23:51

Fixed 🐛

  • Native binary TLS on macOS/Linux: auth() failed: HTTP 0api.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

Choose a tag to compare

@github-actions github-actions released this 12 Jun 23:06

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

Choose a tag to compare

@github-actions github-actions released this 26 May 13:08

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.