Product Flows

AI Connectors (MCP)

Connecting Claude, ChatGPT and other assistants to a Logga workspace over the Model Context Protocol.

Logga speaks the Model Context Protocol. Point an AI client at https://api.logga.sh/mcp with a connector token and the assistant can read the event stream, run analytics, look up an end user's history, and log events back into Logga — where the usual channel rules turn them into a push notification.

The connector is bound to one workspace and one environment, fixed by the token. There is no argument on any tool that reaches another.

Creating a token

From the web dashboard: Settings → AI connectors → Create connection.

From the iOS app: Settings → AI Connectors → Create connection.

Both produce a lg_mcp_… token that is shown exactly once. The server stores a SHA-256 digest, so a lost token cannot be recovered — revoke it and create another. Both screens offer a Read only switch; see Scopes.

Connecting a client

Claude Code

bash
claude mcp add --transport http logga https://api.logga.sh/mcp \
  --header "Authorization: Bearer lg_mcp_your_token"

Claude Desktop, Cursor, VS Code

json
{
  "mcpServers": {
    "logga": {
      "type": "http",
      "url": "https://api.logga.sh/mcp",
      "headers": { "Authorization": "Bearer lg_mcp_your_token" }
    }
  }
}

Clients that only accept a URL

Some hosted clients give you a URL field and nowhere to put a header. For those, the token can ride in the path:

text
https://api.logga.sh/mcp/k/lg_mcp_your_token

This form works everywhere the header form does, but a URL travels through address bars, proxy logs and screen shares in a way a header does not. Prefer the header when the client allows it, and treat a URL-form token as more disposable: give it read-only scopes and a shorter life.

What the assistant can do

Twenty-one tools, grouped by what they are for.

Group Tools
Discovery get_project_overview, list_projects, list_channels
Events search_events, get_event, log_event
Portable search search, fetch
Analytics run_analytics_query, run_funnel_query, run_retention_query, get_user_growth
End users list_tracked_users, get_tracked_user
Sessions list_sessions, get_session, start_session, update_session
Alerting list_alert_rules, create_alert_rule, list_notifications

get_project_overview is the one that makes the rest work: it returns the project's channels, the event types actually seen in the last 90 days, the level distribution, the metadata keys with sample values and the user property keys. An assistant that skips it invents event names, and an invented name returns zero rows — which reads as "it never happened".

run_analytics_query is the same aggregation engine the in-app analytics agent uses: counts, sums, averages and percentiles, grouped by channel, event type, level, user, a metadata path, a user property (user.plan) or a time bucket, and optionally narrowed to users whose properties match (userFilters).

run_funnel_query and run_retention_query answer the questions a single aggregate cannot, because they follow each user across events: how many users went from signup to their first report, in order and within a week, and how many of the users who signed up in a given week came back in the weeks after. Both take the same userFilters. A retention period that has not started yet comes back as null, and the tool description tells the assistant not to read it as zero. User properties are read as they are now, not as they were when the event happened.

search and fetch exist because ChatGPT's connectors look for those two names specifically and ignore a server without them. They are a thin surface over the same data — a client that has the full tool list will use the more specific tools.

Prompts

Four prompt templates ship with the server and appear in clients that support them (/logga slash commands in Claude Desktop):

  • health_check — a short, honest read on the last day
  • incident_review — investigate an error spike: what, when, who, and why
  • user_story — reconstruct one end user's experience
  • alert_audit — review the alert rules against what actually fired

Writing back

log_event, start_session, update_session and create_alert_rule change things. The interesting one is log_event: an event written to a channel with notifications enabled sends a push to the phone, so "tell me when you've finished" is a matter of the assistant logging its own completion rather than a separate notification API.

A long piece of work is better modelled as a session: start_session opens it, log_event with the session id attaches each step, and update_session moves the progress bar and closes it. The result is watchable from the iOS app while it runs.

Scopes

A token carries an explicit scope list. Two presets exist, and the dashboard's read-only switch chooses between them:

Preset Scopes
Read only events:read, analytics:read, channels:read, sessions:read, users:read, rules:read, notifications:read
Default the above plus events:write, sessions:write, rules:write

Tools a token has no scope for are not listed at all — an assistant is never shown a tool it would then fail to call.

Scopes apply to the REST API too. A request with a token missing the scope its route needs gets a 403 insufficient_scope naming the scope it wanted. Keys created before scopes existed carry an empty list, which means unrestricted; every key created since carries an explicit one.

Tokens may also carry an expiry (expiresInDays on the create endpoint). An expired token is rejected exactly like a revoked one.

Transport details

Streamable HTTP, stateless. Every request is a POST carrying one JSON-RPC 2.0 message, answered in the response body. There is no session id, no SSE stream and no server-initiated message, so a redeploy mid-conversation costs nothing.

  • POST /mcp — the endpoint. initialize, tools/list, tools/call, prompts/list, prompts/get, ping.
  • GET /mcp405, with a JSON body describing how to connect.
  • Protocol versions: 2025-06-18, 2025-03-26, 2024-11-05. A client asking for anything else is answered with the newest of those.
  • Rate limit: 600 requests per 15 minutes per token.

Tool failures — a channel that does not exist, a query the compiler rejected — come back as a normal result with isError: true, so the assistant reads the message and tries something else. JSON-RPC errors are reserved for failures that stop the call: an unknown method, malformed params.

Security notes

  • The token fixes the workspace and environment. Nothing in a tool argument can widen that.
  • Metadata payloads are clipped in list results and returned in full only by get_event.
  • The MCP endpoint logs redact anything shaped like a Logga key, including inside a URL path.
  • Revoking a connection takes effect on the next request; there is no cached session to expire.