Skip to main content
Glama
omarqx
by omarqx

logsafe

Run it: npx logsafehttp://127.0.0.1:4600

What is this

logsafe is a local debugging log server: point any app (or any HTTP client) at it and it collects log events into named sessions, stored in a local SQLite database. It groups related events (across multiple processes or sources — a browser tab and its backend, say) so you can filter, search, and tail them while you debug. A web UI for browsing sessions is included (see below); everything is also available over plain HTTP (see API.md).

Related MCP server: Firebase MCP Server

Quickstart

npm install
npm start
# [logsafe] listening on http://127.0.0.1:4600  (db: ~/.logsafe/logsafe.db, retention: 7d)

Send it a log line:

curl -s localhost:4600/v1/log -d '{"msg":"hello world"}'
# {"accepted":1,"rejected":0}

curl -s localhost:4600/api/sessions | jq

Or run the bundled demo, which emits a realistic multi-source session and verifies it back over the API:

npm run demo -- --keep   # leaves the server running so you can explore

Web UI

Build once, then the server serves the app at its own port:

npm run build:ui
npm start
# open http://127.0.0.1:4600

Session list → click into a session for the dense log stream: composable filters (ns:payment.*, level:warn,error, trace:…, bare text = full-text search) typed into the command bar as key:value tokens, an error/density minimap on the right edge (click to jump), per-row expandable ctx JSON, and a live tail over SSE that pauses when you scroll up (buffered events are counted; G resumes). Every piece of view state — filters, timestamp mode, pinned rows, selection — lives in the URL, so copying the address bar shares the exact view. Filter changes are history entries: the back button undoes them.

Keyboard map:

Key

Action

j / k

move selection down / up (pauses live tail)

Enter / o

expand/collapse the selected row's ctx

/

focus text search

f

focus the filter input

e

toggle level:warn,error

p

pin/unpin the selected row (pins survive filter changes)

t

cycle timestamps: absolute → relative → Δ from previous

g / G

jump to top / bottom (G at bottom resumes the live tail)

x

(session list) delete the selected session

Esc

leave the focused input

Timestamps show client-reported time; ordering is always the server's arrival order (seq), so interleaved multi-source sessions read in the order the server actually saw.

Dev loop for UI work: npm run dev:ui (Vite on 5173, proxying to the server on 4600).

Logging from your app

JavaScript/TypeScript: logsafe-client

Zero-dependency helper for browser or Node apps. It batches events and sends them over POST /v1/log.

import { initLogsafe, createLog } from 'logsafe-client'

const { sessionId } = initLogsafe({
  source: 'webapp',              // required: identifies this process/app
  sessionLabel: 'checkout flow', // optional, human-readable
  // url: 'http://127.0.0.1:4600' (default)
})

const log = createLog('cart')    // ns: a dotted/colon namespace for this logger
log.info('cart hydrated', { items: 3, total_cents: 8497 })
log.error('payment failed', { status: 502 })

// Follow one request/operation across sources by sharing a trace id:
const reqLog = createLog('cart:payment').withTrace(`req-${sessionId.slice(0, 6)}`)
reqLog.info('submitting payment', { provider: 'stripe' })

Events are buffered and flushed automatically (every 250ms, or immediately at 64 buffered events), and flushed on page unload via sendBeacon. Call flush() to force-send (useful before a script exits, e.g. in tests or a CLI tool).

Any other language: it's just HTTP POST

There's no SDK requirement — anything that can make an HTTP request can log to logsafe. Send a JSON object or a JSON array of objects to POST /v1/log:

curl -s localhost:4600/v1/log -d '[
  {"session_id": "s1", "source": "api", "ns": "http", "level": "info",  "msg": "GET /api/cart 200", "ctx": {"ms": 12}},
  {"session_id": "s1", "source": "api", "ns": "http", "level": "error", "msg": "POST /api/checkout 500", "ctx": {"ms": 340}}
]'
# {"accepted":2,"rejected":0}

Only msg is required — everything else has a sane default. See API.md for the full field table, coercion rules, and status codes.

For AI coding agents

If you're an agent debugging an app that logs to logsafe, this is the fast path to finding and reading its logs. Full field/param reference is in API.md.

  • Server: runs locally at http://127.0.0.1:4600 by default. Check it's up with curl -s localhost:4600/api/health{"ok":true}.

  • Find the relevant session:

    curl -s localhost:4600/api/sessions | jq

    Sessions are returned newest first. Look at label (human-readable hint), sources (which processes logged to it), error_count/ warn_count (is something obviously wrong), and status"active" means it received an event in the last 60 seconds, i.e. the app is probably still running right now.

  • Read it, narrowest filter first:

    curl -s 'localhost:4600/api/sessions/<id>/events?level=error' | jq

    Then widen as needed:

    • level=warn,error — multiple levels, comma-OR'd.

    • ns=auth:* — namespace wildcard (* only; matches any run of chars).

    • q=timeout — case-insensitive text search across msg and ctx.

    • trace=req-abc123 — follow one request/operation across every source that tagged it with the same trace id (e.g. frontend + backend for one HTTP call). These all AND together, e.g. ?level=error&source=api&trace=req-abc123 narrows to error-level events from the api source within one traced request.

  • Bulk analysis: GET /api/sessions/<id>/export.ndjson streams every matching event (same filters as above) as one JSON object per line — pipe-friendly:

    curl -s 'localhost:4600/api/sessions/<id>/export.ndjson' | jq -c 'select(.level=="error")'
  • Pagination and ordering: responses are always seq ASC (server insertion order). If next_after_seq is non-null, pass it back as after_seq on the next request to keep paging. Events carry both ts (the client's own clock, which can be skewed or backdated) and received_at/seq (server-assigned) — trust seq for ordering, not ts.

  • Live tail: GET /api/sessions/<id>/stream is an SSE endpoint that replays history then streams new events as they arrive — useful for watching a session while reproducing a bug interactively.

Hooking up an AI agent

MCP (Cursor, Claude Code, any MCP client) — logsafe ships an MCP server:

// Cursor: ~/.cursor/mcp.json
{ "mcpServers": { "logsafe": { "command": "npx", "args": ["logsafe", "mcp"] } } }
# Claude Code:
claude mcp add logsafe -- npx logsafe mcp

Tools: list_sessions, get_session, query_events, tail_session — read-only, talking to your local server (override with --url or LOGSAFE_URL).

MCP over HTTP (no subprocess) — a running logsafe server hosts MCP at /mcp:

claude mcp add --transport http logsafe http://127.0.0.1:4600/mcp
// Cursor ~/.cursor/mcp.json
{ "mcpServers": { "logsafe": { "url": "http://127.0.0.1:4600/mcp" } } }

The stdio form (npx logsafe mcp) still works for stdio-only clients.

Skill (Claude Code) — a debugging workflow skill ships in this repo/package:

# installed via npm:
cp -r node_modules/logsafe/skills/debugging-with-logsafe ~/.claude/skills/

# from source (this repo):
cp -r packages/server/skills/debugging-with-logsafe ~/.claude/skills/

(For Cursor, paste the SKILL.md body into a project rule instead.)

Configuration

Environment variables, read at server startup (npm start):

Var

Default

Notes

PORT

4600

Server listens on 127.0.0.1:<PORT> (local only, not exposed on the network). An unset/empty value uses the default; a non-numeric value logs a warning and falls back to the default rather than failing to start.

LOGSAFE_DB

~/.logsafe/logsafe.db

Path to the SQLite database file. Parent directories are created automatically. Use a throwaway path (e.g. /tmp/logsafe-test.db) for scratch/test servers so you don't pollute your real log history.

RETENTION_DAYS

7

Sessions whose most recent event (last_ts) is older than this many days are deleted (session + all its events) automatically, at startup and then hourly. Same validation as PORT: non-numeric falls back to the default with a warning. 0 or negative disables pruning entirely.

LOGSAFE_DB=/tmp/logsafe-scratch.db PORT=4601 npm start
A
license - permissive license
-
quality - not tested
B
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.

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/omarqx/logsafe'

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