context-mode Platform

Docs

How to use MCP and the Insights Product.

Reference · v1 · Insights Product


What is the Insights Product

The context-mode OSS plugin already ships events from every coding session — tool calls, errors, prompts, file edits. The context-mode Platform ingests those events server-side and exposes the Insights Product through three lenses: a Dashboard, a REST API, and a Remote MCP server.

Three personas, three scope ceilings. Owner sees the whole org. Manager sees the teams they are authorized for (one team for a Team Lead, several for an EM). Member sees themselves only. The same backing queries power every surface — your role decides what the queries return.

Insights are derived patterns, not raw events. The pattern engine reads the shared events table and produces findings: stuck-on-error loops, secret-exposure hits, drop in adoption, top performers, week-over-week deltas. No separate ingest pipelines per tool — one firehose feeds everything.

"Same data, different lens, three roles."


Install and connect

Two steps. Install the OSS plugin, then point it at the Platform with a one-line install script.

1
Install the OSS plugin
The plugin (open source, ELv2) emits the events. Without it, the Platform has no source to ingest.
npm
npm install -g context-mode
Claude Code marketplace
/plugin marketplace add mksglu/context-mode
2
Connect to the Platform
Run the install script with the Bootstrap Token from your dashboard invite. It writes the Machine Token to ~/.context-mode/platform.json.
# BOOTSTRAP_TOKEN comes from your dashboard invite curl -fsSL https://platform.context-mode.com/install.sh \ | bash -s -- <BOOTSTRAP_TOKEN>

The script writes a 2-field config. That is the entire client surface per ADR-0006.

// ~/.context-mode/platform.json { "api_key": "ctxm_a3f29b1c_8d4e2f9a1b6c", "platform_url": "https://platform.context-mode.com/api/v1" }

From this point the Forwarder hook (shipped with the OSS plugin) POSTs every canonical event to POST /api/v1/events — a single firehose endpoint. No per-tool routing, no client-side classification. Fire-forget, 2s timeout, returns 201.


Roles and RBAC

Three roles. Each has a hard scope ceiling enforced server-side, both in the REST middleware and in the MCP schema layer (the LLM never sees options it cannot use).

RoleScope ceilingPersona exampleDisplay
owner self + team + org CTO, founder, billing owner "Owner"
manager self + team (managed_teams) EM, Team Lead, Director, DevOps Lead "Team Lead of Backend" (1 team)
"Manager of A, B, C" (2-3)
"Manager of N teams" (4+)
member self only IC developer "Member"

managed_teams is a JSON array on the member row. Owner edits it from the dashboard. A Team Lead has one entry; an EM has several. Handlers at scope=team filter SQL by managed_teams; Owner skips the filter; Member is forced to self-scope by schema (the scope enum simply lacks "team" and "org" for member tokens).

Single-team managers see their team plus an anonymized peer comparison. Multi-team managers get fan-out queries across all teams in their array.


Remote MCP

The Insights MCP server runs on Cloudflare Workers with the McpAgent Durable Object pattern (ADR-0005). Transport is Streamable HTTP — no local install, no stdio, no extra process. Point your client at the URL with your Machine Token in the header.

Seven agents supported across two tiers. The bearer token is inlined directly into each tool's per-user config file or mcp add command — same security model as ~/.ssh/id_rsa (mode 0600, user-scoped). Works the same on macOS, Linux, and Windows. No shell profile edits.

Tier 1 — CLI install: Claude Code, Gemini CLI, Qwen Code.

# Claude Code claude mcp add \ --transport http --scope user \ --header "Authorization: Bearer ctxm_..." \ context-mode-insights "https://platform.context-mode.com/mcp/insights" # Gemini CLI gemini mcp add \ --scope user --transport http \ --header "Authorization: Bearer ctxm_..." \ context-mode-insights "https://platform.context-mode.com/mcp/insights" # Qwen Code qwen mcp add \ --scope user --transport http \ context-mode-insights "https://platform.context-mode.com/mcp/insights" \ --header "Authorization: Bearer ctxm_..."

Tier 2 — Edit config file: Codex (~/.codex/config.toml), OpenCode (~/.config/opencode/opencode.json), Cursor (~/.cursor/mcp.json), Kimi Code (~/.kimi-code/mcp.json). Token sits in the headers / http_headers field of each agent's own config — file mode 0600, no env vars.

# ~/.codex/config.toml — Codex CLI lacks --header, edit TOML directly [mcp_servers.context-mode-insights] url = "https://platform.context-mode.com/mcp/insights" [mcp_servers.context-mode-insights.http_headers] "Authorization" = "Bearer ctxm_..."
// ~/.cursor/mcp.json — inline bearer { "mcpServers": { "context-mode-insights": { "url": "https://platform.context-mode.com/mcp/insights", "headers": { "Authorization": "Bearer ctxm_..." } } } }

OpenCode and Kimi Code follow the same JSON shape under mcp / mcpServers. The Connect this machine wizard in the dashboard renders the exact command — already populated with your token — for whichever agent you pick.

On connect, the server inspects your token, resolves your role and managed_teams, and registers all 9 Insights tools with role-tuned scope enums (ADR-0007). A Member token sees only scope: "self" in tool schemas; a Manager sees "self" | "team"; an Owner sees "self" | "team" | "org". The schema is the first defense layer — the LLM cannot construct a scope outside the enum.


MCP Insights tools

Nine tools. Pick the one whose verb matches your intent. Every response includes scope_resolved.reason explaining which view the server returned and why.

find_blockers Who is stuck right now.

Persona — Berke (EM) Monday morning: "anyone blocked on error loops this week?"

find_blockers(scope: "team", period: "7d", limit: 5)

Returns — Ranked list of up to limit blockers. Each: subject, pattern_id, severity, evidence_count, suggested_action.

scopemember: team · manager: team · owner: org · period: 24h | 7d | 30d | 90d
what_changed What signals appeared this week.

Persona — EM writing the weekly summary; CTO doing a monthly review.

what_changed(scope: "org", period: "7d", limit: 8)

Returns — Two lists. new_patterns (silent before, firing now) and delta_patterns (match-count changed by 30%+ vs prior period).

scopemember: team · manager: team · owner: org
top_patterns Exploratory entry point — what's most active right now.

Persona — First call after install: "what does this thing show me?"

top_patterns(scope: "team", period: "7d", limit: 5)

Returns — Top patterns ranked by impact (severity × evidence × recency). Each: pattern_id, category, severity, match_count, one-line evidence.

scopemember: team · manager: team · owner: org
how_is_team Single-team health snapshot.

Persona — EM doing weekly team review; CTO drilling into one team.

how_is_team(team_id: "backend", period: "7d")

Returns — productivity_score, quality_score, top_3_contributors, top_3_risks, headline.

scopemember: own team only (server-bound) · manager: any team in managed_teams · owner: any team
compare_teams Cross-team leaderboard with deltas vs org median.

Persona — CTO doing org-wide comparison; Team Lead curious how they rank.

compare_teams(period: "30d", limit: 10)

Returns — Ranked teams with productivity, quality, adoption metrics + delta vs org median.

scopemember: own team + 4 anonymized peers ("Team A".."Team D") · owner: full leaderboard, all teams named
how_am_i Self snapshot + anonymized peer benchmark + recommendations.

Persona — Engineer end-of-week review; new joiner onboarding.

how_am_i(period: "7d")

Returns — productivity_score, quality_score, top_3_strengths, top_3_growth_areas, peer_benchmark (team avg), 1-3 personalized recommendations.

scopeAll roles: self only
identify_risk Risks ranked by severity — secret hits, mcp_violations, blocked-on >14d, error spikes.

Persona — CTO pre-release check; security lead reviewing the AI surface; post-mortem prep.

identify_risk(scope: "org", period: "30d", limit: 10)

Returns — Ranked risks. Each: risk_id, category (security/quality/workflow), severity, subject, evidence_count, suggested_action.

scopemember: team · manager: team · owner: org
engagement_health Adoption rate, active/inactive members, ROI estimate.

Persona — EM checking adoption after onboarding; CTO measuring ROI on the AI tooling spend.

engagement_health(scope: "org", period: "30d")

Returns — adoption_rate (0-1), active_members, inactive_members, roi_estimate (savings_hours_per_week), top_3 active, top_3 inactive.

scopemember: team · manager: team · owner: org
top_members Per-member activity leaderboard within scope.

Persona — EM doing weekly recognition or load-balancing; CTO identifying skew or burnout risk. Answers "who worked most this week".

top_members(scope: "team", period: "7d", limit: 10)

Returns — Ranked list of up to limit members. Each: member_id, name, email, team, events_count, sessions_count, commit_count, error_rate, last_event_at.

scopemember: self (single-row) · manager: team · owner: org

REST API

Same data, raw access. Useful for custom dashboards, BI imports, or wiring Insights into your existing tooling. Every request takes Authorization: Bearer ctxm_* — the same Machine Token used by the Forwarder and MCP.

Ingest

POST /api/v1/events Single firehose. Every canonical event lands in a 35-column events table. Zod discriminated union on event.type.

Query

GET /api/v1/insights Pattern findings. Filter by scope, period, category, severity.
GET /api/v1/data Raw event slices. Used by the team-health and self views.
GET /api/v1/overview Aggregate dashboard summary: counts, top movers, headline metrics.
GET /api/v1/compare Cross-team metrics; backs compare_teams.
GET /api/v1/category-analytics Adoption, engagement, effectiveness, efficiency, quality, security per category.

Org & members

GET /api/v1/orgs/teams List of valid team names in your org. Use the result when editing managed_teams.
GET /api/v1/members Member list. Visibility scoped by role.
PATCH /api/v1/members/:id Owner only. Mutates role and managed_teams.

Wire format: Authorization: Bearer ctxm_*, Content-Type: application/json, X-Schema-Version: 2.


Dashboard walkthrough

A quick tour of the web UI at platform.context-mode.com. Every tab is a different view onto the same backing queries.

Insights tab — the default landing surface. 177 patterns across 6 categories (adoption, effectiveness, efficiency, engagement, quality, security). Findings list ranks by impact score, scoped by your role.

Members tab — roster view. Owner sees everyone and can edit role + managed_teams inline. Manager sees their authorized teams. Member sees only themselves.

Settings — Org Teams list (used by managed_teams validation), Bootstrap Token generation, Machine Token rotation, billing.

Connect Machine modal — first-login UX. Generates a one-shot Bootstrap Token, shows the install script command, opens with a copy-to-clipboard CTA.


Architecture

A quick architecture reference. Full details live in the docs/adr/ directory of the repo.

Forwarder — an 80-line OSS module (hooks/platform-bridge.mjs) shipped with the plugin. Reads ~/.context-mode/platform.json on cold start and every 60s thereafter. POSTs canonical events to the firehose.

Single firehose — POST /api/v1/events is the entire ingest surface (ADR-0006). Products differ in interpretation, not transport. Insights, future Audit, future Risk Score events all flow through this one URL.

Validation — server-side Zod discriminated union on event.type (ADR-0004). The right variant validates the right payload; row lands in the 35-column events table tagged by type.

Insights engine — all 8 MCP tools route through src/insights/engine.ts::evaluatePatterns(). No tool defines its own SQL. The same in-process helpers back the REST endpoints — parity between dashboard, REST, and MCP is guaranteed by construction.

Remote MCP — Cloudflare Workers + McpAgent Durable Object (ADR-0005). Streamable HTTP transport. Per-session tool registration with role-tuned schemas (ADR-0007).


Common questions

Where is my org's data stored?
Cloudflare D1, fully isolated per org. No cross-tenant queries are possible — the org_id is enforced at the middleware layer on every request.
Can I self-host the Platform?
Not in v1. The Platform is single-tenant SaaS on Cloudflare. On-prem deployment is on the roadmap for enterprise tier. The OSS plugin remains fully self-contained and works without the Platform.
What if my org has 200+ members?
That is the Enterprise tier. Contact hello@context-mode.com for SSO, custom retention, on-prem options, and SLA.
Does the Forwarder URL ever change?
If it changes, you re-run the install script. There is no auto-update mechanism in the Forwarder — this is intentional (ADR-0006). The 2-field config is the single source of truth.
Why can't a Member see org-wide patterns?
Schema-enforced. The MCP tool registration for a Member token does not include "org" in the scope enum (ADR-0007). The LLM cannot even construct the call. The REST layer enforces the same ceiling via middleware.
Is there a free tier?
Up to a small team size for evaluation. See pricing for current limits.