Elfa

ai.elfaPublished by elfa.aiv4.10.0Updated Nov 7, 2026

Crypto social intelligence from X and Telegram, plus the Elfa Auto condition engine

Overview

AI-generated overview

Elfa gives an assistant crypto and equity market intelligence from X and Telegram social data, plus an Auto condition engine that fires actions when…

What you can do
  • Resolve tickers, cashtags, handles, contract addresses and other identifiers into entity ids, and check API key tier, credits and history depth
  • Read market events, storylines and arcs, and whole-market views such as mindshare, call books and trending contracts
  • Read positions accounts take in posts, open positioning per asset, and X accounts ranked by standing or track record
  • Read social mentions, trending tokens and contracts, and written narrative analysis with source links
  • Draft, validate, activate, cancel and delete Auto queries and drafts, and poll their executions and analyses
  • Ask for written market analysis in a conversational chat
When to use it
Useful when you want an assistant to research crypto or equity market activity through social signals, track what accounts are positioning in, or set up unattended monitoring queries that notify, call a webhook or message a Telegram bot when conditions are met.
Requirements
Runs locally over stdio via npx, or as a hosted remote server with browser sign-in. Local use needs an Elfa API key in ELFA_API_KEY, obtained from the provider's developer site. Credits are consumed per call, and some tools require a higher-tier plan.
Before you install
Most tools spend credits per call, and LLM-backed tools such as narratives and market_chat cost more and are billed even if the client times out. Auto write tools activate queries that run unattended and fire actions without asking again; validate first and review estimated costs and per-post or per-day account charges. Social text and asset names are third-party content and should be treated as data, not instructions.

Installation

In SourceWeft

  1. Open Elfa in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

Elfa MCP

Model Context Protocol server for the Elfa API — API v3 events, positions and rankings across crypto and equities, Auto, a condition engine that watches the market and fires an action when your conditions are met, plus crypto social intelligence from X and Telegram.

Works with any MCP client, either signed in to the hosted server or running locally with an API key.

Install

Hosted, sign in with Elfa

Add https://mcp.elfa.ai/mcp as a remote MCP server in your client and approve it in your browser with your dev.elfa.ai account. No key to copy, nothing to install. If your client cannot sign in, run the server locally instead. Setup steps are in the MCP guide.

Local, API key

Get an API key at dev.elfa.ai. No install step — npx fetches the server on demand.

One click

[Add to Cursor] [Add to VS Code]

Claude Desktop

Download elfa-mcp-<version>.mcpb from the latest release and open it. Claude Desktop installs it, prompts for your API key, and keeps it updated. Nothing else to configure.

Claude Code

bash
claude mcp add elfa --env ELFA_API_KEY=your-key -- npx -y @elfa-ai/mcp

Cursor, VS Code, Claude Desktop, and other clients

json
{  "mcpServers": {    "elfa": {      "command": "npx",      "args": ["-y", "@elfa-ai/mcp"],      "env": {        "ELFA_API_KEY": "your-key"      }    }  }}

VS Code uses "servers" instead of "mcpServers". Everything else is the same.

Ask "what's trending in crypto right now?" to confirm it works.

Configuration

VariableRequiredPurpose
ELFA_API_KEYyesAuthenticates every request
ELFA_TIMEOUTnoRequest timeout in ms, default 120000
ELFA_RETRIESnoRetries on failure, default 0
ELFA_MCP_MAX_RESPONSE_CHARSnoResponse size ceiling, default 60000
ELFA_EXTRA_HEADERSnoJSON object of extra headers to send upstream, for proxies and non-production environments

Upstream requests identify themselves as User-Agent: elfa-mcp/<version> (<transport>; client=<app>). On stdio, <app> is the MCP client's name and version from the handshake; over HTTP, it is the connecting client's own User-Agent header. Set User-Agent in ELFA_EXTRA_HEADERS to send your own instead.

The timeout is high and retries are off on purpose. The interpretation endpoints are LLM-backed and can take over a minute, and they cost credits per attempt, so a silent retry would bill you again for a call you never saw. Raise ELFA_RETRIES only if you are calling the cheap measurement endpoints.

Some MCP clients apply their own timeout, often around 60 seconds. narratives and market_chat can exceed that; the request still completes and is still charged, even if the client gives up first.

Tools

16 tools, mapped to every documented /v2 and /v3 operation.

ToolModeCostWhat it does
api_statusreadFreeCheck API key tier, credit usage and remaining requests, and historyFrom, how far back events, market and calls read. Also confirms the API is reachable.
entitiesread1 per callResolve a ticker, $cashtag, name, @handle, contract address, CoinGecko id, FIGI or CIK to the entity id that events and calls take. Matches exactly, it is not a search.
eventsread1, plus 1 per event or 2 per storyline or arcWhat is happening in crypto and equity markets. level=events for what happened and how prices reacted, level=storylines for one development threaded over days, level=arcs for storylines grouped into a larger movement. Searchable by topic.
marketreadcall_book 2, mindshare 5, trending_contracts 5 (plus 5 over a 24 hour range), doubled for limit over 50Whole-market views for crypto or equities. view=mindshare ranks assets by share of attention, view=call_book is the crowd's long/short lean hour by hour, view=trending_contracts ranks contract addresses by how many posts pasted them.
callsread1, plus 1 per call or 2 per episode; positioning 2Positions accounts take in posts. level=calls for each post that takes or changes a position, level=episodes for each position from open to close with the author's track record, level=positioning for open longs and shorts on one asset now.
top_accountsread5 by standing, 25 by a track metric, doubled for limit over 50X accounts ranked by standing (how much other accounts engage with them) or, with metric, by their track record as callers (alphaScore, hitRate, avgReturn).
auto_buildread1 plus LLM usageTurn a plain-language monitoring request into an EQL query. Returns a draft to validate and activate, it does not activate anything itself.
auto_validatereadFreeCheck EQL syntax and get a cost estimate before activating, or check that a symbol has market data on a venue.
auto_queryreadFreeRead side of Auto: list queries, poll one query, and read its executions and LLM sessions.
auto_query_writewrite5 plus LLM usage to create, free to cancel or deleteActivate, cancel or delete an Auto query. Activated queries run unattended and fire their action when conditions are met.
auto_draftreadFreeRead side of Auto drafts: list saved drafts and read one. Drafts are queries parked without activating; they never evaluate or fire.
auto_draft_writewriteFree, except convert which costs the same as creating a queryCreate, update, delete or activate an Auto draft. Converting a draft activates it as a live query that runs unattended.
mentionsread1 per callSocial mentions from X and Telegram. mode=top ranks a ticker's mentions by engagement, mode=search filters by keyword or account, mode=news returns the token news feed, which is X posts from accounts tagged as news sources rather than articles from news outlets.
trendingread1 per callWhat is gaining social attention. scope=tokens for tickers, scope=contracts_twitter or scope=contracts_telegram for contract addresses.
narrativesread5 per callWritten narrative analysis with source links. scope=market extracts market-wide narratives, scope=keywords summarises events for specific keywords.
market_chatreadVaries by speedAsk for written market analysis. Supports conversational chat, macro overview, quick summary, token intro, token analysis and account analysis.

Not exposed as tools:

  • chat-stream-v2 — A tool call returns one result, so streaming adds nothing. market_chat covers the same analysis.
  • auto-stream-queries-v2 — Long lived streams have no tool equivalent. Poll with auto_query.
  • auto-stream-query-v2 — Long lived streams have no tool equivalent. Poll with auto_query.
  • getAccountSmartStats-v2 — Deprecated and not maintained, so no tool wraps it. To rank accounts, use top_accounts; mentions with mode=search returns per-post engagement metrics with the posting account.

Some tools depend on the plan: today market_chat, which needs a higher-tier plan than the free one, and the API v3 tools on a key whose scopes leave them out. At startup (stdio) or per request (HTTP, cached for a minute per key), the server reads the key's scopes from /v2/key-status. A tool the plan doesn't include stays listed, but its description says it needs a higher-tier plan, and calling it returns the upgrade link without calling the API or spending credits. If the scopes can't be read within 3 seconds, every tool is listed as usual and the API decides.

Streaming endpoints stay available through the SDKs for applications that can consume SSE.

API v3

entities, events, market, calls and top_accounts read API v3: events, storylines and arcs; call books, mindshare and trending contracts; calls, call episodes and positioning; ranked accounts. They cover crypto and equities and are open to every plan. Each call costs credits, priced per endpoint on the pricing page.

  • Filters take entity ids, not tickers. Resolve an asset with entities first and reuse the id.
  • Times are unix seconds. Milliseconds are refused.
  • How far back a key reads depends on its plan. api_status returns it as historyFrom.

Where this differs from the raw API

The tools deliberately do not inherit every API default, because an agent pays for verbosity in context.

APIHereWhy
pageSize10 to 50 depending on endpoint, max 10010Page through rather than pull everything
limit on v3 tools10 or 50 depending on endpoint, max 30 or 20010Page with cursor rather than pull everything
speed on chatexpertfastCheaper by default, ask for expert when depth matters
Mention fieldsfull recordhigh signal fieldsPass verbosity: "detailed" for the rest
Large responsesreturned wholetrimmed to fit, with a noteKeeps one call from filling the context window

Every value is still settable per call: pageSize accepts up to 100, and limit up to the endpoint's maximum.

Auto

Auto queries run unattended. Once armed, a query keeps evaluating and fires its action without asking again.

The flow is three steps:

  1. auto_build — describe what to watch in plain language, get EQL back
  2. auto_validate — check the syntax and get the credit cost
  3. auto_query_write — activate it

Actions can notify you, call a webhook, message a Telegram bot, or run an LLM analysis.

There is no push channel over MCP. Poll auto_query with method=get, and wait for the returned pollAfterSeconds between calls.

Remote server

The same server runs over Streamable HTTP for hosted deployments:

bash
ELFA_MCP_TRANSPORT=http ELFA_MCP_PORT=3000 npx -y @elfa-ai/mcp

It is stateless — no sessions, one server instance per request, safe behind a load balancer. Credentials come from the x-elfa-api-key request header, falling back to the environment, or from an OAuth sign-in (see below).

DNS rebinding protection is on by default. The server accepts only the loopback names it binds — localhost:PORT and 127.0.0.1:PORT — which covers the local run above and nothing else. Any deployment that answers on a different Host must list the values it serves:

bash
ELFA_MCP_ALLOWED_HOSTS=mcp.example.com

That includes a public domain, a reverse proxy, and a container that maps the port to a different one than the server binds. A Host the list does not cover is rejected with 403.

VariableRequiredPurpose
ELFA_MCP_TRANSPORTnohttp to serve over Streamable HTTP, default stdio
ELFA_MCP_HOSTnoBind address, default 127.0.0.1
ELFA_MCP_PORTnoBind port, default 3000
ELFA_MCP_ALLOWED_HOSTSnoComma separated Host allowlist, defaults to the loopback names bound
ELFA_MCP_ALLOWED_ORIGINSnoComma separated Origin allowlist
ELFA_MCP_OPENAI_APPS_CHALLENGEnoDomain-verification token from OpenAI's plugin portal, served as plain text at /.well-known/openai-apps-challenge

Set ELFA_MCP_ALLOWED_ORIGINS as well when browsers call the server directly. It complements the host allowlist rather than replacing it: a rebound request is same origin, so it carries no Origin header for that list to check, and the Host header is the only one still naming the attacker's domain.

OAuth sign-in

A hosted server can let clients sign in through a browser instead of sending an API key. Set ELFA_MCP_AUTH=oauth and the server becomes an OAuth resource server under the MCP authorization spec:

  1. A request with no credential gets 401 and a WWW-Authenticate challenge.
  2. The challenge points the client to the protected-resource metadata at /.well-known/oauth-protected-resource/mcp.
  3. That metadata names the authorization server, where the user signs in.
  4. The client then sends Authorization: Bearer <token>.
  5. The server checks the token against the authorization server's introspection endpoint. The endpoint answers with the Elfa API key the request runs as, so the token never reaches the Elfa API.
bash
ELFA_MCP_TRANSPORT=http \ELFA_MCP_AUTH=oauth \ELFA_MCP_RESOURCE_URL=https://mcp.example.com/mcp \ELFA_OAUTH_ISSUER=https://auth.example.com \ELFA_OAUTH_INTROSPECTION_URL=https://auth.example.com/introspect \ELFA_OAUTH_INTROSPECTION_TOKEN=... \ELFA_MCP_ALLOWED_HOSTS=mcp.example.com \npx -y @elfa-ai/mcp
VariableRequired in OAuth modePurpose
ELFA_MCP_AUTHyesoauth to enable, default apikey
ELFA_MCP_RESOURCE_URLyesCanonical URL of this endpoint. Tokens must be issued for exactly this value
ELFA_OAUTH_ISSUERyesAuthorization server listed in the metadata
ELFA_OAUTH_INTROSPECTION_URLyesWhere tokens are checked
ELFA_OAUTH_INTROSPECTION_TOKENyesBearer sent to the introspection endpoint
ELFA_OAUTH_SCOPESnoComma separated scopes to advertise, default elfa

Notes:

  • An x-elfa-api-key header still works in OAuth mode.
  • ELFA_API_KEY is ignored in OAuth mode, so a caller with no credential never runs as the server's own key.
  • Valid tokens are cached for up to a minute, which bounds how long a revoked token keeps working.

Safety

api_status is the fastest way to tell an auth problem from a credit problem.

Mentions, news and narratives return third-party social text that anyone can write, events are written up from it, and the v3 tools carry third-party asset, account and channel names. The server marks it as untrusted in every response, and the server instructions tell the model to treat it as data. Keep that in mind before letting an agent chain from that content into auto_query_write.

Development

bash
npm installnpm run buildnpm run verify

npm run verify runs typecheck, tests, the spec drift check, and the docs check.

manifest.json maps every documented API operation to the tool that covers it. npm run check:drift fails if the API grows an operation the server does not handle. The tool table above is generated from the same file with npm run docs:tools.

Links

License

MIT

Source: README.md at commit 4ef1b35

Tools

16

api_status

API key status

Check the Elfa API key tier, credit usage and remaining requests, and confirm the API is reachable. Free. historyFrom is the earliest time, in unix seconds, the events, market and calls tools read on this plan.

Takes no parameters.

entities

Entities

Turn a ticker, $cashtag, name, @handle, contract address, CoinGecko id, FIGI or CIK into the entity id that events and calls take.. It matches exactly, it is not a search: a prefix or a misspelling returns nothing. A ticker is not unique, so take the first row and check its name, or narrow with entityType. Forms of an asset share one family id where known: WBTC and cbBTC are Bitcoin. Resolve once and reuse the id.

ParametersqrequiredlimitcursorentityType

events

Events

What is happening in crypto and equity markets, written up from posts across many sources.. level=events: what happened, what it names, how prices reacted where measured (impacts is empty on most events), and the posts behind it. level=storylines: the events of one development, threaded over days. level=arcs: storylines grouped into a larger movement. Search any level by topic with q, filter by asset with entityIds from the entities tool, or fetch up to 30 you hold with ids. Not returned: post text, a sentiment score or a price.

ParametersqtoidsfromsortarcIdlevellimitordercursorstatusnotable+9 more

market

Market

Whole-market views, no asset needed.. view=mindshare ranks assets by share of attention over a period, with hot on those heating up. view=call_book is the crowd's long/short lean, one bar per hour plus a live tick: read crowdingPercentile rather than longShare, since the accounts lean long almost always. view=trending_contracts ranks contract addresses by how many posts pasted them, crypto only, and the unnamed ones are often the ones worth watching.

ParameterstofromviewlimitordercursormarketperiodminMentions

calls

Calls

What accounts are doing: positions taken in posts on X and Telegram.. level=calls: each post that opened, added to, trimmed, reaffirmed, reversed, closed or stopped out of a position. level=episodes: each position from open to close, with entry and exit prices and the author's track record. level=positioning: open longs and shorts on one asset right now. level=episodes with status=open and from set to now reads what every matching account holds right now. Not returned: post text or a recommendation.

ParameterstoidsfromlevellimitordercursorhandlestatusentityIddirectionentityIds+1 more

top_accounts

Top accounts

X accounts ranked by standing (how much other accounts engage with them) or, with metric, by their track record as callers.. Standing measures attention, not accuracy; track is null for an account that has never opened a position. For the best callers use metric=alphaScore, not avgReturn, which a few big wins or a rally can top. Track metrics rank only accounts with at least 20 scored positions, over every position since late June 2026; scoredEpisodes is the number of positions behind each account's track metrics.

Parameterslimitordercursormetric

auto_build

Auto query builder

Turn a plain-language monitoring request into an EQL query. Costs 1 credit plus LLM usage. This only drafts the query: nothing runs until it is activated. Say what to watch, the threshold, and what should happen when it fires. It drafts tweet conditions only for accounts in Elfa's real-time set (included), not for other X accounts.

ParametersspeedmessagerequiredsessionId

auto_validate

Validate Auto query

Check EQL syntax and get the estimated cost of activating a query. Free. tweetAccounts lists the X account behind each tweet condition: billing=per_post accounts cost creditsPerPost for every post from the account (not replies or reposts), matched or not, while the query runs, on top of estimatedCredits. followAccounts lists the X account behind each x_follow_made or x_follow_overlap condition: billing=per_day accounts cost creditsPerDay for each UTC day their follows are read while the query runs, also on top of estimatedCredits. Pass either an inline query or a draftId. method=symbol instead checks that a symbol has market data on a venue, which price and ta conditions need.

ParametersquerytitlemethodsymboldraftIdexchangedescription

auto_query

Read Auto queries

Read side of Auto. Free. method=list browses queries, method=get polls one query and returns its latest evaluation, plus failure when it failed with a recorded reason, method=executions and method=execution show what fired, method=sessions and method=session return the LLM analysis attached to a query. There is no push channel here, poll with method=get and respect pollAfterSeconds.

ParameterstypelimitmethodrequiredoffsetsearchstatusqueryIdsessionIdexecutionId

auto_query_write

Write Auto queries

Activate, cancel or delete an Auto query. Creating costs 5 credits plus LLM usage, cancel and delete are free. An activated query runs unattended and fires its action without asking again. Per-post X accounts in its tweet conditions and per-day accounts in its x_follow_made or x_follow_overlap conditions are billed on top while it runs.

ParametersquerytitlemethodrequiredqueryIddescription

auto_draft

Read Auto drafts

Read side of Auto drafts. Free. method=list browses saved drafts, method=get returns one draft. A draft is an Auto query parked without activating it: it never evaluates and never fires.

ParameterslimitmethodrequiredoffsetsearchstatusdraftId

auto_draft_write

Write Auto drafts

Create, update, delete or activate an Auto draft. method=upsert parks a query as a draft without activating it; drafts never evaluate and never fire. method=delete removes a draft. method=convert activates a draft as a live query, which runs unattended and fires its action without asking again, and costs the same as creating a query. upsert and delete are free.

ParametersquerytitlemethodrequireddraftIddescription

mentions

Mentions

Social mentions from X and Telegram. 1 credit per call. Returns engagement metrics and a link per post, not the post text. mode=top ranks one ticker's mentions by engagement. mode=search filters by keywords or by account. mode=news returns the token news feed, which is X posts from accounts tagged as news sources rather than articles from news outlets.

ParameterstofrommoderequiredpagelimitcursortickercoinIdsrepostskeywordspageSizeverbosity+3 more

narratives

Narratives

Written narrative analysis with source links, for when counts are not enough. 5 credits per call. scope=market extracts the narratives moving the market. scope=keywords summarises events for keywords you supply, and can take over a minute to return.

ParameterstofromscopekeywordstimeFramesearchTypetimeWindowmaxNarrativesmaxTweetsPerNarrative

market_chat

Market chat

Ask Elfa for written market analysis grounded in its social data. Costs credits and varies by speed, so fast is the cheaper option. Pass sessionId from a previous reply to continue the same conversation. The reply includes sources: links to the posts and pages the research read (links only, not their text), so you can cite or check them.

ParameterschainspeedsymbolmessageusernamesessionIduseMemoryanalysisTypecontractAddress

Version history

12
  1. v4.10.0LatestNov 3, 2026
  2. v4.9.3Oct 26, 2026
  3. v4.9.2Oct 26, 2026
  4. v4.9.1Oct 21, 2026
  5. v4.9.0Oct 19, 2026
  6. v4.8.0Oct 15, 2026
  7. v4.7.0Oct 14, 2026
  8. v4.6.0Oct 14, 2026
  9. v4.5.0Oct 5, 2026
  10. v4.3.0Sep 23, 2026
  11. v4.1.0Sep 22, 2026
  12. v3.0.0Sep 16, 2026

Score

90% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts
  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts