
Company News
Jerod Santo Joins Socket as Head of Media
Allow myself to introduce... myself.
@riv-io/mcp
Advanced tools
Riv MCP server — spend authorization and governed trading tools over the Riv API (policy engine + venue gateway).
MCP server for Riv — the entry point for connecting agents. Instead of writing the
HTTP authorization call into your agent's code, the developer connects riv-mcp as an
MCP server in their client and the agent gets the authorize and get_activity tools
ready to use.
It's a thin shell over the Riv API (POST /api/v1/authorize and
GET /api/v1/activities): it doesn't reimplement authentication, the decision engine or
the ledger — it just receives the tool call, calls the HTTP API with the riv_key and
returns the result.
authorize({ amount, currency, description?, category? })Asks Riv whether a transaction is allowed before executing it.
amount (number, > 0, up to 2 decimals) — the transaction value.currency (string) — currency, e.g. BRL, USD.description (string, optional) — description for audit.category (string, optional) — spend category (e.g. inference, saas);
per-category mandates use this. Normalized (lowercased) on the server; with no
category, only general policies apply.Returns a text with the governance decision:
Decision: ALLOW | BLOCK | REQUIRE_APPROVAL
Reason: <policy reason>
activityId: <ledger record id>
BLOCK and REQUIRE_APPROVAL are valid decisions (not errors). Real call failures
— invalid credential (401), invalid input (400) or network — return with
isError: true and a distinct message, so the agent doesn't confuse "failure" with
"block".
get_activity({ activityId?, limit? })Queries the Riv ledger — always scoped to the agent itself (the riv_key).
activityId (string UUID, optional) — point lookup: the result of a specific
authorization, using the id returned by the authorize tool.limit (integer 1–50, optional, default 10) — how many recent activities to return
in the statement. Ignored when activityId is provided.Without activityId, returns the recent statement. Each line:
<createdAt ISO> APPROVED | PENDING | BLOCKED | REJECTED <amount> <currency> (<type>)
activityId: <id>
category: <if any>
description: <if any>
A missing activityId (or one from another agent) → 404 and isError: true.
PENDING is resolved by a human in the Riv dashboard: it becomes APPROVED (starts
counting toward accumulated spend) or REJECTED (doesn't count). BLOCKED is always an
engine verdict. Query the activity again to see the outcome.
Transport: stdio (local). The client spawns the server and talks over stdin/stdout.
{
"mcpServers": {
"riv": {
"command": "node",
"args": ["/path/to/riv/mcp/dist/index.js"],
"env": {
"RIV_API_KEY": "riv_...", // the agent's credential (required)
"RIV_API_URL": "http://localhost:3000" // API base (defaults to this value)
}
}
}
}
Once published to npm, you can skip the local path and run it with npx:
{
"mcpServers": {
"riv": {
"command": "npx",
"args": ["-y", "@riv-io/mcp"],
"env": { "RIV_API_KEY": "riv_...", "RIV_API_URL": "https://riventa.dev" }
}
}
}
RIV_API_KEY — required; the riv_key issued when you connect the agent in Riv.
Without it the server exits on startup with an error on stderr.RIV_API_URL — optional; defaults to http://localhost:3000 (local dev). For agents
in production, use https://riventa.dev. Validated on startup: only http:
or https:, and https:// is required unless the host is localhost,
127.0.0.1 or [::1] (the riv_key travels in the Authorization header and must
not cross the network in the clear). An invalid URL exits with an error on stderr.cd mcp
npm install
npm run build # tsc → dist/
npm run typecheck # type check without emitting
# E2E (from the repo root; the harness spins up the app on an ephemeral port —
# requires `npm run build` at the root and `npm run build` here in mcp/):
# node --env-file=.env scripts/verify-mcp.mjs
Publicar no npm é passo de go-live — nunca parte do fluxo normal de desenvolvimento.
npm publish roda prepublishOnly automaticamente (typecheck + build);
se qualquer um falhar, nada é publicado.npm pack --dry-run:
apenas dist/ (+ package.json, README.md, LICENSE) deve aparecer —
nunca src/, testes, .env ou qualquer configuração local.@riv-io/* (versões saem em lote).Seven tools expose Riv's governed trading surface. Point your agent at this
MCP server instead of a raw exchange MCP: every order goes through Riv's
policy engine and gateway (leverage caps, position limits, loss halts,
trading hours, human approval), and executed orders carry Riv's builder code.
BLOCK and REQUIRE_APPROVAL are normal outcomes, not errors — read the
Reason/ReasonCode and adapt (reduce size or leverage, switch asset, or
wait for approval).
place_order({ asset, side, orderType, notional, leverage, reduceOnly?, limitPrice?, tif?, expiresAfterSeconds? }) — evaluates the order against
the org's trading policies and, with an active venue connection, submits
it. Returns Decision, Reason, ReasonCode, Executed, VenueOrderId
and the ledger activityId. market executes immediately (IoC); limit
requires limitPrice (submitted literally — prices the venue tick cannot
represent are rejected, never altered), rests on the book (execution.status: resting) and supports tif (gtc default, alo post-only) and
expiresAfterSeconds (auto-cancel if unfilled). Resting orders are tracked
by Riv until filled (partial fills included), canceled or expired; the kill
switch cancels them at the venue.
Two independent state levels (see docs/api/trading.md in the Riv
repo for the full HTTP contract): the governance decision (Decision: ALLOW / status: approved) means the policies permitted the order; only
the execution object says whether the venue actually executed it. An
approved order can still fail at the venue (execution.status: "failed" with the venue's literal reason). Deprecated: the top-level
Executed/VenueOrderId fields remain for compatibility (removal date
TBD) — read execution.status / execution.venueOrderId instead.
get_positions() — open positions from Riv's view of the account
(refreshed from the venue when stale; may take a few seconds).
get_account_state() — equity, peak equity, daily realized PnL,
consecutive losses and open positions — the same state the policies
evaluate against.
get_market_data({ asset }) — read-only mid/mark price, hourly funding
rate and open interest. No custodial connection required.
cancel_order({ asset, venueOrderId }) — cancels a resting order via the
gateway. A failed cancel (e.g. already filled) is a normal outcome.
close_position({ asset }) — closes the position with a governed
reduce-only market order in the opposite direction (same policy engine as
place_order). Reduce-only orders pass ONLY the three loss halts
(max_daily_loss, max_drawdown_halt, consecutive_loss_halt) by
design — trading hours, leverage caps, asset lists, position size and
notional threshold still apply, and a suspended connection (kill switch)
blocks them like any other order.
list_trading_policies() — human-readable summary of the policies in
effect. With no policies, all orders are blocked by default (fail-closed).
authorize/get_activity tools (the shared
10s timeout landed in 0.2.0).FAQs
Riv MCP server — spend authorization and governed trading tools over the Riv API (policy engine + venue gateway).
The npm package @riv-io/mcp receives a total of 216 weekly downloads. As such, @riv-io/mcp popularity was classified as not popular.
We found that @riv-io/mcp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Company News
Allow myself to introduce... myself.

Research
/Security News
A Twitch browser extension on Chrome and Firefox forwards users’ live OAuth session tokens through proxies controlled by a Russian bot service.

Security News
Anthropic found biased reasoning and recklessness drove Claude Mythos 5 to publish malware on PyPI and compromise a security vendor.