# SNHP — free negotiation math + agent memory MCP server

Free game-theory negotiation advisor for agents, plus paid receipted sessions and agent memory.

## Links
- Registry page: https://www.getdrio.com/mcp/io-github-ryuxik-snhp
- Repository: https://github.com/ryuxik/snhp
- Website: https://snhp.dev

## Install
- Endpoint: https://api.snhp.dev/mcp/
- Auth: Not captured

## Setup notes
- Remote endpoint: https://api.snhp.dev/mcp/

## Tools
- negotiate (Negotiate — your optimal next move) - Your math-optimal next move in any price negotiation — free, no account or key needed.

USE THIS WHEN: you're haggling over a single PRICE across multiple back-and-
forth rounds and want a better outcome than winging it. Validated edge: ~12%
better head-to-head (measured on this recommender, n=20 paired LLM
negotiations, 95% CI +6.5-17.4%, p<0.0001). NOT FOR: one-shot or fixed prices
(it'll tell you to just negotiate directly); multi-issue bundles (use
negotiate_bundle — it logrolls across several linked issues); or non-price
decisions like accept-vs-decline a job offer (just reason it through).

You provide only what you already know — no game theory:
  side          "sell" or "buy"
  walk_away     your reservation in dollars (seller=floor/minimum, buyer=ceiling/max)
  target        your aspiration in dollars (seller=high, buyer=low)
  counterparty_offers  their offers so far, in dollars, oldest first
  rounds_left   (optional, default 8) roughly how many back-and-forths remain
  compute_ms    (optional, default 0; EXPERIMENTAL) milliseconds of Monte-Carlo
                rollouts to spend refining the move. 0 = instant closed form.
                Validated to show NO realized edge over the closed form (n=400,
                mc_validation.py) — kept off by default as a research mechanism,
                not a quality improvement. The reply carries a "compute" block

You get back, in dollars:
  {"action": "counter"|"accept"|"walk", "recommended_price": 5387.0,
   "message": "...the best I can do is $5,387.00", "fit": {...},
   "expected_settlement": 4943.5, "confidence": 0.62}

WORKED EXAMPLE — selling a contract, floor $4,000, hope $6,000, the buyer has
bid $4,200 then $4,500:
  negotiate(side="sell", walk_away=4000, target=6000,
            counterparty_offers=[4200, 4500], rounds_left=6)
  -> counter ~$5,387 with a ready-to-send message; ACCEPT once their bid crosses
     the optimal target; WALK if they stay below your floor near the deadline.

Works against ANY counterparty with zero setup. (The verified-peer cooperation
premium is the separate, advanced gt_a2a_* flow on the pro door.)
 Endpoint: https://api.snhp.dev/mcp/
- negotiate_bundle (Negotiate a bundle — logroll linked issues) - Negotiate several linked issues at once by logrolling — free, no account or key needed.

USE THIS WHEN: a deal has more than one issue on the table and they trade off —
a job offer (base + equity + signing), a SaaS contract (price + seats + term +
SLA), any package deal. It concedes on the issues you care about LESS (and the
other side cares about MORE) to win the ones you care about most — a trade that
beats splitting every issue down the middle. For a single PRICE, use
negotiate instead.

Provide `issues`: a list of {"name", "options" (the choices), "my_utility" (how
good each option is to YOU — one number per option, any scale), "their_utility"
(how good each option is to THEM — their preference direction)}. Optionally
`my_priorities` ({issue_name: weight}, how much each issue matters to you) and
`their_offers` (their packages so far as {issue_name: option}, oldest first —
this is what lets it INFER their priorities). Returns {action, recommended_offer
(issue -> option), message, my_utility, their_expected_utility,
inferred_their_priorities, trade_logic, fit, confidence, acceptance_probability}.

Validated (separately from the single-issue +12%): returns a Pareto-efficient
package that beats naive "split-every-issue-down-the-middle" bargaining by ~40%
joint surplus (300 random 4-issue profiles). HONEST CAVEAT: the priority
INFERENCE layered on top is weak (recovery r≈0.3) and currently adds only ~1%
(and can be slightly NEGATIVE against some opponents) over the same engine run
with no inference — so the proven value today is the efficient-package search,
not (yet) the logrolling edge.

Optional timing refinement: pass `rounds_left` (bargaining rounds remaining)
with `compute_ms` > 0 to spend that many ms of Monte-Carlo rollouts choosing
WHICH package to hold for as the other side concedes over the rounds — a firmer
package closes later (discounted) than a generous one. 0 = the instant
closed-form package; the reply then carries a `compute` block. Modest by design
(never worse than the closed form in-model; helps on a minority of deals).

Example: a SaaS contract — you most want a low price_per_seat, can flex on
seats/term/SLA. negotiate_bundle(issues=[
  {"name":"price_per_seat","options":["$50","$40","$30"],"my_utility":[0,0.5,1],"their_utility":[1,0.5,0]},
  {"name":"sla","options":["99%","99.9%"],"my_utility":[0,1],"their_utility":[1,0]} ...],
  my_priorities={"price_per_seat":0.55,"sla":0.1,...}, their_offers=[...])
  -> a full package that gives ground on SLA to hold the price.
 Endpoint: https://api.snhp.dev/mcp/
- score_deal (Score a deal against the Pareto frontier) - Score how good a deal is against your floor/target — free, no account or key needed.

Score a settled package against the exact Pareto frontier — the SNHP
leaderboard metric ("dollars left on the table") for YOUR negotiation.

Args:
    issues: one dict per issue: {"name": str, "options": [labels],
        "my_utility": [per-option value to me], "their_utility":
        [per-option value to them]} — both sides' TRUE per-option values.
    my_weights: {issue_name: weight} — my true priorities (any scale).
    their_weights: {issue_name: weight} — their true priorities.
    package: the settled deal, {issue_name: option_label}.
    notional: deal size in dollars for the dollars-left framing.

Returns realized joint welfare, the frontier best, the naive middle-split
baseline, frontier capture, logroll capture, and dollars_left_on_table.
 Endpoint: https://api.snhp.dev/mcp/
- auction_bid (Optimal auction bid) - The optimal bid when you're bidding in an auction — free, no account or key needed.

USE THIS WHEN: you're a bidder and want the bid that maximizes your expected
surplus without overpaying. NOT for running an auction (use
auction_reserve) or 1:1 haggling (use negotiate).

Provide: auction_format ("first_price" sealed bid, "second_price_vickrey",
or "english_ascending"); my_valuation (what the item is worth to YOU, in $);
n_competing_bidders (how many OTHER bidders, not counting you); and
competitor_value_prior — a rough model of what rivals will pay, e.g.
{"family":"uniform","params":{"low":0,"high":6000}} (or
{"family":"lognorm","params":{"mu":8.5,"sigma":0.4}}). Estimate it if unknown.
Returns {optimal_bid, expected_surplus, win_probability, dominant_strategy,
rationale} — bid and surplus in the SAME $ you passed in.

Example: a domain worth $5,000 to you, 4 rivals who'd pay up to ~$6,000, in a
sealed first-price auction -> auction_bid(auction_format="first_price",
my_valuation=5000, n_competing_bidders=4,
competitor_value_prior={"family":"uniform","params":{"low":0,"high":6000}})
-> optimal_bid ~$4,000, win_probability ~0.48.
 Endpoint: https://api.snhp.dev/mcp/
- auction_reserve (Revenue-optimal reserve price) - The revenue-optimal reserve price when you're selling — free, no account or key needed.

USE THIS WHEN: you're running an auction or sale with multiple bidders and need
the floor price (minimum bid you'll accept) that maximizes your expected
revenue. NOT for one-on-one haggling (use negotiate for that).

Provide: n_bidders (how many bidders), seller_valuation (what the item is worth
to YOU, in $), and bidder_value_prior — a rough model of what bidders will pay,
e.g. {"family":"uniform","params":{"low":2000,"high":8000}}. Estimate it if
unknown. Returns the reserve price and expected revenue.

Example: a painting, ~5 bidders, worth $1,000 to you, bidders likely pay
$2,000–$8,000 -> auction_reserve(n_bidders=5, seller_valuation=1000,
bidder_value_prior={"family":"uniform","params":{"low":2000,"high":8000}}).
 Endpoint: https://api.snhp.dev/mcp/
- clearance_price (Clearance price & markdown schedule) - Best price plus markdown schedule to clear stock by a deadline — free, no account or key needed.

USE THIS WHEN: you must sell a FIXED number of units before a cutoff and
demand arrives over time — event tickets, perishable inventory, end-of-life
stock. NOT for 1:1 haggling (negotiate) or auctions (auction_bid/reserve).

Provide: inventory (units to sell); horizon_seconds (selling window in
SECONDS — 14 days = 14*24*3600 = 1209600); arrival_rate_per_second (expected
shoppers per second = expected total shoppers / horizon_seconds); and
buyer_arrival_prior — a rough model of willingness-to-pay, e.g.
{"family":"uniform","params":{"low":40,"high":150}}. Returns {static_price
(one good fixed price), static_expected_revenue, dynamic_schedule (list of
{t_seconds, recommended_price} markdown waypoints), sellthrough_rate,
rationale} — all prices in the SAME $ as your prior.

Example: 200 tickets, 14-day window, ~600 shoppers willing to pay $40-$150 ->
clearance_price(inventory=200, horizon_seconds=1209600,
arrival_rate_per_second=600/1209600,
buyer_arrival_prior={"family":"uniform","params":{"low":40,"high":150}})
-> static_price ~$112, schedule marks down $114 -> ~$76 as the deadline nears.
 Endpoint: https://api.snhp.dev/mcp/
- stable_match (Stable matching (Gale–Shapley)) - Match two groups by their rankings so no pair wants to swap — free, no account or key needed.

A STABLE matching: USE THIS WHEN you're assigning two sides to each other by
mutual preference — interns<->teams, students<->schools, mentors<->mentees —
and want a result with no "blocking pair" (no person+slot that both prefer
each other over what they got).

Provide proposers and receivers, each a list of {"id": name,
"preferences": [ids of the OTHER side, most-wanted first]}. Receivers may add
"capacity" (default 1) to accept several. Returns {matching (name -> name),
unmatched_proposers, blocking_pairs (empty list = provably stable),
n_proposals}. NOTE: the result is PROPOSER-optimal, so put the side you want
to favor in `proposers`.

Example: stable_match(
    proposers=[{"id":"Ana","preferences":["Growth","Core"]},
               {"id":"Ben","preferences":["Core","Growth"]}],
    receivers=[{"id":"Growth","preferences":["Ben","Ana"]},
               {"id":"Core","preferences":["Ana","Ben"]}])
-> matching {"Ana":"Growth","Ben":"Core"}, blocking_pairs [].
 Endpoint: https://api.snhp.dev/mcp/
- memory_save (Save agent memory (blind locker)) - Persistent memory for your agent across sessions — save now, load in any later session.

You encrypt before saving; the store holds only ciphertext (blind custody)
and signs a receipt over its hash — it cannot read your memory.

Saving uses your prepaid wallet; a new key's 50¢ starter credit covers
your first saves, and loading it back (memory_load) is free. `blob_b64`
is YOUR ciphertext as base64 — encrypt BEFORE saving; keys never transit,
contents are never logged, so a breach leaks only sealed boxes. Charged a
thin flat fee ONLY on durable store (empty/oversize/unencodable is
uncharged). ttl_seconds is clamped to [60s, 7d] and the effective
expires_at is returned. The receipt's content_hash is over YOUR
ciphertext, so you can prove what you stored without the store ever seeing
plaintext. Endpoint: https://api.snhp.dev/mcp/
- memory_load (Load agent memory) - Load a memory you saved in an earlier session — retrieval is free.

Get back an encrypted blob you parked earlier (the blind locker) by its
claim `ticket`. Returns {ok, blob_b64, size_bytes, expires_at} — the
ciphertext you saved, which only YOU can decrypt. A wrong owner reads as a
missing ticket; an expired TTL is `expired`; a lost at-rest key is
`at_rest_key_unavailable`. Free (the save settled it). Endpoint: https://api.snhp.dev/mcp/
- session_open (Open a $2 receipted session) - Open a $2 receipted negotiation session: deterministic, replayable, every move signed.

PAID ($2 once, from your credit balance) — the $2 covers EVERY move of
this negotiation (up to 10 moves, 7 days), tuned to the category. A new
key's 50¢ starter credit is a taste, not enough for a session — top up
first. category: resale | supply | retail. side: buy | sell.
walk_away = your true floor (sell) / ceiling (buy) — private,
never crossed. Pass their_offers to get the first move back
immediately with the session. Subsequent moves: session_advise
with the session_id — no further charge. Endpoint: https://api.snhp.dev/mcp/
- session_advise (Session move — next single-price offer) - Your next move inside a receipted session (single-issue) — no additional charge (the $2 at session_open covered it).

Pass the FULL offer history each time, oldest first. Returns move, exact
price, ready-to-send message, and the receipt (why[], context_hash,
deterministic compute block). Endpoint: https://api.snhp.dev/mcp/
- session_bundle (Session move — multi-issue bundle) - Multi-issue logrolled advice inside a receipted session — no additional charge.

The logrolling tier, the thing the free tool does NOT have. Trade the
issues you care less about for the ones you value: issues = [{name,
options, my_utility (per option), their_utility (your read of their
direction)}]; their_offers = packages they've tabled, oldest
first. Returns the recommended package, trade logic, inferred
counterparty priorities, acceptance probability, and the receipt.
Deterministic closed form — no rollout theater. The package is
guaranteed to clear YOUR stated BATNA (enforced, not promised). Endpoint: https://api.snhp.dev/mcp/
- session_close (Close session & get the signed receipt) - Close a receipted session and get the signed summary receipt.

Optional — sessions also expire on their own — but closing timestamps the
outcome, which helps the machine learn real round-counts per
category. Returns the `closed` flag AND a signed session-summary
receipt (GAUNTLET #4) — moves count, total charged (one $2 open), and
the per-move context_hashes — to hand your principal. An unknown session
or key mismatch leaves `closed` false and returns an `error` instead of
the receipt (indistinguishable, so a session id can't be probed). Endpoint: https://api.snhp.dev/mcp/
- store_catalog (Store catalog & wallet balance) - See what's on the shelf — free, no key needed: prices, predicates, receipt scheme, and your balance.

THE STORE: one counter, one prepaid wallet, many slots. One read covers
the whole shelf — the commodity slots, the blind locker (agent memory),
and the paid receipted-session SKU (folds in what nextmove_catalog used
to report separately).

Every commodity slot settles ON DELIVERY: the wallet is debited only
when a machine-checkable predicate passes — a failed fetch is never
charged, because here you cannot pay for nothing. Each receipt names
the backend that served and its EXACT wholesale cost (passthrough, no
per-call markup); the counter's cut is a published fee on wallet
top-ups, not on the calls — 5% + a fixed 30¢ per transaction (the 30¢
is the card rail's own per-transaction toll, passed through).

Every new key gets a one-time 50¢ starter credit — unconditional, no
card — enough to taste the shelf before funding it. Don't see the
capability you need? store_request logs it; unmet demand decides what
gets stocked next. Returns the money unit (millicents, 1000 per cent),
per-slot {tier, max_price_millicents, predicate_id, request_doc,
serving-backend ids}, the anchor SKUs, the paid_session card, and the
two pricing facts. Never returns key material. Endpoint: https://api.snhp.dev/mcp/
- store_request (Request a capability / check a filing) - Ask for a capability we don't sell yet — free; filings are public and drive what we stock.

Two reads in one tool (absorbs the old store_request_status /
nextmove_request): pass `request_id` to RE-QUERY a filing's status
instead of filing anew — returns {found, request_id, status, status_note,
filed_at, door, text} (found: false on an unknown id). Without a
request_id it FILES a new ask and returns {request_id, status, watch,
check}: every filing is logged verbatim (size-capped, stored as data,
never rendered raw) and gets an id you can come back to (GAUNTLET #5).
Check any filing with GET /v1/store/request/{id}; the public count is
GET /v1/store/requests. Unmet demand decides what gets stocked next — the
shelf writes itself from what agents ask for and can't get.

Pass watch=True WITH an api_key when filing to flag the ask for a heads-up
on a status flip (poll store_my_requests to see it — poll-based, no push);
an anonymous watch is ignored, and the chosen flag is echoed as `watch`. Endpoint: https://api.snhp.dev/mcp/

## Resources
Not captured

## Prompts
Not captured

## Metadata
- Owner: io.github.ryuxik
- Version: 0.4.0
- Runtime: Streamable Http
- Transports: HTTP
- License: Not captured
- Language: Not captured
- Stars: Not captured
- Updated: Jul 23, 2026
- Source: https://registry.modelcontextprotocol.io
