Skip to main content
Glama
Sofiia7

actually-mcp-server

Actually - What Markets Really Think

A Chrome extension and an MCP server that put prediction-market odds on top of the news you are already reading.

News tells you that "experts are concerned" or that "odds are rising". It rarely tells you a number. The number exists - on a prediction market, where people are betting their own money on the outcome. It just lives in another tab, and finding it means knowing such a market exists in the first place.

Actually closes that gap. Open an article, click the toolbar icon, and the extension matches the text against live Polymarket markets and shows the market's own probability. No account, no wallet, no signup.

Add it to Chrome from the Chrome Web Store - free.

A news article matched to a live Polymarket market

What it does

  • Matches an article to a market. A local embedding model (Xenova/all-MiniLM-L12-v2, ~33 MB) scores the article text against the cached market set, boosted by keyword and number overlap - numbers matter because the encoder is nearly blind to them, and "dip to $57,500" embeds almost identically to "reach $120,000".

  • Runs on your device. Model and WASM runtime are bundled at build time - nothing is fetched from a CDN at install or runtime, and on the default settings the article text never leaves the machine.

  • Reads non-English pages. They are translated to English before matching, using Chrome's own built-in Translator API (local, no network). Every Polymarket question is written in English, and the local model holds 86 Cyrillic tokens out of 30522 - an untranslated Russian headline embeds to noise. Translated, the same headline scores 0.53-0.71 against the market it is actually about, against a 0.35 floor.

    A German article matched to a Berlin election market

  • Trades, optionally. Connect any WalletConnect v2 wallet for limit and market orders, selling, cancelling resting orders, and a positions panel with cost basis and P&L. Keys and funds are never held by us.

  • Serves agents too. The same capabilities are exposed over the Model Context Protocol: check_news, get_market, place_order, sell_order, cancel_order, get_positions.

Related MCP server: Polymarket Predictions MCP

Using the MCP server

The MCP server is published, so it needs no clone and no build. Add it to any MCP client (Claude Desktop, Cursor, and anything else that speaks the protocol):

{
  "mcpServers": {
    "actually": {
      "command": "npx",
      "args": ["actually-mcp-server"]
    }
  }
}

That gives an agent the signal tools - check_news and get_market - with no key and no wallet. Ask it "what do markets think about this?" with a headline and it answers with the market's own price.

The very first launch downloads the package and its local model runtime (about 170 MB), and the first check_news then fetches the 34 MB model. On a slow connection that can take longer than a client waits for a server to start; if yours reports a timeout, run npx -y actually-mcp-server once in a terminal, let it finish, and restart the client. Later launches start in a few seconds.

Trading tools appear only if you supply a key of your own:

"env": {
  "POLYMARKET_PRIVATE_KEY": "0x...",
  "ACTUALLY_MAX_ORDER_USD": "100",
  "ACTUALLY_DAILY_LIMIT_USD": "500"
}

Both caps are enforced server-side against a persisted spend ledger, so an agent cannot talk its way past them by claiming a different price. redeem_position needs a further explicit opt-in (ACTUALLY_ENABLE_REDEEM=true) because it submits a real on-chain transaction and is still in testing.

Full documentation, including every environment variable and the reasoning behind the guards: packages/mcp-server/README.md.

Listed in the official MCP registry as io.github.Sofiia7/actually, on mcpservers.org, and on Glama:

Listed on mcpservers.org

actually MCP server

How it fits together

extension/            Chrome MV3 extension (React popup, offscreen document)
extension/worker/     Cloudflare Worker - API proxy, rate limiting, market cache
packages/core/        Matching, pricing and Polymarket API logic, shared by both clients
packages/mcp-server/  MCP server, published to npm as actually-mcp-server
packages/market-cache-builder/   Cron job that precomputes the market embeddings

The heavy work lives in an offscreen document because MV3 service workers cannot run WASM, hold a WebSocket, or survive long enough to sign an order.

The market cache is 2000 open markets with precomputed embeddings, rebuilt every two hours. Selection blends three orderings - 24h volume, lifetime volume, and recency - because ranking by lifetime volume alone is the wrong shelf for a news tool: a market opened this morning under today's headline has no history and loses to a year-old election market every time.

The Worker exists so no client has to hold a credential. It proxies Polymarket's APIs, serves the precomputed cache, and acts as a remote signer for the relayer, so the builder credential stays on the server and never ships inside an extension.

Running it

npm install
npm run models:fetch -w extension   # bundle the embedding model
npm run build -w extension          # type-check + build to extension/dist

Load extension/dist as an unpacked extension in Chrome. Copy extension/.env.example to .env.local and fill it in first - the build bakes the Worker URL, the WalletConnect project id and the builder code.

npm test --workspaces               # 822 tests across four workspaces

Privacy

Discovery is free and needs no account. There are no content scripts: the page is read only when you click, and only the active tab. On the default settings (local embeddings) the article text does not leave your machine - translation, when the page needs it, also runs locally via the browser's own built-in translator, regardless of embedding provider. Telemetry is opt-in and off by default.

Full policy: https://actually-api.sofiaseremeteva.workers.dev/privacy

Status

The extension is live on the Chrome Web Store. actually-mcp-server is published on npm and listed in the official MCP registry.

Redeeming a resolved position is in testing: builder authentication, neg-risk contract selection and the zero-balance guard are each verified against live services, but no redeem has yet been observed collecting funds end to end.

Viewing odds works everywhere. Opening new positions follows Polymarket's own restrictions: it is unavailable in, among others, the US, the UK, France, Germany, Italy, the Netherlands, Belgium, Poland, Ireland, Australia, New Zealand, Japan, Singapore, Taiwan, Thailand, Brazil, Russia, and the Canadian provinces of Ontario, British Columbia, Alberta and Quebec - there, existing positions can still be sold and resting orders cancelled. Sanctioned jurisdictions are blocked entirely. The check runs on the Worker.

Actually does not provide financial advice.

License

See LICENSE.

Available Tools

2 tools
check_newsCheck news text against prediction marketsA
Read-only

Map a piece of news text to the relevant Polymarket market and return its current YES probability - the market's real, unmodified price, not a number synthesized from the text. That price is the crowd's current bet, not a verdict on whether the news is true. It also does not classify whether the news is dramatized or accurate relative to the market - that interpretation is left to the calling agent, which has both the original text and this market anchor. The probability comes from a precomputed cache refreshed on a cron cadence (can be up to ~2 hours stale) - for a live price before trading, call get_market with the returned marketId. If that cache looks abandoned rather than just late, the response adds cacheStale: true and cacheAgeHours - treat the match as unreliable and prefer get_market/a direct search when present.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover readOnlyHint/openWorldHint, and the description goes far beyond them: it discloses the price is the crowd's bet not a truth verdict, that it does NOT classify dramatization/accuracy, that values come from a cron-refreshed cache up to ~2 hours stale, and that an abandoned cache adds cacheStale/cacheAgeHours. This is unusually rich behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose and return value, and each clause carries real signal (cache caveat, non-classification). It is dense and slightly long with embedded dashes, but almost no sentence is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return burden and does it: YES probability, market match, marketId for follow-up, and cacheStale/cacheAgeHours failure signals. Nothing an agent needs to call and interpret it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

One parameter with 0% schema description coverage, so the schema names 'text' but explains nothing. The description implies it is 'a piece of news text' but adds no length limit, format, or content guidance beyond the schema field name; borderline for a single obvious input.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Map a piece of news text to the relevant Polymarket market') and the exact return (current YES probability), and explicitly distinguishes itself from the sibling by naming get_market as the live-price alternative. An agent can tell what this does without opening anything.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use (map news to a market anchor), when-to-not-rely (stale/abandoned cache), and the alternative (call get_market with the returned marketId before trading). Routing conditions are spelled out, not inferred.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_marketGet a market's price and orderbookA
Read-only

Look up a specific Polymarket market by id: details, live price, and an orderbook snapshot for ONE outcome token. Falls back to a direct Gamma lookup when the id is outside the precomputed cache's top markets by volume.

ParametersJSON Schema
NameRequiredDescriptionDefault
outcomeNoWhich token to price - match this to the side you intend to trade (place_order/sell_order's BUY_YES/SELL_YES → 'Yes', BUY_NO/SELL_NO → 'No'). Defaults to 'Yes'. YES and NO books move somewhat independently, not simply 1 − each other, so quoting the wrong one hands you the wrong price.
marketIdYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so safety is covered, and the description goes further by disclosing the cache-vs-Gamma fallback path — real behavioral context an agent can't get from structured fields. It stops short of noting failure behavior for unknown ids or how deep the orderbook snapshot is.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with the primary purpose, then the fallback caveat. Every clause carries information; no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully enumerates the return payload (details, price, orderbook) and explains the cache fallback. Missing only edge-case context such as not-found handling or orderbook depth, which is minor for a read-only lookup.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 50%: the 'outcome' parameter is richly documented in the schema (including its interaction with BUY_YES/SELL_YES), but marketId has no description anywhere. The description says lookup is 'by id' and hints that ids may fall outside the cached top-volume set, but never clarifies the id format, so compensation is partial.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('look up a specific Polymarket market by id') plus the returned artifacts (details, live price, orderbook snapshot for ONE outcome token). Nothing overlaps with the unrelated sibling check_news, so an agent can place it immediately.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implies the usage context (fetch a single market by id, with an automatic Gamma fallback for uncached ids) but never states when to prefer this over alternatives or what prerequisites exist. The when-to-use detail ('match to the side you intend to trade') lives in the schema, not the description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev0.1.8
    • Changedget_market1 field changed
      • addedInput schema / properties / outcome
        Added value: +{
        +  "description": "Which token to price - match this to the side you intend to trade (place_order/sell_order's BUY_YES/SELL_YES → 'Yes', BUY_NO/SELL_NO → 'No'). Defaults to 'Yes'. YES and NO books move somewhat independently, not simply 1 − each other, so quoting the wrong one hands you the wrong price.",
        +  "enum": [
        +    "Yes",
        +    "No"
        +  ],
        +  "type": "string"
        +}
  2. 2 tool updatesv0.1.7
    • First observedcheck_news
    • First observedget_market

TDQS

A4.1/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct purposes: check_news maps news text to a market and returns a cached probability, while get_market looks up a specific market by id for live details and orderbook. The descriptions explicitly direct the agent to call get_market for a live price, avoiding overlap.

Naming Consistency5/5

Both tools follow a consistent verb_noun snake_case pattern (check_news, get_market), making the naming predictable and easy to parse.

Tool Count3/5

Only two tools are provided, which feels thin for a server that could support broader market exploration (e.g., search, listing). However, they cover the core workflow, so it's borderline rather than severely mismatched.

Completeness3/5

The surface covers news-to-market mapping and single-market live lookup, but lacks operations like searching markets by keyword, listing multiple outcomes, or retrieving orderbooks for all outcomes. These gaps limit an agent's ability to explore beyond the provided news anchor.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables interaction with Polymarket prediction markets through read-only access to market data, events, orderbooks, and user positions, plus authenticated trading capabilities for creating and managing orders.
    1
    -
  • A
    license
    B
    quality
    D
    maintenance
    Enables LLM agents to interact with Polymarket prediction markets, including market discovery, real-time pricing, analytics, account management, and trading with built-in safety guards.
    34
    MIT