Advanced
MCP server
Give Claude Code, Codex, Cursor, or any MCP client Gloom's research tools, and with Terminal control your open Gloom app.
Gloom Cloud hosts a Model Context Protocol server at https://api.gloom.sh/mcp. It gives an agent the research tools Gloom's own assistant uses, and with the right access your notes, teams and connected brokers. Part of Gloom Pro.
The same keys work for the REST API and Google Sheets. With Terminal control the same server also drives your open desktop or TUI; for one-off reports, use the CLI.
Connect
Sign in from the client. OAuth clients (Claude Code, claude.ai, Cursor and most recent clients) only need the endpoint. The first call opens a browser tab where you choose what the client may reach.
claude mcp add --transport http gloom https://api.gloom.sh/mcpUse a key. For scripts and clients without a browser, create a key in Cloud settings, Agents and send it as a bearer token (x-api-key also works). Keys are shown once; you can hold up to 10.
claude mcp add --transport http gloom https://api.gloom.sh/mcp \
--header "Authorization: Bearer gloom_mcp_..."export GLOOM_MCP_KEY=gloom_mcp_...
codex mcp add gloom --url https://api.gloom.sh/mcp --bearer-token-env-var GLOOM_MCP_KEY{
"mcpServers": {
"gloom": {
"url": "https://api.gloom.sh/mcp",
"headers": { "Authorization": "Bearer gloom_mcp_..." }
}
}
}Raw HTTP is stateless: one JSON reply per POST, and GET and DELETE return 405.
Access
| Access | Reaches |
|---|---|
| Market data | Market, company, filing, macro, news and research tools |
| Read | Plus teams, notes, collections and the broker tools |
| Read and write | Plus notes.save, collections.add_symbol, collections.remove_symbol |
| Terminal control | Adds the `terminal.*` tools to any level: your open Gloom app. Off unless you tick it |
A key's access, Terminal control and optional team pin are fixed at creation. Signed-in clients get the same levels through the mcp:read, mcp:write and mcp:terminal scopes; the consent page leaves Terminal control unticked. tools/list returns only what the caller may call.
Tools
Read-only unless marked write. Most take limit; ? marks an optional argument. tools/list has the full schema. Start with market.search when a ticker is ambiguous.
Market
| Tool | Arguments |
|---|---|
market.search | query |
market.quotes | symbols, exchange? |
market.history | symbol, exchange?, interval?, startDate?, endDate? |
market.screener | category |
market.options_chain | symbol, exchange?, expiration? |
market.short_interest | symbol, years? |
market.options_flow | symbol?, days?, minPremium? (a filter searches recorded prints, not the live tape) |
Company
| Tool | Arguments |
|---|---|
company.profile, company.financials, company.holders, company.analyst_research, company.corporate_actions | symbol, exchange? |
company.statements | symbol, exchange?, period? |
equity.diagnostic | symbol, exchange?, mode? |
Filings and ownership
| Tool | Arguments |
|---|---|
sec.filings | ticker, offset? |
sec.insider_transactions | ticker |
sec.thirteenf_holders | ticker, quarter? (YYYYQn), offset? |
sec.thirteenf_crowding | quarter?, rank? (new, exits, increases, decreases), funds? |
congress.house_trades, congress.senate_trades | year?, member?, ticker?, side?, owner?, assetType?, minAmount? |
Macro and news
| Tool | Arguments |
|---|---|
macro.calendar, macro.yield_curve | none |
macro.series | seriesId, startDate?, endDate? |
news.stories | query?, feed?, tickers?, topics? |
social.ticker_posts | ticker, hours?, includeReplies? |
social.search_posts | query, queryType?, hours? |
Events and credit
| Tool | Arguments |
|---|---|
market.catalysts | symbol?, type?, agency?, country?, sector?, source?, status?, search?, from?, to?, dateField?, upcoming?, changed?, offset? |
company.litigation | symbol, offset? |
catalysts.event | id, offset? |
catalysts.changes | since, cursor? |
credit.documents | symbol |
credit.instrument | symbol, instrumentId |
credit.screen | headroomBelow?, springingWithinMonths? |
Company data
| Tool | Arguments |
|---|---|
company.kpis, company.guidance | symbol, metric?, basis?, from?, to?, asOf?, includeRevisions? |
company.awards | ticker?, jurisdiction?, agency?, sector?, awardType?, from?, to?, fiscalYear?, query?, minAmount?, cursor? |
company.award_evidence | id, revisionsCursor? |
company.hiring | ticker, roles? |
market.hiring_movers | none |
hiring.momentum | symbol?, offset? |
apps.attention | symbol?, country?, chart?, days?, offset? |
apps.rank_history | store, appId, country?, chart?, days?, offset? |
Markets and compute
| Tool | Arguments |
|---|---|
market.attention | symbol?, window? |
perps.board | baseAsset?, underlyingSymbol?, assetClass? |
perps.compare | baseAsset |
perps.history | marketId, from?, to?, resolution? |
perps.rankings, gpu.board | none |
gpu.history | gpuModel?, seriesId?, basis?, from?, to? |
gpu.changes | gpuModel? |
Supply chain and power
| Tool | Arguments |
|---|---|
company.supply_chain_graph | from, depth?, direction?, roles?, tiers?, minPct?, minConfidence?, asOf? |
company.supply_chain_paths | from, to, plus the graph arguments |
company.supply_chain_evidence | symbol, tiers?, includeLeads? |
power.board, power.history | country?, region?, fuel?, status?, kind?, symbol?, search?, loadClass?, historical?, offset? |
power.summary | the same filters, plus section |
power.project | id, offset? |
power.coverage | none |
Notes and teams
| Tool | Arguments |
|---|---|
teams.list | none |
notes.list | scope (user or team), teamId?, kind? (ticker or quick) |
notes.get | id |
notes.save (write) | scope, teamId?, kind, key, title?, content, expectedRevision? |
collections.list | teamId? |
collections.get | teamId?, collectionId |
collections.add_symbol (write) | teamId?, collectionId, symbol, exchange?, quantity?, note? |
collections.remove_symbol (write) | teamId?, collectionId, symbol, exchange? |
notes.save replaces the whole note, so read it first and pass expectedRevision; a newer edit returns revision_conflict. quantity applies to portfolios only.
Portfolio
| Tool | Arguments |
|---|---|
portfolio.accounts | none |
portfolio.positions | broker? |
portfolio.performance | broker?, accountId?, since? (YYYY-MM-DD) |
portfolio.exposure | holdings, depth?, cashWeight?, scenario |
Brokers
Connect a broker in Gloom and every client with read access reaches it through Gloom. The portfolio.* tools cover every connected broker in one call and need no Pro.
With no connection they return no rows and a note; a broker that fails adds an error row and the result is partial. They read brokerage accounts, not team portfolios (use collections.get).
| Broker | Tools | Writes (read and write access) |
|---|---|---|
| Interactive Brokers | ibkr.*: positions, balances, trades, orders, contract search, prices, alerts, watchlists | Order instructions, alerts and watchlists, when trading instructions are enabled |
| Robinhood | robinhood.*: accounts and equity positions | None |
An IBKR order instruction is not an order: IBKR returns a link where you review and submit it yourself.
Terminal control
Terminal control reaches everything the remote API does in your open, signed-in desktop or TUI: read the screen, open and arrange panes, navigate tickers, switch and edit layouts, semantic UI actions and plugin capabilities. The app asks once before an assistant takes over; plugin capabilities, button presses, commands and anything that reaches an outside service (orders, transfers, messages) ask you in the app on every call, and an unanswered one is denied after 60 seconds.
Claude Code ──MCP──> api.gloom.sh/mcp ──Cloud socket──> your Gloom app ──> panes, layouts, tickers
│
asks you: once per assistant, every call that leaves the app| Tool | Does |
|---|---|
terminal.devices | Open terminals, the most recently used first |
terminal.snapshot | Layouts, panes, focused pane, command bar, open form |
terminal.pane_content | One pane's settings, state and drawn UI (paneId) |
terminal.pane.screenshot | One pane of the desktop app as a PNG image, as it looks on screen (paneId?, width?). A read: it runs once you approved the assistant, without asking each call. Up to 1600 px on the long side and 512 KB; the TUI answers unsupported |
terminal.get_resource, terminal.patch_resource | Any remote API resource; configuration arrives without credentials |
terminal.pane.*, terminal.ticker.*, terminal.layout.*, terminal.view.*, terminal.app.*, terminal.desktop.*, terminal.command_bar.*, terminal.ui.*, terminal.capability.invoke | One tool per remote API operation, generated from the app's schema |
terminal.call_result | The outcome of a call that answered pending |
Each tool takes device? (an id or name from terminal.devices). Descriptions carry the operation's tier and whether you confirm each call. A call that waits on you longer than 45 seconds answers pending with a callId; read the outcome with terminal.call_result. With no app open, tools answer no_terminal. Revoke an assistant in the app (Account Management, Agents), or revoke its key or disconnect it here, and its next call stops.
Results and limits
Each call returns text plus structuredContent with status (ok, partial when a limit removed rows, or error), rowCount, truncated, asOf and data. Results are capped at 256 KB. A failed source returns status: "error" with data.error = { code, source, reason }. terminal.pane.screenshot returns the same JSON as text plus an image block, and no structuredContent, since some clients read only that and would drop the image.
Creating keys needs Pro. Any valid key can initialize and tools/list; tool calls need Pro, except portfolio.*, and get real-time quotes and the live news wire.
Keys allow 120 requests a minute and 5,000 a day; over the limit returns 429 with Retry-After. If Pro lapses, keys stay but tool calls are refused. Revoking a key applies on the next request; a disconnected client's token expires within two hours, and its terminal calls stop at once.