Skip to content

Add OddsRelay connector - #977

Merged
helpcodeai merged 6 commits into
HelpCode-ai:mainfrom
oddsrelay:add-oddsrelay-connector
Oct 18, 2026
Merged

helpcodeai merged 6 commits into
HelpCode-ai:mainfrom
oddsrelay:add-oddsrelay-connector

Conversation

@oddsrelay

Copy link
Copy Markdown
Contributor

Summary

Adds an OddsRelay adapter (gb/oddsrelay.json): GET tools for the OddsRelay odds API, covering sports, events, bookmakers, coverage, the matched boards, one event's odds and the key's usage. A REST connector cannot quote before a call, so each board or event call spends tokens from the user's account; a quote tool that costs no tokens sits beside each of the two, and the instructions tell the assistant to quote first.

Disclosure: this pull request is from OddsRelay, the API it lists.

Changes

  • packages/backend/src/adapters/gb/oddsrelay.json: the adapter, all GET, Bearer auth from ODDSRELAY_KEY, Accept-Encoding: gzip (some boards refuse a request that does not accept gzip), probe and healthcheckPath on the usage call, which costs no tokens. The two GETs that spend tokens, oddsrelay_get_board and oddsrelay_get_event_odds, are annotated readOnlyHint: false on purpose, so the shared endpoint runs them through anythingmcp_run_write_tool, which tells the assistant to get the user's confirmation before each call; please keep that annotation
  • packages/backend/src/adapters/gb/oddsrelay.live.spec.ts: static assertions only (base URL, auth, gzip, probe and health check, which tools spend tokens)
  • packages/frontend/public/logos/connectors/oddsrelay.svg: logo
  • catalog.ts regenerated, quoted adapter counts updated

Type

  • New feature

Testing

  • Added/updated unit tests
  • Tested manually (describe steps below)

From the repository root:

  • node scripts/validate-adapters.mjs --warn: gb/oddsrelay.json passes with no errors and no warnings
  • node scripts/regenerate-catalog.mjs: two lines added to catalog.ts
  • node scripts/adapter-count.mjs --check: OK
  • gb/oddsrelay.live.spec.ts with intl/todoist.live.spec.ts under Jest 30 and the backend tsconfig.json: both suites pass

Not run: the full backend suite, which needs the database setup. The adapter follows the REST rules in catalog.spec.ts (every declared argument reaches the request, {name} path placeholders, no body on a GET), and every route and parameter was checked against the API's public OpenAPI file (https://api.oddsrelay.io/v2/openapi.json). It has not been run against a live AnythingMCP instance.

Checklist

  • My code follows the existing code style
  • I have tested my changes locally
  • I have updated documentation (if applicable)
  • All existing tests pass (npm test)
  • This PR has a descriptive title

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown

👋 Welcome, @oddsrelay, and thanks for opening your first PR on AnythingMCP!

A few quick pointers:

  • Make sure CI is green before requesting review (Backend, Frontend, Playwright, CodeQL, Trivy).
  • If this is a new adapter, the parametrised catalog.spec.ts test will validate it automatically.
  • Sign off your commits if you can — it's not blocking, just nice to have.

Someone from the core team will look at this within ~48h. If you don't hear back, please ping us in Discussions / Q&A.

⭐ While you wait — if you find AnythingMCP useful, a star helps others discover it.

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@helpcodeai helpcodeai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, and sorry it sat for a few days. I checked the routes against your openapi.json and they all line up, and the quote-first flow with readOnlyHint: false on the two paid tools is exactly how we'd want it. Keep that annotation.

A few things before it can go in:

  1. CLA: the check is still red. Please post the exact sentence the CLA bot asks for as a comment here ("I have read the CLA Document and I hereby sign the CLA"), then the check reruns.
  2. main has moved a long way since you branched (the catalog is at 422 adapters now), so catalog.ts and the counts conflict. Please merge main, then run node scripts/regenerate-catalog.mjs and node scripts/adapter-count.mjs --check from the root and update whatever files it names. The counts should end up at main's number plus one (423 today). Don't edit the numbers by hand.
  3. oddsrelay_get_coverage in gb/oddsrelay.json sends the whole /v2/coverage reply to the model. Right now that's about 246 KB: 3,692 bookmaker/sport rows across the seven products plus the market lists. Since the instructions make it step 1, every session would start by burning a big chunk of context. Please add a responseMapping to shrink it. Keeping only the market keys would already do (something like {"transform": {"mode": "jmespath", "expression": "{generated_at: generated_at, markets: markets}"}}), since your 400/403 errors already list the valid bookmakers. If you'd rather keep the bookmaker/sport pairs, drop status and the interrupted_24h rows and check the size again.

Smaller stuff, not blocking:

  • The description and the first lines of instructions say "bet365 included" twice. That reads like the landing page. Just say what the connector covers (pre-match odds from UK and Irish bookmakers with exchange lay prices) and leave the bookmaker list to oddsrelay_list_bookmakers.
  • oddsrelay.live.spec.ts only has static checks. Since /v2/usage and quote=true cost nothing, a block behind RUN_ODDSRELAY_LIVE=1 that calls usage and one board quote with a real key would be cheap for you and would catch route changes later.

Once 1 to 3 are in, I'll run the catalog suite again and take another look.

oddsrelay and others added 2 commits October 16, 2026 15:02
Resolve the adapter-count conflicts by taking main's text and running
node scripts/regenerate-catalog.mjs and node scripts/adapter-count.mjs
--check, which now report 475 adapters (main's 474 plus OddsRelay).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: OddsRelay <330405695+oddsrelay@users.noreply.github.com>
- oddsrelay_get_coverage gets a JMESPath responseMapping. The connector
  always sends the key, so /v2/coverage answers with its keyed view
  (venues with prices now, per board, with event counts and last-seen
  times; it has no markets field). The mapping keeps, per board, each
  bookmaker's and exchange's key with its sport keys, and drops names,
  counts and times.
- Tool and parameter descriptions no longer say coverage lists market
  keys; an unknown market key is refused with the valid keys listed.
- The description and instructions say what the connector covers and
  leave the bookmaker list to oddsrelay_list_bookmakers.
- oddsrelay.live.spec.ts pins the coverage mapping on a keyed fixture,
  and adds a block behind RUN_ODDSRELAY_LIVE=1 (key from ODDSRELAY_KEY)
  that calls usage and quotes one board, both free. It is skipped when
  either variable is unset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: OddsRelay <330405695+oddsrelay@users.noreply.github.com>
@oddsrelay

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

@oddsrelay

Copy link
Copy Markdown
Contributor Author

Thanks for the review. All three are in:

  1. CLA: signed in the comment above.
  2. Merged main and ran node scripts/regenerate-catalog.mjs and node scripts/adapter-count.mjs --check from the root (a6fc5c3). Main was at 474 when we merged, so the counts now read 475.
  3. oddsrelay_get_coverage has a JMESPath responseMapping (71987c3). One wrinkle: the connector always sends the key, and with a key /v2/coverage returns its keyed view (venues pricing now, per board, with event counts and last-seen times). That view has no markets field, so a markets-only mapping would come back empty. The mapping keeps each board's bookmaker and exchange keys with their sport keys, and drops names, counts and times. The same shape on today's keyless reply is about 52 KB against 257 KB, and the keyed view only lists venues pricing now, so it comes out no bigger. The spec pins the mapping on a keyed fixture.

The two smaller ones are done too: the description and instructions no longer name a bookmaker, and oddsrelay.live.spec.ts has a block behind RUN_ODDSRELAY_LIVE=1 (key from ODDSRELAY_KEY) that calls usage and quotes one board, both free. It skips when either variable is unset.

github-actions Bot added a commit that referenced this pull request Oct 16, 2026
@helpcodeai
helpcodeai enabled auto-merge (squash) October 18, 2026 18:02
@helpcodeai

Copy link
Copy Markdown
Contributor

Thanks, this is in good shape. Merged onto current main, the counts check passes at 475 and the catalog suite is clean. I also ran your coverage mapping on its own: it gives exactly the shape your spec pins. One edge case: if a board ever comes back without a bookmakers or exchanges array, from_items fails on null and the transform falls back to the full reply. I pushed a small commit that defaults both (and sports) to empty, so the worst case is an empty board instead of 250 KB. It goes in once CI is green.

@helpcodeai
helpcodeai merged commit 28c176a into HelpCode-ai:main Oct 18, 2026
14 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 18, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants