New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

veyora

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

veyora

The Veyora command line: a zero-dependency MCP client for the Veyora research server, with a stdio bridge for MCP hosts that only launch local servers.

latest
npmnpm
Version
0.2.2
Version published
Weekly downloads
35
-91.82%
Maintainers
1
Weekly downloads
 
Created
Source

veyora — the Veyora command line

A zero-dependency MCP client for the Veyora research server, with a human face and a stdio bridge. Node 18 or later; ESM; nothing to install beyond the package.

Every command is a tools/call on the Veyora MCP server (/api/mcp). The command line uses the same access tokens and the same plan as the MCP server: a read the plan does not carry says so, and ask is charged to the account's credits exactly as a chat message is.

Install and sign in

npm install -g veyora
veyora login

Create an access token in Settings → Integrations, then paste it at the prompt (typing is hidden; veyora login --token with no value asks the same way). The token is checked with get_account and stored at $XDG_CONFIG_HOME/veyora/credentials.json — else %APPDATA%\veyora\credentials.json on Windows, else ~/.config/veyora/credentials.json — mode 0600, keyed by server origin; a token the server refuses is said to be refused, and nothing is stored. veyora logout forgets the local copy; the token itself stays live until revoked in Settings. veyora doctor checks the whole setup.

Token precedence: --token TOKEN > VEYORA_TOKEN > the stored file. Server precedence: --server URL > VEYORA_SERVER > veyora config set server > https://veyora.ai.

Commands

veyora login [--token TOKEN] [--server URL]
veyora logout
veyora account                                # plan, credits, limits, this token's name and scopes
veyora usage                                  # this calendar month: credits spent and left, news refreshes
veyora credits [--limit N] [--before CURSOR]  # the account's credit ledger, a page at a time
veyora plans                                  # every plan, price, allowance and credit pack (a listing)
veyora search <query> [--category C] [--limit N] [--after DATE] [--before DATE]
veyora browse <lens> [--category C] [--limit N]  # movers, most_active, resolving_soon, newly_listed
veyora market <ticker>
veyora history <ticker> [--range 1D|1W|1M|3M|ALL]
veyora book <ticker> [--depth N]
veyora trades <ticker> [--limit N]
veyora related <ticker>
veyora news <ticker>
veyora tracked
veyora settled [--series S] [--limit N] [--since ISO] [--cursor "before,beforeTicker"] [--candles] [--all] [--cursor-file PATH]
veyora export history <ticker> [--period minute|hour|day] [--from ISO] [--to ISO] [--cursor C] [--all] [--cursor-file PATH]
veyora export tape <ticker> --kind trades|books|candles [--period minute|hour] [--from ISO] [--to ISO] [--cursor C] [--all] [--cursor-file PATH]
veyora analyses
veyora analyze <id> <ticker> [--param key=value ...] [--version N] [--async]
veyora analyze <id>,<id>... <ticker> --async   # several analyses on one market, a job each
veyora notebooks                              # the starter notebooks, and which this server can run
veyora notebook <id> <ticker> [--async]       # run a starter notebook on the server, where enabled
veyora ask <ticker> "<question>" [--depth quick|standard|deep] [--experience beginner|amateur|expert] [--async]
veyora jobs [--limit N]                        # this account's jobs, newest first
veyora jobs result <handle>                    # one finished job's result
veyora jobs cancel <handle>                    # ask a working job to stop
veyora wait <handle> [<handle> ...] [--timeout SECONDS]
veyora tools                                  # tools/list as the server states it
veyora mcp                                    # stdio ↔ HTTPS bridge
veyora init <claude-code|vscode|cursor|windsurf> [--global] [--force] [--dry-run]
veyora open <ticker> [--kalshi] [--print]     # Veyora's page for the market, or the contract on Kalshi
veyora config [get <key> | set <key> <value> | unset <key> | path]
veyora doctor                                 # check Node, the files, the server, the token and the output
veyora completion <bash|zsh|fish>             # a shell completion script
veyora help [command]
veyora --version

Global flags: --format table|json|md|csv (--json is --format json; the default is your configured format, else a table on a terminal and JSON on a pipe), --text (the tool's own text, on a terminal or a pipe and ahead of a configured format; beside --format or --json it is a usage error, and under it an error goes to stderr alone), --server, --token, --no-color. veyora help <command> prints a manual page: name, synopsis, description, options, examples and exit status.

A flag the command does not take is refused (exit 2, code usage), never ignored: veyora search rate --limt 5 says that veyora search has no --limt option, asks "Did you mean --limit?" when exactly one of the command's flags or the global flags is within two edits (never one reached only by rewriting every character, so export --n is not pointed at --to), and names veyora help search. It is refused before the server or a token is read. So is a switch given a value (--all=yes), and --version N beside any command but analyze; a bare --version prints the version. Each command's flags are the ones its manual page lists, which are also exactly what the shell completions offer. -- ends the flags: everything after it is an argument (veyora search -- --weird).

A flag that takes a value, given none, is refused the same way (exit 2, code usage), never read as absent: at the end of the line, before another flag or --, empty after =, or only whitespace (--token " ", a token file holding just a line ending). An empty --format= chooses no format, so its refusal goes where any other does: on a pipe, the usage object on stdout. veyora search fed --category says that veyora search takes --category with a value: --category C, with the placeholder its manual page writes; a bare --server used to talk to the default server and now talks to none. Which flags take a value is the same table: the ones a usage line writes with a placeholder, and the global --format, --server and --token. A value may begin with one dash (--limit -5 reaches the range check, a cursor or a path may start with -); one beginning with two goes after = (--category=--x). The one exception is veyora login --token with no value, which asks for the token at the hidden prompt as veyora login does, so a token need never be typed into shell history; an empty answer is exit 2, and --token= or a --token of only spaces is refused.

Formats. md writes Markdown tables; csv writes a listing's table and nothing else (search, browse, tracked, history, book, trades, settled, export, plans, credits, jobs and notebooks — another command is a usage error; a listing with no row writes the header row alone and says why on stderr, exit 0); notebook writes a Note,Value block (as_of, delayed, the number of tables) and then each table the run displayed, with RFC 4180 quoting and the minus as ASCII so a spreadsheet reads it. Colour marks only a movement's sign: --no-color > NO_COLOR (set and not empty) > FORCE_COLOR (0 or false turns it off) > veyora config set color > a terminal; json, md and csv never carry it.

veyora search matches one phrase inside each listed market's question or ticker. --after DATE and --before DATE keep markets resolving in [after, before), in UTC: a date YYYY-MM-DD (00:00 UTC that day) or an ISO instant with its zone (2026-10-01T14:00:00Z); one month is the 1st to the 1st of the next (--after 2026-10-01 --before 2026-11-01). Either may be given alone. They travel as typed, as resolves_after and resolves_before; the server applies the window before the rows are cut to the busiest, states it above the rows, and refuses a value it cannot read in its own sentence (exit 1).

veyora browse finds markets with no words to search for, through Explore's four measured lenses: movers (the top 20 by today's move, thin markets excluded), most_active (the top 20 by 24-hour volume), resolving_soon (contested markets resolving within 14 days, thin markets excluded) and newly_listed (opened in the last 7 days, thin markets excluded). It prints the lens's rule as the server states it, then the rows with the listing's stamp; --category keeps one desk before the lens is applied. A lens is a measurement, never a recommendation. A server older than this command has no lenses and says so; veyora search works there.

veyora market reads one market at a glance: the question, the probability with its price, today's move (or that no prior close is on file), a sparkline of the week's closes with its window and range stated beside it (a gap breaks it, and a narrow range is drawn across at least 8 points rather than stretched), the book's cost, the outcome family, every stamp, delayed, each block that failed to load named as a failure, and Open on Kalshi with the quote's time. A pipe still gets get_market's structured content, unchanged.

veyora ask streams on a terminal: one quiet "thinking…" line on stderr while the analyst reasons, then the answer written as it arrives (the server sends the new text in its progress notifications, under _meta["ai.veyora/delta"]). A pipe, --json or --text gets the finished answer. --depth and --experience fall back to veyora config values.

veyora config shows every effective setting and where it came from (server, token — masked to its last four characters — format, colour, the analyst's depth and experience, the two files); set, get and unset change config.json beside the credentials (mode 0600). It never holds a token.

veyora doctor checks Node, the credentials file (present, 0600, readable) and the settings file, the server (and that it answers as an MCP server, and offers sign-in), this machine's clock against the Date of the server's answer (more than 300 s apart fails, with the offset measured), the token, the account it signs in as and the scopes the token carries, the protocol era, the tools offered and the output. It writes nothing; it exits 0 when everything passes, 5 when the server could not be reached, 3 when sign-in failed, 1 otherwise.

veyora open opens Veyora's page for a market (no token needed), or with --kalshi the contract's own page on Kalshi. It only ever opens the server's address or kalshi.com, prints the address either way, and --print opens nothing.

settled --all walks the next cursor up to ten pages and says so when it stops short. settled --cursor-file PATH makes the walk resumable: after each page the next cursor and the query it belongs to are written to the file, running the same command again continues from it, a file for a different query is refused, and a finished walk says so; with --format csv a resumed run writes no header row, so >> rows.csv builds one file. export (where the server enables bulk export) pages a market's candles or its recorded tape — trades, order-book snapshots as one row per side and level, or candles — oldest first, the rows written exactly as the server sent them; --all walks twenty pages and names the cursor to continue from — --cursor C (a run given --cursor writes no CSV header, so >> appends) or --cursor C --cursor-file PATH to make the rest resumable — and --cursor-file resumes the same way settled does. A cursor file never records a page before its rows are written: an error mid-walk prints the rows read, exits non-zero, and the same command continues with the next row. With --format csv the server's summary line (coverage, delayed, a cap, a market never captured) goes to stderr, and a page that left rows out with no cursor to follow is said, never reported as finished. credits prints the next page's command, with the server's cursor verbatim. plans prints each price as the server's own text — the command line formats no money — and buys nothing: plan changes and credit packs happen in Settings → Plan & billing, signed in. analyze --param values are coerced: true/false become booleans, plain numbers become numbers, anything else stays text.

--async starts the work as a JOB and prints its handle at once instead of holding the terminal while it runs; veyora wait <handle> waits for it (calling the server again every 25 s at most, for up to --timeout seconds, default 600) and prints the result exactly as the synchronous command would. A job and its result are kept on the server for 24 hours, then deleted; nothing is saved to Tools history. A handle names a job of the account it was started from and no other. ask --async is charged when it runs, exactly as ask is.

Human output prints every stamp the server states, the word delayed for a figure that is last-known rather than current, — for an absence, a probability as 62% (62¢), and the true minus sign. A movement's sign is the only thing that takes colour. While a call works its progress words go to stderr, and a word the server repeats back to back prints once.

Exit codes

CodeMeaning
0ok
1the tool answered with an error — a plan lock, insufficient credits, an outage, an unknown market — or the server does not offer the tool (it predates this version); its sentence is on stderr
2usage: an unknown command or option, a missing argument, a value out of range
3sign-in needed: no token for the server, or the server refused the one sent (401) — the sentence says which, where a refused token came from, and how to replace it there (--token, VEYORA_TOKEN, or veyora login for the stored one)
4rate-limited: a 429, or a tool that answered rate-limited (the per-account wall, or a spent budget such as export history's live reads) — the tool's own sentence, which says when to try again and what else stood in the way
5the server couldn't be reached or is unavailable

veyora wait exits 0 when every job completed and 1 when any failed, was cancelled, was not found for this account, or was still working when --timeout elapsed (stderr names the handles to wait on again).

With --json (or a pipe) an error also writes one object to stdout: {"ok":false,"code":"…","error":"…"}. code is tool-error, jsonrpc, unknown-tool (the server does not offer that tool: it predates this command) (exit 1), usage, config-invalid, exists (exit 2), auth (with reason: missing when no token reached the command, refused when the server refused it), forbidden (exit 3), rate-limited (exit 4, with retryAfter in seconds when the server named one, and a tool's structured error as structured), unavailable, handshake, empty, shape, open-failed or unexpected (exit 5). Branch on the exit code, which is the stable signal.

Add Veyora to an MCP host (veyora init)

veyora init <host> adds a veyora entry to the host's config file for the server this command resolves (--server, else VEYORA_SERVER, else veyora config set server, else https://veyora.ai). It never writes a token:

HostFileEntry
claude-code.mcp.json (this project)the server address; run /mcp and sign in
vscode.vscode/mcp.json (this project)the server address; VS Code asks you to sign in on first start
cursor.cursor/mcp.json, or ~/.cursor/mcp.json with --globalthe bridge, npx -y veyora mcp
windsurf~/.codeium/windsurf/mcp_config.jsonthe bridge, npx -y veyora mcp

Claude Code and VS Code connect by signing in with OAuth. Cursor and Windsurf run the bridge, which uses the token veyora login stored, so a bridge entry needs that login first. Every other server in the file is kept; a file that is not JSON is left untouched; a veyora entry that differs is replaced only with --force; --dry-run prints the file it would write.

Settings → Integrations has the same installs as links and a download: Add to VS Code, Add to Cursor, and veyora.mcpb for Claude Desktop, which asks for an access token when you open it and keeps it in the system keychain. None of them carries a token.

Shell completion (veyora completion)

source <(veyora completion bash)      # or add the line to ~/.bashrc
source <(veyora completion zsh)       # or save the output as _veyora on $fpath
veyora completion fish | source       # or save it as ~/.config/fish/completions/veyora.fish

It completes the commands, each command's flags — the same table the command line enforces, so it never offers a flag a command refuses — the global flags, init's hosts, browse's lenses and the shells, and nothing that needs the network.

The bridge (veyora mcp)

For MCP hosts that only launch local servers. Newline-delimited JSON-RPC on stdin becomes one HTTPS POST per message to the remote server, with the bearer and the mirrored headers; each answer comes back as one line on stdout. Nothing but JSON-RPC is written to stdout, even when the bridge cannot start (no token, a bad --server: the sentence goes to stderr); diagnostics go to stderr. A 401 is answered with the refused-token sentence, naming where the token came from — an MCP host that sets VEYORA_TOKEN (Claude Desktop's bundle does) needs its own token setting changed, not veyora login. The bridge speaks both eras — a request carrying modern _meta travels with MCP-Protocol-Version/Mcp-Method/Mcp-Name mirrored from its body; a legacy initialize is forwarded and its negotiated version remembered for later requests. Notifications are forwarded and answered with nothing. A host's notifications/cancelled is passed through as a cancel: it aborts that request's HTTPS request, which closes the stream the server answers on (the server's own cancel), and nothing is written for that id; it is not POSTed, and a cancel naming initialize, a finished request or an unknown id changes nothing. Streamed answers forward notifications/progress lines as they arrive, then the final response. The process exits 0 when stdin closes or on SIGTERM.

{
  "mcpServers": {
    "veyora": {
      "command": "npx",
      "args": ["-y", "veyora", "mcp"]
    }
  }
}

The bridge reads the token veyora login stored; a host that cannot reach that file can pass it as "env": { "VEYORA_TOKEN": "<your token>" } instead.

Hosts that sign in with OAuth need no bridge and no token:

claude mcp add --transport http veyora https://veyora.ai/api/mcp

then /mcp in Claude Code to sign in. A host that cannot sign in can set the header instead: --header "Authorization: Bearer <your token>".

How it speaks MCP

The first request of a process is server/discover with modern (2026-07-28) per-request _meta. A server that speaks only the handshake era answers with something that is not a modern result, and the client falls back to initialize (2025-11-25) and notifications/initialized. A modern server that refuses the version with -32022 and lists what it supports gets a version the client speaks, else the handshake. login records the era the server answered in; a stored legacy era skips the probe on later runs. This is what makes the command line a real MCP client: pointed at another MCP endpoint with --server, it works the same way.

Development

In the Veyora source repository (not part of this package): packages/cli/test/stubServer.mjs is a stand-in for POST /api/mcp that speaks both eras and serves the catalog's tool names with fixture results: node packages/cli/test/stubServer.mjs [--legacy] [--port N] prints its endpoint and tokens. From the repository root, npm run cli -- <command> runs the checked-out source.

FAQs

Package last updated on 13 Oct 2026

Related posts