trii-cli
v0.0.11
Published
Manage your Trii investment account via terminal, REST API, or MCP server for Claude
Maintainers
Readme
Install
# From npm (requires Bun)
bun add -g trii-cli
# Or clone and link
git clone https://github.com/camilocbarrera/trii-cli.git
cd trii-cli
bun install
bun linkLogin
trii login # Opens browser — log in with your Trii account + 2FAOr via API proxy (headless):
trii connect <username> <password> [api-url]trii login is a capture-mode browser session. It launches a real Chromium, you log in with email/password and the 2FA SMS code, and the CLI snapshots your cookies (sk2, cf_clearance, user, ...) into ~/.trii-config.json for subsequent commands to reuse.
CLI Usage
Investing
trii portfolio # List positions with quantity + avg cost
trii balance # Cash + invested + total value
trii orders 2026-01-01 2026-04-30 # Order / trade history
trii movements # Cash-in / cash-out ledger (PSE)
trii dividends 2026-04-01 2026-05-31 # Dividends calendarTrading ⚠️ moves real money
# Dry run — prints the exact request that WOULD be sent, zero network calls
trii buy TERPEL 1 --limit 11500
trii sell TERPEL 1 --limit 12000
# Real order — prompts for "yes" confirmation
trii buy TERPEL 1 --limit 11500 --confirm
# Real order — no prompt (for scripts)
trii sell TERPEL 1 --limit 12000 --confirm --yesEvery trading command is dry-run by default. To actually submit, you must add --confirm AND type yes at the prompt (or pass --yes to skip the prompt in scripts). Orders are hard-capped at 200,000 COP via the TRII_MAX_ORDER_COP environment variable — bypass with --yolo only if you know what you're doing. Market orders are currently disabled; --limit <price> is required. See Trading safety below.
Session
trii whoami # Show session info + portfolio
trii health # Check API proxy status
trii logout # Disconnect and clear sessionREST API
trii server # Starts on http://localhost:3210| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | /api/portfolio | Positions with quantity + avg cost |
| GET | /api/positions | Alias of /api/portfolio |
| GET | /api/balance | Normalized cash + invested + total |
| GET | /api/balance/snapshot | Raw Trii balance snapshot (cash, titles, funds, US cash) |
| GET | /api/orders?from=Y&to=Z | Order history |
| GET | /api/movements | Cash-in / cash-out movements |
| GET | /api/dividends?from=Y&to=Z&country=CO | Dividends calendar |
| GET | /api/whoami | Session info |
Trading endpoints are intentionally not exposed over REST — the local server has no authentication and open CORS, so putting buy/sell behind it would let anything on your machine submit real orders.
MCP Server (Claude Integration)
The Trii CLI includes an MCP (Model Context Protocol) server so Claude can query your investment account natively. Trading tools are deliberately excluded for safety.
Setup for Claude Code
Add .mcp.json to your project root:
{
"mcpServers": {
"trii": {
"command": "bun",
"args": ["run", "/path/to/trii-cli/src/mcp/index.ts"]
}
}
}Setup for Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"trii": {
"command": "/path/to/.bun/bin/bun",
"args": ["run", "/path/to/trii-cli/src/mcp/index.ts"]
}
}
}Use the full path to
bunfor Claude Desktop (runwhich bunto find it).
Available Tools
| Tool | Description |
|------|-------------|
| login | Connect to Trii via API proxy |
| logout | Disconnect and clear session |
| get_positions | List stock positions with quantity + avg cost |
| get_balance | Normalized cash + invested + total summary |
| get_balance_snapshot | Full raw balance snapshot (cash, titles, funds, US cash) |
| get_orders | Order history within a date range |
| get_cash_movements | PSE deposits / withdrawals ledger |
| get_dividends | Dividends calendar |
| session_info | Current session mode, expiry, and connection status |
Architecture
src/
constants.ts → Hosts, action hashes, session TTL
http.ts → Next.js Server Action client (RSC stream parser)
config.ts → Config load/save with Zod validation
formatters.ts → Currency + date formatting (es-CO / COP)
schemas/ → Zod schemas (config, position, order, trade, dividend, trii raw)
services/ → Business logic (shared by CLI, REST + MCP)
auth.ts → Proxy login / logout
portfolio.ts → getPositions, getBalance, getBalanceSnapshot
order.ts → getOrders (with client-side date filtering)
transactions.ts → getCashMovements
dividend.ts → getDividends
trade.ts → previewTrade + placeTrade (direct Server Action)
fees.ts → Trii's 12,500 COP + 19% IVA formula
market.ts → Stub — see "Not implemented"
api/app.ts → Hono REST API
mcp/index.ts → MCP server (9 tools for Claude)
commands/ → CLI commands (standalone scripts)
_trade.ts → Shared buy/sell flow (safety rails, preview, confirm)
ui/ → Terminal formatting (chalk, tables, spinners, ASCII banner)
index.ts → CLI entry point
server.ts → REST server entry pointHow it talks to Trii
web.trii.co is a Next.js App Router site. All authenticated data flows through React Server Actions — POST web.trii.co/<page> with a Next-Action: <hash> header and a JSON-array body. The response is an RSC stream where the return value lives on the line starting with 1:. src/http.ts implements this calling convention (including the Next-Router-State-Tree tree-builder) once; every service on top of it is just "pick an action hash, shape the arguments, parse line 1".
Auth is cookie-based: sk2 is the session, cf_clearance satisfies Cloudflare, and a couple of profile cookies (user, country) tag along. We persist them in ~/.trii-config.json after login.
Not implemented
- Market data / charts.
api-multi.trii.ws/prices/...sits behind Cloudflare TLS fingerprinting, locks CORS toweb.trii.co, and returns a custom binary format (not JSON) that the Trii SPA decodes client-side.src/services/market.tsis a documented stub. Reverse-engineering the binary payload is left as an exercise. - Market orders.
trii buy/trii sellrequire--limit <price>. Without a live quote source we can't compute the fee or show you a trustworthy preview for a market order.
Type Safety
All Trii responses are validated with Zod before the CLI touches them:
- Raw Trii server-action payloads →
schemas/trii.ts(positions, orders, transactions, balance, dividends) - Normalized CLI / MCP output →
schemas/position.ts,schemas/order.ts,schemas/trade.ts,schemas/dividend.ts - Config → discriminated union (
directcookie mode |apiproxy mode) - Errors →
TriiErrorwithstatusCode+isSessionExpiredso commands can print a clean "runtrii loginto reconnect"
Trading safety
Read this before you run
trii buyortrii sellwith--confirm.
The trading commands move real money on your brokerage account. The CLI adds several layers of safety, but the ultimate responsibility is yours.
Layers in place
- Dry-run by default. Without
--confirm, the command computes the exact request body that would be POSTed, shows a full preview (symbol, side, quantity, price, fee breakdown, total), and exits without any network call. - Required
--limitprice. Market orders are disabled. You must specify a limit price — no "fat finger" can blow past the current quote. - Hard order-size cap.
TRII_MAX_ORDER_COP(default 200,000 COP) refuses to submit anything larger. Bypass explicitly with--yolo. - Interactive confirmation.
--confirmtriggers a y/n prompt showing the exact order ("BUY 1 TERPEL @ $11,500 for $26,375 total") that requires typingyes. Skip with-yonly in trusted scripts. - Sell-side holdings check. Before submitting a sell, the CLI pulls your positions and refuses if you don't own enough shares of the symbol.
- Session-expiry detection. If your
sk2cookie is stale, the command bails with a clear "runtrii login" instead of silently failing. - After-placement lookup. Once Trii accepts the order, the CLI re-queries the orders list to find the real order ID and server status, so you see a concrete confirmation (not just "ok").
Layers NOT in place
- No reversing of orders. Once submitted, cancellation is on you (not yet wired — see the Trii web app).
- No dependency on a broker-side idempotency key. If you run
--confirm -ytwice back-to-back, you place two orders. - No rate limiting / circuit breaker. If Trii starts returning errors, nothing stops you from spamming the button.
Rule of thumb: start with dry-runs until the preview looks exactly like what you'd click in the real Trii UI, and keep TRII_MAX_ORDER_COP at its default for the first few real orders.
Security Considerations
This tool is designed for fully local, personal use only. It runs entirely on your machine — no data is sent to third-party servers (except Trii's own endpoints). Working with real brokerage credentials and placing real orders carries inherent risks you should understand before using it.
Credential Storage
Session cookies (sk2, cf_clearance, user) are stored in plaintext at ~/.trii-config.json. This file is not encrypted. Anyone with access to your home directory — malware, shared machine, backup sync, cloud drive — could read your Trii session. Recommendations:
- Run
chmod 600 ~/.trii-config.jsonto restrict file permissions to your user only - Always run
trii logoutwhen you're done to clear stored credentials - Never commit or share your config file
- The
usercookie contains your real name, document number, and phone number
Shell History
The trii connect <user> <pass> command accepts your password as a CLI argument, which means it gets saved in your shell history (~/.zsh_history, ~/.bash_history). If you use this command, clear the entry from your history afterwards. The browser-based trii login is the safer alternative.
REST API
The local API server (trii server) binds to port 3210 with no authentication and open CORS. This is fine for personal use on localhost, but:
- Do not expose this port to the network or internet
- Any application on your machine can query your positions and orders while the server is running
- Trading endpoints (
buy,sell) are intentionally not exposed over REST for this exact reason - Stop the server when not in use
MCP Server & AI Context
When using the MCP server with Claude (Code or Desktop), your account data — positions, balances, orders, movements — is sent as text to the AI model. Be aware that:
- This data flows through Anthropic's API and is subject to their data policies
- Conversation context may be logged, cached, or used for safety monitoring
- Trading tools are deliberately omitted from the MCP server — Claude cannot place orders on your behalf
- Avoid using MCP if you are not comfortable with your financial data being processed by a third-party AI provider
Browser Automation
The trii login command launches a Chromium instance with --no-sandbox and automation flags disabled. This is necessary to interact with Trii's Next.js + Cloudflare front-end but reduces browser-level security protections during the login flow. The same applies to any capture session you run against the real Trii UI.
Session Capture Files
If you run a capture session (see the reverse-engineering workflow in docs/), the resulting .trii-capture/ directory will contain a full HAR file with your email, your password, your 2FA tokens, and live session cookies. Treat it like a password file:
- Never commit it (the provided
.gitignoreexcludes it) - Never share it in issues or pastebins
- Delete it when you're done reverse-engineering
General Advice
- Use this tool at your own risk. It is an unofficial, community project — not endorsed by Trii.
- Real brokerage orders are real money. Double-check every
--confirmbefore pressing Enter. - Treat your machine as the security boundary. If your machine is compromised, your brokerage session is compromised.
- Review the source code before use. This is why it's open source.
Tech Stack
- Bun — Runtime
- TypeScript — Type safety
- Zod — Schema validation
- Hono — REST API framework
- Playwright — Browser login automation
- MCP SDK — Claude integration (9 tools)
License
MIT
