Prediction market integration for Hermes Agent -- search, compare, and trade across prediction market exchanges via pmxt
Project description
hermes-pmxt
Prediction market integration for Hermes Agent. Search markets, compare prices, detect arbitrage, and trade across prediction market exchanges via pmxt (>= 2.50.0).
What This Is
A Hermes skill + Python toolset that gives any Hermes agent real-time access to prediction markets. Instead of hallucinating probabilities, the agent checks actual market prices.
User: "Will Trump win 2028?"
Agent: *calls pmxt_search + pmxt_quote*
Agent: "The market implies a 1.9% chance (No: 98.1%). Polymarket is pricing this very low."
Installation
Install directly with pip, matching the one-command style used by Hermes plugins such
as Mnemosyne. You do not need to clone this repository unless you are developing it.
pip install "git+https://github.com/0xharryriddle/hermes-pmxt.git"
For local development from a checkout:
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
Hermes Skill Setup
After installing the package, copy or symlink skill/SKILL.md into your Hermes skills
directory so agents know when and how to use the tools. Example:
mkdir -p ~/.hermes/skills/pmxt
cp skill/SKILL.md ~/.hermes/skills/pmxt/SKILL.md
If your Hermes install supports GitHub-backed skill/plugin installation, point it at
https://github.com/0xharryriddle/hermes-pmxt and enable the pmxt skill.
Modes
hermes-pmxt supports three runtime modes:
| Mode | Config | Behavior |
|---|---|---|
| Hosted | Set PMXT_API_KEY |
Talks to https://api.pmxt.dev. Handles exchange connections, caching, and rate limits automatically. Recommended for most users. |
| Custom | Set PMXT_API_URL or PMXT_BASE_URL |
Points to any PMXT-compatible server. |
| Local Sidecar | No API key/URL set | Assumes PMXT core is running at http://localhost:3847. For self-hosting / development. |
Check your current mode:
from hermes_pmxt import pmxt_runtime_status
print(pmxt_runtime_status())
Quick Start
from hermes_pmxt import pmxt_search, pmxt_quote, pmxt_runtime_status
# Check status
print(pmxt_runtime_status())
# Search
result = pmxt_search("bitcoin", exchange="polymarket", limit=5)
for m in result["data"]:
prices = m.get("outcomes", [])
if prices:
print(f"{m['title'][:60]}: YES={prices[0]['price']*100:.1f}%")
# Quote
quote = pmxt_quote("bitcoin reach", exchange="polymarket")
print(f"YES: {quote['data']['yes_pct']} NO: {quote['data']['no_pct']}")
Data Model
Event (broad topic)
└── Market (tradeable question)
├── Outcome "Yes"
└── Outcome "No"
When users ask about a topic, start with events (pmxt_events), then drill down to
markets and outcomes.
Tools
Discovery & Research
| Function | Auth | Description |
|---|---|---|
pmxt_search(query, exchange?, limit?, sort?, search_in?, slug?) |
No* | Search markets by keyword |
pmxt_events(query, exchange?, limit?, sort?, search_in?, slug?) |
No* | Search event groups |
pmxt_quote(identifier, exchange) |
No* | Get YES/NO probabilities |
pmxt_order_book(outcome_id, exchange, limit?) |
No* | Order book depth |
pmxt_ohlcv(outcome_id, exchange, resolution?, limit?) |
No* | Price candles |
pmxt_trades(outcome_id, exchange, limit?) |
No* | Recent trades |
pmxt_execution_price(outcome_id, exchange, side, amount) |
No* | Slippage estimate |
Cross-Venue & Arbitrage
| Function | Auth | Description |
|---|---|---|
pmxt_compare_market(query, exchanges?, limit?) |
No* | Compare prices across exchanges |
pmxt_arbitrage_scan(query, exchanges?, threshold?) |
No* | Detect arbitrage opportunities |
pmxt_call("compareMarketPrices", "router", ...) |
No* | Native router comparison |
pmxt_call("fetchArbitrage", "router", ...) |
No* | Native arbitrage search |
pmxt_call("fetchHedges", "router", ...) |
No* | Hedging opportunities |
Portfolio & Account
| Function | Auth | Description |
|---|---|---|
pmxt_balance(exchange) |
Yes | Account balance |
pmxt_positions(exchange) |
Yes | Open positions |
pmxt_portfolio(exchanges?) |
Yes | Cross-exchange portfolio |
Trading (All Destructive -- Require Explicit Confirmation)
| Function | Auth | Description |
|---|---|---|
pmxt_build_order(...) |
Yes | Build/sign order without submitting (SAFE) |
pmxt_submit_order(built, exchange, confirmed=True) |
Yes | Submit a pre-built order |
pmxt_cancel_order(order_id, exchange, confirmed=True) |
Yes | Cancel an open order |
pmxt_order(...) |
Yes | Legacy one-step order (prefer build+submit) |
Generic API Call
| Function | Auth | Description |
|---|---|---|
pmxt_call(method, exchange, ...) |
Varies | Generic PMXT API call with safety checks |
Server & Diagnostics
| Function | Auth | Description |
|---|---|---|
pmxt_runtime_status() |
No | Full runtime status |
pmxt_list_exchanges() |
No | Known/available exchanges |
pmxt_server_status() |
No | Sidecar diagnostics |
pmxt_server_start() |
No | Start sidecar |
pmxt_server_stop() |
No | Stop sidecar |
* Read-only tools work without credentials in local sidecar mode. Hosted mode requires PMXT_API_KEY for all operations.
Trading Safety
Destructive operations (create, submit, cancel orders) require explicit user confirmation.
# SAFE: Build order for preview (does NOT place any order)
built = pmxt_build_order(
market_id="market-uuid",
outcome="yes",
side="buy",
order_type="limit",
amount=10,
price=0.55,
exchange="polymarket",
)
# DESTRUCTIVE: Submit requires confirmed=True
result = pmxt_submit_order(built, "polymarket", confirmed=True)
# Without confirmed=True:
result = pmxt_submit_order(built, "polymarket")
# => {"success": False, "error": "Operation 'submit_order' is destructive..."}
Supported Exchanges
hermes-pmxt knows about 17 venues including:
polymarket/polymarket_uskalshi/kalshi-demolimitlessprobable/baozi/myriad/opinionmetaculus/smarketsgemini-titan/hyperliquid/suibets/rainmock/router
Actual availability depends on the installed pmxt build. Run pmxt_list_exchanges() to check.
Environment Variables
# Hosted mode (recommended)
export PMXT_API_KEY="pmxt_live_..."
export PMXT_WALLET_ADDRESS="0x..."
export PMXT_PRIVATE_KEY="0x..."
# Custom server
export PMXT_API_URL="https://your-server.com"
# or
export PMXT_BASE_URL="https://your-server.com"
# Venue-specific (self-hosted mode)
export POLYMARKET_PRIVATE_KEY="0x..."
export POLYMARKET_PROXY_ADDRESS="0x..." # Optional
export KALSHI_API_KEY="..."
export KALSHI_PRIVATE_KEY="..."
export LIMITLESS_API_KEY="..."
export LIMITLESS_PRIVATE_KEY="..."
export POLYMARKET_US_API_KEY="..."
export POLYMARKET_US_PRIVATE_KEY="..."
Project Structure
hermes-pmxt/
├── hermes_pmxt/
│ ├── __init__.py # Public API exports
│ ├── config.py # Runtime config and mode detection
│ ├── exchanges.py # Exchange initialization + normalization
│ ├── registry.py # Tool registry with safety annotations
│ ├── shaper.py # Result shaping for LLM context
│ └── tools.py # Core tool functions
├── skill/
│ └── SKILL.md # Hermes agent skill instructions
├── examples/
│ └── demo.py # Interactive demo
├── tests/
│ ├── conftest.py # Test path setup
│ ├── test_exchanges.py # Exchange wiring unit tests
│ └── test_tools.py # Unit + integration tests
├── pyproject.toml
└── README.md
Testing
# Unit tests (no pmxt required)
python3 -m pytest -q -m unit
# All non-destructive tests
python3 -m pytest -q -m "not trading"
# Integration tests (need pmxt + sidecar/API)
python3 -m pytest -q -m integration
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hermes_pmxt-0.3.0.tar.gz.
File metadata
- Download URL: hermes_pmxt-0.3.0.tar.gz
- Upload date:
- Size: 32.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0192f2fe2f59714972b1e6e8b12007ab7367a86a6d64c2e8fcf9340646555f09
|
|
| MD5 |
1800cce3b2c3817e739334c781d7a8b8
|
|
| BLAKE2b-256 |
be3e02867140a9cf0b7d0876e6ff36d2c4b09b2671410c2095199fe00ad7c8c4
|
Provenance
The following attestation bundles were made for hermes_pmxt-0.3.0.tar.gz:
Publisher:
workflow.yml on 0xharryriddle/hermes-pmxt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hermes_pmxt-0.3.0.tar.gz -
Subject digest:
0192f2fe2f59714972b1e6e8b12007ab7367a86a6d64c2e8fcf9340646555f09 - Sigstore transparency entry: 1878547507
- Sigstore integration time:
-
Permalink:
0xharryriddle/hermes-pmxt@f855a4f9e1df021b02b0954928ca0677d37c54d1 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/0xharryriddle
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@f855a4f9e1df021b02b0954928ca0677d37c54d1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file hermes_pmxt-0.3.0-py3-none-any.whl.
File metadata
- Download URL: hermes_pmxt-0.3.0-py3-none-any.whl
- Upload date:
- Size: 24.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3ffce0194d0fe45be6e0fc8e0bdf96b27aaec8c57a73d60d961369f998062e3
|
|
| MD5 |
3c36bd25acdbe127f131c9a164077a94
|
|
| BLAKE2b-256 |
2bcc63d9414399cfee3f5be101c22546429ebca0014485e17b4f056034886206
|
Provenance
The following attestation bundles were made for hermes_pmxt-0.3.0-py3-none-any.whl:
Publisher:
workflow.yml on 0xharryriddle/hermes-pmxt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hermes_pmxt-0.3.0-py3-none-any.whl -
Subject digest:
e3ffce0194d0fe45be6e0fc8e0bdf96b27aaec8c57a73d60d961369f998062e3 - Sigstore transparency entry: 1878547633
- Sigstore integration time:
-
Permalink:
0xharryriddle/hermes-pmxt@f855a4f9e1df021b02b0954928ca0677d37c54d1 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/0xharryriddle
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@f855a4f9e1df021b02b0954928ca0677d37c54d1 -
Trigger Event:
push
-
Statement type: