Skip to main content
Glama
meticulosity-dward

AskElephant MCP

AskElephant MCP

A Cloudflare Worker that lets Meticulosity staff dig into AskElephant call transcripts from claude.ai, on the web and on mobile.

Live: https://askelephant-mcp.<your-subdomain>.workers.dev/mcp Deploy your own: SETUP.md Setup for staff: docs/install-guide.md How to ask for things: docs/usage-examples.md

Why this exists

AskElephant ships an MCP server, but it runs locally over stdio. That works for Cursor, VS Code, Windsurf and Claude Desktop, and it does nothing for claude.ai, which can only talk to a hosted endpoint. Our team works in claude.ai, so transcripts were out of reach there. This Worker is the hosted endpoint.

It is read-only. Every path to AskElephant is a GET. Nothing in this codebase can change, delete, or create anything in your AskElephant account.

Related MCP server: airspeed-mcp

The problem it actually solves

Transcripts are enormous. Measured across the real corpus:

characters

approx tokens

average call

41,518

10,400

largest measured

129,088

32,300

Handing whole transcripts to a model costs about 415,000 tokens for a forty-call search, which does not fit in a 200,000-token context window. So the design principle is:

The Worker does the reading. Claude does the thinking.

Transcript text never reaches the model unless someone explicitly asks for it. A forty-call search costs roughly 12,400 tokens instead of 415,000, because the Worker fetches the transcripts, scans them itself, and returns only the matching passages.

The five tools, cheapest first

Tool

What it does

Cost

list_meetings

Compact rows: id, title, date, duration, companies

~30 tokens per row

list_companies / list_contacts

Name to id lookup for the filters

negligible

search_transcripts

Searches inside transcripts, returns short excerpts with speaker and timestamp

~12,400 tokens for 40 calls

get_transcript

Full raw text, in chunks

up to ~32,000 tokens for one call

The tool descriptions themselves steer Claude toward the cheap ones. That is deliberate: get_transcript describes itself as expensive and points at search_transcripts first.

search_transcripts requires a narrowing filter (a date range, a company, a contact, or title terms). Without one it would scan the entire corpus of 3,705 engagements, so it refuses instead.

Architecture

claude.ai  --MCP over Streamable HTTP-->  Worker  --REST-->  app.askelephant.ai/api/v2
                                            |
                                            +-- KV cache (transcripts, 90 day TTL)

Stateless apart from the cache. No database, no ingestion pipeline, no sync job. The Worker is fully correct with the cache empty; the cache only saves refetching.

Login is Cloudflare Access over OIDC with PKCE. @cloudflare/workers-oauth-provider makes the Worker its own OAuth server so claude.ai can register itself, and delegates the actual login upstream to Cloudflare Access. Access is restricted to the named individuals in CONFIG.allowedEmails.

Repo layout

Path

What

src/config.ts

Every deployment-specific value. The seam a fork changes.

src/askelephant.ts

The only code that talks HTTP to AskElephant

src/meetings.ts

Listing and the compact projection

src/cache.ts

Read-through KV transcript cache

src/search.ts

Pure excerpt scanner, no IO

src/search_meetings.ts

Search orchestration, caps and guards

src/mcp.ts

The five tools

src/access_handler.ts

Cloudflare Access OIDC login

docs/api-notes.md

Verified AskElephant API reference. See below.

docs/api-notes.md is the valuable part

AskElephant's v2 API is not publicly documented. docs/api-notes.md records what we established by probing it, with the raw commands and raw output, including where an earlier conclusion was wrong and how it was corrected. Some of it is genuinely surprising:

  • The auth header takes the raw key with no Bearer prefix

  • processing_status reports PENDING for every engagement ever, including calls from 2023, so it is useless as a filter

  • search matches titles only, never transcript bodies, which is the entire reason the excerpt scanner exists

  • Date filters reject a plain 2026-01-01 and require a full UTC datetime

  • filter[company_ids] returns a 400 without an operator; it needs filter[company_ids][in]

  • There is no summary and no action-items content: the transcript is all you get

Every one of those cost us a bug or a wrong assumption first. Read that file before changing anything that talks to the vendor.

Development

npm install        # requires the committed .npmrc, see below
npm test           # 143 tests, no network access
npm run typecheck

Why .npmrc exists. Plain npm install fails with ERESOLVE because wrangler, agents and @cloudflare/workers-types declare peer ranges that npm's strict resolver will not reconcile, even though every individual range is satisfiable. .npmrc sets legacy-peer-deps=true, which restores npm's pre-v7 behaviour and changes which versions actually install not at all. Without that file the build is not reproducible on a clean checkout.

Tests never touch the network. Every AskElephant response in the suite comes from a recorded fixture built from real probe output.

Deploying

The Worker lives on the Meticulosity Cloudflare account. Note that a global CLOUDFLARE_API_TOKEN in a shell profile may point somewhere else entirely, so pass the token explicitly:

export CLOUDFLARE_API_TOKEN=$(security find-generic-password -s cloudflare_api_token -w)
export CLOUDFLARE_ACCOUNT_ID=<YOUR_CLOUDFLARE_ACCOUNT_ID>
npx wrangler deploy

Secrets are set with wrangler secret put and never live in this repo: ASKELEPHANT_API_KEY, ACCESS_CLIENT_ID, ACCESS_CLIENT_SECRET, ACCESS_ISSUER, COOKIE_ENCRYPTION_KEY.

Data retention

Transcripts the Worker reads are cached in Cloudflare KV with a 90 day expiry (CONFIG.cacheTtlDays). That is a retention decision, not a performance knob: without it the Worker would keep a permanent second copy of every transcript it ever read, outside AskElephant's own retention controls. Lower it if your client agreements require it.

Access and offboarding

Access is an explicit list of named people in CONFIG.allowedEmails, enforced twice: the Cloudflare Access policy names the same individuals, and the Worker re-checks the identity before registering any tools.

It is not domain-wide, and that is a correction rather than a preference. We first granted the whole @example.com domain, reasoning that revocation could be delegated upstream because everyone uses a company-controlled Claude account, so deprovisioning that account would take the connector with it. That reasoning is wrong. The connector can be added from any Claude account, including a personal one, because the only identity the Worker ever sees is the Cloudflare Access identity. This was demonstrated during setup, when two separate Claude clients registered against the same address.

Revoking someone

Removing a person from CONFIG.allowedEmails and from the Access policy stops them getting a new grant. It does not touch a grant they already hold, which lives in OAUTH_KV and keeps working until it expires.

To cut someone off immediately:

scripts/revoke.sh someone@example.com   # deletes their grants and tokens
scripts/revoke.sh --list                     # show every live grant

Do all three: revoke the grant, remove them from CONFIG.allowedEmails and redeploy, and remove them from the Cloudflare Access policy. The first cuts off the session they have; the other two stop them logging back in.

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    An MCP server that provides AI agents access to Granola meeting notes. It enables searching notes, retrieving full content with transcripts, and paginating through meeting history.
    Last updated
    3
    MIT
  • F
    license
    -
    quality
    C
    maintenance
    Remote MCP server that exposes Airspeed/Glyphic call data to Claude web, enabling tools to list, retrieve, and query calls, transcripts, snippets, and playbooks.
    Last updated
  • F
    license
    A
    quality
    C
    maintenance
    MCP server that exposes Discord and Twitch/Chatty chat log query tools to Claude Code, enabling searching messages, channel stats, user messages, and events from chat logs.
    Last updated
    7

View all related MCP servers

Related MCP Connectors

  • Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer

  • Hosted Amazon Seller and Vendor MCP server for Claude, ChatGPT, Cursor, Codex, Gemini, Copilot.

  • Hosted MCP server exposing US hospital procedure cost data to AI assistants

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/meticulosity-dward/askelephant-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server