Logflare Code Mode
БесплатноНе проверенEnables agents to interact with the Logflare API by writing JavaScript functions that run in a Vercel Sandbox, using three tools: search, execute_read, and exec
Описание
Enables agents to interact with the Logflare API by writing JavaScript functions that run in a Vercel Sandbox, using three tools: search, execute_read, and execute_write.
README
A Model Context Protocol server that gives an agent three tools instead of dozens for driving the Logflare Management API. The agent writes a short JavaScript function that runs inside a Vercel Sandbox and calls the API through a thin api.request() client — looping, filtering, and chaining calls in one round-trip.
This applies Cloudflare's Code Mode pattern to Logflare:
- LLMs write API-calling code more reliably than long chains of individual tool calls.
- Intermediate data stays in the sandbox, out of the model's context.
- The agent discovers endpoints with
search(the OpenAPI spec), then calls them withexecute_read/execute_write.
This is a local stdio server — one process per MCP client, communicating over stdin/stdout, the same way you'd run any locally-installed MCP server (npx, or a command/args entry in your client config). Logflare has no OAuth 2.1 authorization server, so there's no per-request bearer token to broker the way a remote streamable-HTTP server would; the API key is just an environment variable for the whole process.
Quickstart
Prerequisites: Node.js ≥ 20.12, pnpm (corepack enable provides it), a Vercel account with Sandbox access, and a Logflare API key (Logflare account → API Keys).
pnpm install
pnpm build
Copy .env.example to .env and fill in VERCEL_TOKEN/VERCEL_TEAM_ID/VERCEL_PROJECT_ID and LOGFLARE_API_KEY — the local .env is only for pnpm dev/pnpm test; a real MCP client sets these as env entries in its own config instead (see below).
Connect an MCP client — this repo ships a .mcp.json:
{
"mcpServers": {
"logflare-code-mode": {
"command": "node",
"args": ["dist/index.js"],
"env": {
"LOGFLARE_API_KEY": "${LOGFLARE_API_KEY}",
"VERCEL_TOKEN": "${VERCEL_TOKEN}",
"VERCEL_TEAM_ID": "${VERCEL_TEAM_ID}",
"VERCEL_PROJECT_ID": "${VERCEL_PROJECT_ID}"
}
}
}
}
Once published, the same thing works via npx:
{
"mcpServers": {
"logflare-code-mode": {
"command": "npx",
"args": ["-y", "logflare-mcp-code-mode", "--read-only"],
"env": { "LOGFLARE_API_KEY": "...", "VERCEL_TOKEN": "...", "VERCEL_TEAM_ID": "...", "VERCEL_PROJECT_ID": "..." }
}
}
}
Run node dist/index.js --help for the full option/env-var reference.
Try it — call execute_read with an async arrow function:
async () => {
const res = await api.request({ method: 'GET', path: '/api/sources' })
return { status: res.status, count: res.data.length }
}
You get back e.g. { "status": 200, "count": 3 } — produced by code the agent wrote, run in a sandbox that can reach only the Logflare API.
The three tools
Each takes a single code string — an async arrow function that returns a value. console.log output comes back separately as stdout.
| Tool | What it does | In scope | Annotation |
|---|---|---|---|
search |
Query the Logflare OpenAPI spec (all $refs resolved) to find endpoints and their shapes. Network-isolated. |
spec |
read-only |
execute_read |
Call the Logflare API via api.request() — GET only. |
api |
read-only |
execute_write |
Call the Logflare API via api.request() — any method (POST/PUT/PATCH/DELETE). |
api |
destructive |
The workflow is: search to find an endpoint's path and request shape, then execute_read/execute_write to call it. The client is api.request({ method, path, query?, body?, contentType?, rawBody? }), which returns { status, ok, data }.
Run with --read-only to lock the whole server instance into read-only mode: search's spec only contains GET operations (so the agent can't even discover write endpoints), and execute_write isn't registered at all — it's absent from tools/list, and calling it anyway fails as an unknown tool. This is a startup flag (a property of the process), not a per-call one.
How it works
MCP client ──stdio (newline-delimited JSON-RPC)──▶ McpServer (2 or 3 tools)
│
┌───────────────────────────────┼───────────────────────────────┐
search execute_read execute_write
│ └───────────────┬───────────────┘
▼ ▼
fresh Vercel Sandbox fresh Vercel Sandbox
(networkPolicy: deny-all) (networkPolicy: allow logflare.app;
embeds `spec` LOGFLARE_API_KEY injected;
`api.request()` client)
- Transport —
StdioServerTransportfrom the MCP SDK: reads newline-delimited JSON-RPC from stdin, writes responses to stdout. stdout is exclusively the protocol channel — all logging goes to stderr (seesrc/log.ts). - Per call — a fresh Vercel Sandbox (
@vercel/sandbox), stopped infinally. No SDK is installed inside it, so there's nothing to amortize with a warm pool. searchsandbox —networkPolicy: "deny-all"; the slimmed OpenAPI spec (fetched fromLOGFLARE_OPENAPI_URL, defaulthttps://api.logflare.app/api/openapi) is embedded asspecfor the agent's read-only code to query. In--read-onlymode the spec is filtered to GET-only operations first.execute_*sandbox —networkPolicy: { allow: ["logflare.app"] }(the Management API's actual host);LOGFLARE_API_KEYis injected as an env var and sent asAuthorization: Bearer <key>byapi.request(). The read/write split and the credential/backend/team block are enforced by the providedapi.request()client:execute_readthrows on any non-GET before the fetch, and both tools refuse the paths inBLOCKED_PATH. This is a guard against accidental or confused agent behavior, not a hard sandbox capability restriction — agent code is plain Node with the globalfetchin scope, so it could in principle calllogflare.appdirectly and bypass both checks. Safety for a genuinely adversarial caller rests on the fact that they're using their own API key against an API they already have full access to, not on this guard.- Runner — agent code is written to a file and run with
node(nevereval); output returns via a result file. The code sits on its own lines in the invoke scaffold, so a trailing// commentcan't swallow the closing tokens. - Vercel credentials — explicit
VERCEL_TOKEN/VERCEL_TEAM_ID/VERCEL_PROJECT_IDare required (this process never runs on Vercel itself, so there's no ambient OIDC fallback in practice).
The source is small and layered by responsibility:
| File | Responsibility |
|---|---|
src/index.ts |
Entry point: parses --read-only/--help, loads .env, starts the stdio transport. |
src/server.ts |
The MCP surface: the two or three tools (depending on read-only mode), response formatting, the untrusted-data boundary. |
src/sandbox.ts |
Sandbox plumbing: runner construction, the two sandbox shapes, the injected api.request() client, output caps, the credential/backend guard. |
src/spec.ts |
Fetches, $ref-resolves, slims, caches, and (optionally) GET-filters the Logflare OpenAPI spec for search. |
src/log.ts |
pino logger (stderr only) + credential redaction. |
Security notes
Agent code is untrusted but runs inside a Vercel Sandbox microVM and authenticates with the caller's own Logflare key — so by design it can use that key against the Logflare API. Beyond the sandbox isolation, per-tool egress, and read/write split above:
- Untrusted-data boundary — all execute output (
result/stdout/stderr) may embed API content (log events, source metadata), so it's wrapped in a<untrusted-data-{uuid}>…</>envelope (error path too), with the model told not to follow instructions inside. Truncation happens before wrapping, so a size cap can't sever the closing tag. - Credential/backend/team block — paths containing
access-tokens(mints/lists/reveals full API tokens),backends(backendconfigcan embed DB passwords, service-account keys, and other connection secrets), orteams(the Team response embeds the fullUserobject, whoseapi_keyis the account's master Logflare API key) are refused, matched anywhere in the path (e.g./api/sources/{id}/backends/{id}). The path is first normalized to a fixpoint (percent-decode, re-resolve dot-segments, collapse slashes, lowercase), so encoded spellings (/%61ccess-tokens,//backends,/x%2F..%2Fbackends,/TEAMS) still match; it only over-blocks. This guard covers the intendedapi.request()path; see the caveat above about rawfetchin the sandbox. - Known gap — some
Sourcefields (slack_hook_url,webhook_notification_url) embed secrets the caller configured (their own Slack webhook, etc.) rather than Logflare-minted credentials. These are not blocked, the same way reading your own resource's other fields isn't blocked — but a prompt-injected agent could still surface them into its context viaexecute_read/execute_write, same as any other resource field. - Output caps — bounded inside the sandbox before reaching the server: runner result cap (400k chars),
head -creads (500k file / 20k per stream), final server truncate (100k result / 10k logs). - Token location — like Vercel Sandbox generally, there's no outbound-fetch proxy hook to keep the token out of the isolate, so
LOGFLARE_API_KEYlives in the sandbox env (agent code can read it). Safety rests on isolation + egress — the key only reacheslogflare.app— not token secrecy. - Single-tenant by design — there's no bearer-token auth gate because there's nothing to gate: this process is spawned per-caller by an MCP client, already scoped to whoever's shell/config started it, unlike the remote-HTTP shape this was originally built as (see
git log— the streamable-HTTP version is preserved in history if a remote deployment is ever needed again).
Configuration
| Env var / flag | Default | Meaning |
|---|---|---|
LOGFLARE_API_KEY (env) |
— | Required. The Logflare API key used for every execute_read/execute_write call. |
VERCEL_TOKEN (env) |
— | Required. Vercel API token for sandbox creation. |
VERCEL_TEAM_ID (env) |
— | Required. Vercel team ID for sandbox creation. |
VERCEL_PROJECT_ID (env) |
— | Required. Vercel project ID for sandbox creation. |
--read-only (CLI flag) |
off | Hide execute_write; restrict search's spec to GET operations. |
LOGFLARE_SANDBOX_RUNTIME (env) |
node24 |
Vercel Sandbox runtime the sandboxes boot from |
LOGFLARE_EXEC_TIMEOUT_MS (env) |
120000 |
Per-call budget for the agent's code |
LOGFLARE_OPENAPI_URL (env) |
https://api.logflare.app/api/openapi |
Override the OpenAPI spec URL the search tool loads |
LOG_LEVEL (env) |
info |
trace/debug/info/warn/error/fatal/silent |
LOG_FORMAT (env) |
json |
json (structured) or pretty (dev) |
Observability
Structured logs via pino to stderr only — stdout is reserved for JSON-RPC. One line per tool invocation/completion (tool name, code length, duration, calledEndpoints count for execute calls) plus a startup line noting read-only mode. Use LOG_FORMAT=pretty locally. Credentials are never logged (see redactToken in src/log.ts).
Testing
pnpm test
test/server.test.ts— the MCP surface via an in-memory client/server pair (tool list, annotations, error shapes,readOnly: truehidingexecute_write). No key.test/stdio.test.ts— end-to-end over the real stdio transport: spawns the built binary as a child process and speaks newline-delimited JSON-RPC over its stdin/stdout, exactly like a real MCP client. Covers--help,--read-onlyover the wire, and that stdout only ever carries JSON-RPC (logs land on stderr). No key. Requirespnpm buildfirst.test/sandbox.test.ts— offline unit tests for the credential/backend/team guard (path normalization + block regex). No key, no sandbox.test/spec.test.ts— offline unit tests for the read-only spec filter (GET-only operations, paths with no GET dropped entirely). No key, no network.test/live.test.ts— end-to-end against real Logflare + Vercel Sandbox: spec search,execute_readGET plus non-GET rejection, trailing-comment tolerance, error/SyntaxErrorsurfacing inside the boundary, the credential/backend/team guard (including encoded bypasses), anexecute_writecreate+delete round-trip, egress denial, and the stdout size cap. Runs only whenLOGFLARE_API_KEYand theVERCEL_*credentials are set.
Установка Logflare Code Mode
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/Rodriguespn/logflare-mcp-code-modeFAQ
Logflare Code Mode MCP бесплатный?
Да, Logflare Code Mode MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Logflare Code Mode?
Нет, Logflare Code Mode работает без API-ключей и переменных окружения.
Logflare Code Mode — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Logflare Code Mode в Claude Desktop, Claude Code или Cursor?
Открой Logflare Code Mode на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
GitHub
PRs, issues, code search, CI status
автор: GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
автор: mcpdotdirectCompare Logflare Code Mode with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории development
