Repository navigation
fix: canonical marine-fuels path and stdio-only registry record (#146 items 3-4) - #171
Conversation
…items 3-4) - opa_get_marine_fuels and energy_marine_fuels now call the documented GET /v1/prices/marine-fuels/latest instead of the deprecated /v1/marine-fuels/latest alias. Both routes hit prices#marine_fuels_latest and returned byte-identical bodies live on 2026-10-15. - Capability ledger drops the `via` alias and the compatibility prefix. - server.json stays without `remotes`: mcp.oilpriceapi.com/mcp serves a different 9-tool energy_* server (v0.1.1). README now records that this server is stdio-only, and a test pins both facts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Adversarial review: APPROVEHead CI on this SHA. All required checks pass: unit+build, Packed runtime Node 18/20/22/24, product-facts smoke, capability ledger. Live API smoke skips by design on PRs. GitHub reports MERGEABLE/CLEAN. Merge with current main. The branch is one commit behind #168, which touches README.md and src/index.ts. I merged origin/main into a local worktree with no conflicts. On the merged tree, build, check:capability-ledger (36 tools, 49 REST paths), check:readme-tools (36 tools) and verify:release-metadata all pass. vitest: 550 passed, 1 failed. The failure is the known Item 4: the route switch.
Item 3: stdio only, no
Non-blocking notes
|
Publishes to npm and the MCP registry: - opa_get_spread exposes pair, crack type/crude, margin index and daily history; type=basis no longer always fails (#169, #170) - opa_get_history_range: date-range price history for up to 5 codes (#123, #177) - canonical marine-fuels path and stdio-only registry record (#146, #171) - honest 404 wording and README tool drift check (#146, #168) - smoke cleanup of synthetic records (#126, #173) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* chore(deps): bump actions/upload-artifact from 7.0.1 to 7.0.2 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.1 to 7.0.2. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](actions/upload-artifact@043fb46...cf430e0) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * chore(deps): bump actions/setup-node from 7.0.0 to 7.1.0 (#160) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 7.0.0 to 7.1.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](actions/setup-node@8207627...949feb2) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: 7.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix(ci): reconcile capability ledger drift and patch proxy-addr (#159) (#167) * fix(ci): reconcile capability ledger drift and patch proxy-addr (#159) - Ledger v3: record GET /v1/context/market/news and GET /v1/futures/oman as explicitly deferred; market-brief family is now partial. - Refresh the route-policy snapshot to oilpriceapi-api 66f46ed0d (only change since 531e29899 is the retired congressional-trades reason, which no ledger family uses). - npm audit fix: proxy-addr 2.0.7 -> 2.0.8 (GHSA-jqcg-44mw-7w3h). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QQ7W3CkRKEnBpU5KRQUfUu * fix(ci): add ledger row for GET /v1/meta/methodology (#159) The live OpenAPI contract started publishing GET /v1/meta/methodology on 2026-10-14, so check:capability-ledger reported drift against main. Record it as not_exposed/deferred in the commodities family. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QQ7W3CkRKEnBpU5KRQUfUu * fix(ledger): record methodology and api-key rename decisions in v3 changes (#159) Adversarial review BLOCK on 929f194: the v3 changes entry omitted the GET /v1/meta/methodology decision. The ledger contract requires every decision change in changes. While re-checking, the live contract also started publishing PATCH /v1/api-keys/{id} (rename key), which made check:capability-ledger drift again; record it as unsupported like the other api-keys operations. Add a test that every v3 decision is named in the v3 summary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QQ7W3CkRKEnBpU5KRQUfUu --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * chore(deps): bump express from 5.2.1 to 5.3.0 (#163) Bumps [express](https://github.com/expressjs/express) from 5.2.1 to 5.3.0. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](expressjs/express@v5.2.1...v5.3.0) --- updated-dependencies: - dependency-name: express dependency-version: 5.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump @modelcontextprotocol/sdk from 1.31.0 to 1.32.1 (#164) Bumps [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) from 1.31.0 to 1.32.1. - [Release notes](https://github.com/modelcontextprotocol/typescript-sdk/releases) - [Commits](modelcontextprotocol/typescript-sdk@1.31.0...1.32.1) --- updated-dependencies: - dependency-name: "@modelcontextprotocol/sdk" dependency-version: 1.32.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump actions/download-artifact from 8.0.1 to 8.0.2 (#161) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 8.0.1 to 8.0.2. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](actions/download-artifact@3e5f45b...9000827) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: 8.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: README tool drift check and honest 404 wording (#146) (#168) - scripts/check-readme-tools.mjs fails CI when README tool tables and build/capabilities.json differ; wired into Unit tests + build. - README documents the 4 missing tools (36/36). - describeRequestFailure: a "No route matches" 404 is reported as a server request-path defect with the issues link; a routed 404 keeps the API's own message; an empty 404 no longer claims the dataset is unpopulated. Claude-Session: https://claude.ai/code/session_01QQ7W3CkRKEnBpU5KRQUfUu Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix: canonical marine-fuels path and stdio-only registry record (#146 items 3-4) (#171) - opa_get_marine_fuels and energy_marine_fuels now call the documented GET /v1/prices/marine-fuels/latest instead of the deprecated /v1/marine-fuels/latest alias. Both routes hit prices#marine_fuels_latest and returned byte-identical bodies live on 2026-10-15. - Capability ledger drops the `via` alias and the compatibility prefix. - server.json stays without `remotes`: mcp.oilpriceapi.com/mcp serves a different 9-tool energy_* server (v0.1.1). README now records that this server is stdio-only, and a test pins both facts. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(smoke): clean up synthetic records by name and sweep past leaks (#126) (#173) The live smoke deleted its synthetic alert/watch only `if (id)`. On 2026-09-04 the id read missed the response envelope, cleanup was skipped, and watch b84b24a0 has run hourly on the shared test key since. - Cleanup runs whenever the create was sent. Without an id it deletes by the run's unique `mcp-live-contract-<ms>` name, then verifies absence. - Each lifecycle first sweeps `mcp-live-contract-<digits>` records older than one hour. Undated, customer-named or look-alike records are left alone. - Logic lives in scripts/synthetic-cleanup.mjs with unit tests. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * feat: opa_get_history_range — date-range price history (#123) (#177) * feat: opa_get_history_range for date-range price history (#123) Adds opa_get_history_range over GET /v1/prices/historical: 1-5 commodities, start_date/end_date (YYYY-MM-DD), hourly/daily/weekly/monthly, page and per_page (max 500). Rows render per code, oldest first, at the API's own precision, with currency/unit and the API's instrument disclosures. - Pagination totals come from X-Total / X-Total-Pages (requestApi now returns success headers); a page that is not the last says so explicitly. - A start date later than requested (plan history-depth clamp) is reported. - A missing-code claim for a code that has rows on the page is dropped (api#8496, confirmed live 2026-10-15). - extractErrorDetail reads the JSend fail envelope so 400s carry the API's message instead of a bare HTTP 400. - Ledger v4: GET /v1/prices/historical exposed; GET /v1/prices recorded as alias. Live-contract catalog entry, README row, inventory counts 33/37. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: history-depth clamp, past-last-page and page order in opa_get_history_range (#123) Addresses the adversarial review BLOCK on #177: - D1: when the plan's history-depth clamp moves the applied start past the requested range and zero rows come back, say the plan window starts at the applied date and point to opa_get_plans, instead of calling it missing data. - D2: a page beyond X-Total-Pages is reported as past the last page. - D3: description, output and keyless teaser state pages run newest first. - D4: ledger reason for GET /v1/prices alias no longer claims identical rows (default source, spot_price type scope and BYOS scoping differ). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(spread): expose pair, crack type/crude, margin index and history (#169) (#170) * fix(spread): expose pair, crack type/crude, margin index and history (#169) opa_get_spread called /v1/spreads/${type} with no query string, so type=basis always returned 400 MISSING_PARAMETER and crack/margin were stuck on their backend defaults. - pair (basis): WAHA_HH|BRENT_WTI|BRENT_DUBAI|JKM_HH|TTF_HH|BRENT_OMAN; basis without a pair now lists every pair via /v1/spreads/basis/all - crack_type (3-2-1|jet|diesel|gasoline) and crude (4 codes) for crack - index (usgc|singapore|nwe) for margin - start_date/end_date route to /{type}/historical - parameters that do not apply to the type, malformed/reversed dates and basis history without a pair are refused before any request - capability ledger: basis/all and the three /historical ops now exposed Fixes #169 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(spread): classify local refusals as invalid_argument; fix teaser text (#169) Reword the three spreadEndpoint refusals so telemetry classifyToolMiss maps them to invalid_argument instead of unknown, and assert it in the spread tests. The keyless teaser no longer says blending/transport margins; it says composite refinery margins. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(ledger): v5 records #169 spread exposure Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * release: v3.5.0 (#179) Publishes to npm and the MCP registry: - opa_get_spread exposes pair, crack type/crude, margin index and daily history; type=basis no longer always fails (#169, #170) - opa_get_history_range: date-range price history for up to 5 codes (#123, #177) - canonical marine-fuels path and stdio-only registry record (#146, #171) - honest 404 wording and README tool drift check (#146, #168) - smoke cleanup of synthetic records (#126, #173) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: karlwaldman <karl.waldman@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* chore(deps): bump node from `50c8e8c` to `ebfe2f9` Bumps node from `50c8e8c` to `ebfe2f9`. --- updated-dependencies: - dependency-name: node dependency-version: 24-alpine dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> * chore(deps): bump actions/setup-node from 7.0.0 to 7.1.0 (#160) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 7.0.0 to 7.1.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](actions/setup-node@8207627...949feb2) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: 7.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix(ci): reconcile capability ledger drift and patch proxy-addr (#159) (#167) * fix(ci): reconcile capability ledger drift and patch proxy-addr (#159) - Ledger v3: record GET /v1/context/market/news and GET /v1/futures/oman as explicitly deferred; market-brief family is now partial. - Refresh the route-policy snapshot to oilpriceapi-api 66f46ed0d (only change since 531e29899 is the retired congressional-trades reason, which no ledger family uses). - npm audit fix: proxy-addr 2.0.7 -> 2.0.8 (GHSA-jqcg-44mw-7w3h). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QQ7W3CkRKEnBpU5KRQUfUu * fix(ci): add ledger row for GET /v1/meta/methodology (#159) The live OpenAPI contract started publishing GET /v1/meta/methodology on 2026-10-14, so check:capability-ledger reported drift against main. Record it as not_exposed/deferred in the commodities family. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QQ7W3CkRKEnBpU5KRQUfUu * fix(ledger): record methodology and api-key rename decisions in v3 changes (#159) Adversarial review BLOCK on 929f194: the v3 changes entry omitted the GET /v1/meta/methodology decision. The ledger contract requires every decision change in changes. While re-checking, the live contract also started publishing PATCH /v1/api-keys/{id} (rename key), which made check:capability-ledger drift again; record it as unsupported like the other api-keys operations. Add a test that every v3 decision is named in the v3 summary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QQ7W3CkRKEnBpU5KRQUfUu --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * chore(deps): bump express from 5.2.1 to 5.3.0 (#163) Bumps [express](https://github.com/expressjs/express) from 5.2.1 to 5.3.0. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](expressjs/express@v5.2.1...v5.3.0) --- updated-dependencies: - dependency-name: express dependency-version: 5.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump @modelcontextprotocol/sdk from 1.31.0 to 1.32.1 (#164) Bumps [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) from 1.31.0 to 1.32.1. - [Release notes](https://github.com/modelcontextprotocol/typescript-sdk/releases) - [Commits](modelcontextprotocol/typescript-sdk@1.31.0...1.32.1) --- updated-dependencies: - dependency-name: "@modelcontextprotocol/sdk" dependency-version: 1.32.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump actions/download-artifact from 8.0.1 to 8.0.2 (#161) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 8.0.1 to 8.0.2. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](actions/download-artifact@3e5f45b...9000827) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: 8.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: README tool drift check and honest 404 wording (#146) (#168) - scripts/check-readme-tools.mjs fails CI when README tool tables and build/capabilities.json differ; wired into Unit tests + build. - README documents the 4 missing tools (36/36). - describeRequestFailure: a "No route matches" 404 is reported as a server request-path defect with the issues link; a routed 404 keeps the API's own message; an empty 404 no longer claims the dataset is unpopulated. Claude-Session: https://claude.ai/code/session_01QQ7W3CkRKEnBpU5KRQUfUu Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix: canonical marine-fuels path and stdio-only registry record (#146 items 3-4) (#171) - opa_get_marine_fuels and energy_marine_fuels now call the documented GET /v1/prices/marine-fuels/latest instead of the deprecated /v1/marine-fuels/latest alias. Both routes hit prices#marine_fuels_latest and returned byte-identical bodies live on 2026-10-15. - Capability ledger drops the `via` alias and the compatibility prefix. - server.json stays without `remotes`: mcp.oilpriceapi.com/mcp serves a different 9-tool energy_* server (v0.1.1). README now records that this server is stdio-only, and a test pins both facts. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(smoke): clean up synthetic records by name and sweep past leaks (#126) (#173) The live smoke deleted its synthetic alert/watch only `if (id)`. On 2026-09-04 the id read missed the response envelope, cleanup was skipped, and watch b84b24a0 has run hourly on the shared test key since. - Cleanup runs whenever the create was sent. Without an id it deletes by the run's unique `mcp-live-contract-<ms>` name, then verifies absence. - Each lifecycle first sweeps `mcp-live-contract-<digits>` records older than one hour. Undated, customer-named or look-alike records are left alone. - Logic lives in scripts/synthetic-cleanup.mjs with unit tests. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * feat: opa_get_history_range — date-range price history (#123) (#177) * feat: opa_get_history_range for date-range price history (#123) Adds opa_get_history_range over GET /v1/prices/historical: 1-5 commodities, start_date/end_date (YYYY-MM-DD), hourly/daily/weekly/monthly, page and per_page (max 500). Rows render per code, oldest first, at the API's own precision, with currency/unit and the API's instrument disclosures. - Pagination totals come from X-Total / X-Total-Pages (requestApi now returns success headers); a page that is not the last says so explicitly. - A start date later than requested (plan history-depth clamp) is reported. - A missing-code claim for a code that has rows on the page is dropped (api#8496, confirmed live 2026-10-15). - extractErrorDetail reads the JSend fail envelope so 400s carry the API's message instead of a bare HTTP 400. - Ledger v4: GET /v1/prices/historical exposed; GET /v1/prices recorded as alias. Live-contract catalog entry, README row, inventory counts 33/37. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: history-depth clamp, past-last-page and page order in opa_get_history_range (#123) Addresses the adversarial review BLOCK on #177: - D1: when the plan's history-depth clamp moves the applied start past the requested range and zero rows come back, say the plan window starts at the applied date and point to opa_get_plans, instead of calling it missing data. - D2: a page beyond X-Total-Pages is reported as past the last page. - D3: description, output and keyless teaser state pages run newest first. - D4: ledger reason for GET /v1/prices alias no longer claims identical rows (default source, spot_price type scope and BYOS scoping differ). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(spread): expose pair, crack type/crude, margin index and history (#169) (#170) * fix(spread): expose pair, crack type/crude, margin index and history (#169) opa_get_spread called /v1/spreads/${type} with no query string, so type=basis always returned 400 MISSING_PARAMETER and crack/margin were stuck on their backend defaults. - pair (basis): WAHA_HH|BRENT_WTI|BRENT_DUBAI|JKM_HH|TTF_HH|BRENT_OMAN; basis without a pair now lists every pair via /v1/spreads/basis/all - crack_type (3-2-1|jet|diesel|gasoline) and crude (4 codes) for crack - index (usgc|singapore|nwe) for margin - start_date/end_date route to /{type}/historical - parameters that do not apply to the type, malformed/reversed dates and basis history without a pair are refused before any request - capability ledger: basis/all and the three /historical ops now exposed Fixes #169 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(spread): classify local refusals as invalid_argument; fix teaser text (#169) Reword the three spreadEndpoint refusals so telemetry classifyToolMiss maps them to invalid_argument instead of unknown, and assert it in the spread tests. The keyless teaser no longer says blending/transport margins; it says composite refinery margins. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(ledger): v5 records #169 spread exposure Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * release: v3.5.0 (#179) Publishes to npm and the MCP registry: - opa_get_spread exposes pair, crack type/crude, margin index and daily history; type=basis no longer always fails (#169, #170) - opa_get_history_range: date-range price history for up to 5 codes (#123, #177) - canonical marine-fuels path and stdio-only registry record (#146, #171) - honest 404 wording and README tool drift check (#146, #168) - smoke cleanup of synthetic records (#126, #173) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: karlwaldman <karl.waldman@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(demo): tag keyless /v1/demo requests with client=mcp The API's demo telemetry attributes keyless traffic by the `client` query parameter; MCP sent only X-Api-Client headers, so every MCP demo request was logged as client=unknown (OilpriceAPI/oilpriceapi-api#9388). Add withDemoClient() and apply it at all three real /v1/demo request sites: fetchDemoPrices (stdio server), the energy plugin facade (remote), and the doctor demo check. Existing query params and an explicit client are kept. No iid is sent: the server persists no anonymous install id. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CGRpvj87b8YNgH7PC8ivEE * chore(deps): bump actions/setup-node from 7.0.0 to 7.1.0 (#160) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 7.0.0 to 7.1.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](actions/setup-node@8207627...949feb2) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: 7.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix(ci): reconcile capability ledger drift and patch proxy-addr (#159) (#167) * fix(ci): reconcile capability ledger drift and patch proxy-addr (#159) - Ledger v3: record GET /v1/context/market/news and GET /v1/futures/oman as explicitly deferred; market-brief family is now partial. - Refresh the route-policy snapshot to oilpriceapi-api 66f46ed0d (only change since 531e29899 is the retired congressional-trades reason, which no ledger family uses). - npm audit fix: proxy-addr 2.0.7 -> 2.0.8 (GHSA-jqcg-44mw-7w3h). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QQ7W3CkRKEnBpU5KRQUfUu * fix(ci): add ledger row for GET /v1/meta/methodology (#159) The live OpenAPI contract started publishing GET /v1/meta/methodology on 2026-10-14, so check:capability-ledger reported drift against main. Record it as not_exposed/deferred in the commodities family. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QQ7W3CkRKEnBpU5KRQUfUu * fix(ledger): record methodology and api-key rename decisions in v3 changes (#159) Adversarial review BLOCK on 929f194: the v3 changes entry omitted the GET /v1/meta/methodology decision. The ledger contract requires every decision change in changes. While re-checking, the live contract also started publishing PATCH /v1/api-keys/{id} (rename key), which made check:capability-ledger drift again; record it as unsupported like the other api-keys operations. Add a test that every v3 decision is named in the v3 summary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QQ7W3CkRKEnBpU5KRQUfUu --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * chore(deps): bump express from 5.2.1 to 5.3.0 (#163) Bumps [express](https://github.com/expressjs/express) from 5.2.1 to 5.3.0. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](expressjs/express@v5.2.1...v5.3.0) --- updated-dependencies: - dependency-name: express dependency-version: 5.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump @modelcontextprotocol/sdk from 1.31.0 to 1.32.1 (#164) Bumps [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) from 1.31.0 to 1.32.1. - [Release notes](https://github.com/modelcontextprotocol/typescript-sdk/releases) - [Commits](modelcontextprotocol/typescript-sdk@1.31.0...1.32.1) --- updated-dependencies: - dependency-name: "@modelcontextprotocol/sdk" dependency-version: 1.32.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump actions/download-artifact from 8.0.1 to 8.0.2 (#161) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 8.0.1 to 8.0.2. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](actions/download-artifact@3e5f45b...9000827) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: 8.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: README tool drift check and honest 404 wording (#146) (#168) - scripts/check-readme-tools.mjs fails CI when README tool tables and build/capabilities.json differ; wired into Unit tests + build. - README documents the 4 missing tools (36/36). - describeRequestFailure: a "No route matches" 404 is reported as a server request-path defect with the issues link; a routed 404 keeps the API's own message; an empty 404 no longer claims the dataset is unpopulated. Claude-Session: https://claude.ai/code/session_01QQ7W3CkRKEnBpU5KRQUfUu Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix: canonical marine-fuels path and stdio-only registry record (#146 items 3-4) (#171) - opa_get_marine_fuels and energy_marine_fuels now call the documented GET /v1/prices/marine-fuels/latest instead of the deprecated /v1/marine-fuels/latest alias. Both routes hit prices#marine_fuels_latest and returned byte-identical bodies live on 2026-10-15. - Capability ledger drops the `via` alias and the compatibility prefix. - server.json stays without `remotes`: mcp.oilpriceapi.com/mcp serves a different 9-tool energy_* server (v0.1.1). README now records that this server is stdio-only, and a test pins both facts. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(smoke): clean up synthetic records by name and sweep past leaks (#126) (#173) The live smoke deleted its synthetic alert/watch only `if (id)`. On 2026-09-04 the id read missed the response envelope, cleanup was skipped, and watch b84b24a0 has run hourly on the shared test key since. - Cleanup runs whenever the create was sent. Without an id it deletes by the run's unique `mcp-live-contract-<ms>` name, then verifies absence. - Each lifecycle first sweeps `mcp-live-contract-<digits>` records older than one hour. Undated, customer-named or look-alike records are left alone. - Logic lives in scripts/synthetic-cleanup.mjs with unit tests. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * feat: opa_get_history_range — date-range price history (#123) (#177) * feat: opa_get_history_range for date-range price history (#123) Adds opa_get_history_range over GET /v1/prices/historical: 1-5 commodities, start_date/end_date (YYYY-MM-DD), hourly/daily/weekly/monthly, page and per_page (max 500). Rows render per code, oldest first, at the API's own precision, with currency/unit and the API's instrument disclosures. - Pagination totals come from X-Total / X-Total-Pages (requestApi now returns success headers); a page that is not the last says so explicitly. - A start date later than requested (plan history-depth clamp) is reported. - A missing-code claim for a code that has rows on the page is dropped (api#8496, confirmed live 2026-10-15). - extractErrorDetail reads the JSend fail envelope so 400s carry the API's message instead of a bare HTTP 400. - Ledger v4: GET /v1/prices/historical exposed; GET /v1/prices recorded as alias. Live-contract catalog entry, README row, inventory counts 33/37. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: history-depth clamp, past-last-page and page order in opa_get_history_range (#123) Addresses the adversarial review BLOCK on #177: - D1: when the plan's history-depth clamp moves the applied start past the requested range and zero rows come back, say the plan window starts at the applied date and point to opa_get_plans, instead of calling it missing data. - D2: a page beyond X-Total-Pages is reported as past the last page. - D3: description, output and keyless teaser state pages run newest first. - D4: ledger reason for GET /v1/prices alias no longer claims identical rows (default source, spot_price type scope and BYOS scoping differ). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(spread): expose pair, crack type/crude, margin index and history (#169) (#170) * fix(spread): expose pair, crack type/crude, margin index and history (#169) opa_get_spread called /v1/spreads/${type} with no query string, so type=basis always returned 400 MISSING_PARAMETER and crack/margin were stuck on their backend defaults. - pair (basis): WAHA_HH|BRENT_WTI|BRENT_DUBAI|JKM_HH|TTF_HH|BRENT_OMAN; basis without a pair now lists every pair via /v1/spreads/basis/all - crack_type (3-2-1|jet|diesel|gasoline) and crude (4 codes) for crack - index (usgc|singapore|nwe) for margin - start_date/end_date route to /{type}/historical - parameters that do not apply to the type, malformed/reversed dates and basis history without a pair are refused before any request - capability ledger: basis/all and the three /historical ops now exposed Fixes #169 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(spread): classify local refusals as invalid_argument; fix teaser text (#169) Reword the three spreadEndpoint refusals so telemetry classifyToolMiss maps them to invalid_argument instead of unknown, and assert it in the spread tests. The keyless teaser no longer says blending/transport margins; it says composite refinery margins. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(ledger): v5 records #169 spread exposure Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * release: v3.5.0 (#179) Publishes to npm and the MCP registry: - opa_get_spread exposes pair, crack type/crude, margin index and daily history; type=basis no longer always fails (#169, #170) - opa_get_history_range: date-range price history for up to 5 codes (#123, #177) - canonical marine-fuels path and stdio-only registry record (#146, #171) - honest 404 wording and README tool drift check (#146, #168) - smoke cleanup of synthetic records (#126, #173) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* feat: opa_get_futures_history for futures settlement history (#124) Adds opa_get_futures_history over GET /v1/futures/{brent,wti,natural-gas}/historical: instrument enum mapped to literal paths, from/to (YYYY-MM-DD, at most 730 days, no future dates), optional contract_month (YYYY-MM), daily/weekly/ monthly bars. All bounds are checked before any network call. - One OHLC table per contract month at the API's own precision; settlement column only where the API reports one; daily close is labelled as the last captured price. Quote basis from the instrument specification. - The endpoint has no pagination, so rendering is capped at 400 rows with an explicit partial-answer notice naming what was left out (#113). - The HTTP 200 {error, available_dates} empty window is reported as a data fact with the API's available range. - Ledger v4: the three canonical history rows are exposed (selection 2); spreads stay deferred with an updated reason. Live-contract catalog entry with a new futures-history shape, field-checked through its handler args. README row and inventory counts 33/37. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: opa_get_history_range — date-range price history (#123) (#177) * feat: opa_get_history_range for date-range price history (#123) Adds opa_get_history_range over GET /v1/prices/historical: 1-5 commodities, start_date/end_date (YYYY-MM-DD), hourly/daily/weekly/monthly, page and per_page (max 500). Rows render per code, oldest first, at the API's own precision, with currency/unit and the API's instrument disclosures. - Pagination totals come from X-Total / X-Total-Pages (requestApi now returns success headers); a page that is not the last says so explicitly. - A start date later than requested (plan history-depth clamp) is reported. - A missing-code claim for a code that has rows on the page is dropped (api#8496, confirmed live 2026-10-15). - extractErrorDetail reads the JSend fail envelope so 400s carry the API's message instead of a bare HTTP 400. - Ledger v4: GET /v1/prices/historical exposed; GET /v1/prices recorded as alias. Live-contract catalog entry, README row, inventory counts 33/37. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: history-depth clamp, past-last-page and page order in opa_get_history_range (#123) Addresses the adversarial review BLOCK on #177: - D1: when the plan's history-depth clamp moves the applied start past the requested range and zero rows come back, say the plan window starts at the applied date and point to opa_get_plans, instead of calling it missing data. - D2: a page beyond X-Total-Pages is reported as past the last page. - D3: description, output and keyless teaser state pages run newest first. - D4: ledger reason for GET /v1/prices alias no longer claims identical rows (default source, spot_price type scope and BYOS scoping differ). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(spread): expose pair, crack type/crude, margin index and history (#169) (#170) * fix(spread): expose pair, crack type/crude, margin index and history (#169) opa_get_spread called /v1/spreads/${type} with no query string, so type=basis always returned 400 MISSING_PARAMETER and crack/margin were stuck on their backend defaults. - pair (basis): WAHA_HH|BRENT_WTI|BRENT_DUBAI|JKM_HH|TTF_HH|BRENT_OMAN; basis without a pair now lists every pair via /v1/spreads/basis/all - crack_type (3-2-1|jet|diesel|gasoline) and crude (4 codes) for crack - index (usgc|singapore|nwe) for margin - start_date/end_date route to /{type}/historical - parameters that do not apply to the type, malformed/reversed dates and basis history without a pair are refused before any request - capability ledger: basis/all and the three /historical ops now exposed Fixes #169 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(spread): classify local refusals as invalid_argument; fix teaser text (#169) Reword the three spreadEndpoint refusals so telemetry classifyToolMiss maps them to invalid_argument instead of unknown, and assert it in the spread tests. The keyless teaser no longer says blending/transport margins; it says composite refinery margins. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(ledger): v5 records #169 spread exposure Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * release: v3.5.0 (#179) Publishes to npm and the MCP registry: - opa_get_spread exposes pair, crack type/crude, margin index and daily history; type=basis no longer always fails (#169, #170) - opa_get_history_range: date-range price history for up to 5 codes (#123, #177) - canonical marine-fuels path and stdio-only registry record (#146, #171) - honest 404 wording and README tool drift check (#146, #168) - smoke cleanup of synthetic records (#126, #173) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * test: reconcile complete tool inventories after history additions * test: align container inventory with both history tools --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Closes the remaining items of #146. Items 1-2 are in #168; this PR touches none of its files except
README.md(a different section, no textual overlap).Item 4: deprecated marine-fuels alias
opa_get_marine_fuels(src/index.ts) andenergy_marine_fuels(src/energyPlugin.ts) now callGET /v1/prices/marine-fuels/latest.oilpriceapi-apiconfig/routes.rb(origin/main)prices#marine_fuels_latestconfig/openapi_route_policy.yml/v1/marine-fuels/latestis a deprecated compatibility aliasswagger/v1/swagger.yaml/v1/prices/marine-fuels/latest{},?port=SGSIN,?fuel_type=VLSFOdiffof the jq-sorted bodies is empty (17,705 / 2,327 / 131 bytes)The capability ledger drops the
viaalias and the/v1/marine-fuelscompatibility prefix.npm run check:capability-ledger: OK, 37 exposed, 36 tools, 49 REST paths.Item 3: server.json
remotesNot added, on purpose. The registry schema (
2025-12-11,ServerDetail.remotes) describes a remote as the same server as the package. The live endpoint is a different server:POST https://mcp.oilpriceapi.com/mcpinitializereturnsserverInfo {"name":"OilPriceAPI","version":"0.1.1"}.tools/listreturns 9energy_*tools, not the 36opa_*tools in npm 3.4.2. Checked 2026-10-15.energy:read(OAuth), matching chore(deploy): prepare durable remote MCP 0.1.2 rollout #151's record of DO appoilpriceapi-openai-mcp.remotes: null. All 20 published versions have none.The README gains a
## Transportsection saying this server is stdio-only and the hosted endpoint is a separateenergy_*server.directorySource.test.tspins three facts: noremotes, stdio-only packages, and that README text.Tests
npm test: 547 passed, 1 failed. The failure isenergyPlugin.test.ts > cancels an upstream that stalls after opening its response body(5 s timeout). It fails the same way on unmodified origin/main (2 of 5 local runs) and does not touch marine code. It is a pre-existing local flake, filed separately.npm run build,npm run verify:release-metadata,npm run check:capability-ledger: pass.tsc --noEmit(pai-check): pass.Nothing is released, published or deployed by this PR.
energy_marine_fuelsreaches the hosted endpoint only after a separate image deploy.🤖 Generated with Claude Code