TimeBack Analytics MCP Server
The MCP server for TimeBack Analytics. Exposes tools to query student learning data, analyze session patterns, and generate reports.
Version: 1.0.0
Connect to TimeBack Analytics MCP Server
Remote (HTTP)
Add the following to your ~/.cursor/mcp.json file:
{
"mcpServers": {
"timeback-analytics-mcp-server": {
"type": "http",
"url": "https://platform.timeback.com/mcps/analytics"
}
}
}
Remote (HTTP)
Add the following to your VS Code settings.json:
{
"mcp.servers": {
"timeback-analytics-mcp-server": {
"type": "http",
"url": "https://platform.timeback.com/mcps/analytics"
}
}
}
Remote (HTTP)
Run the following command:
claude mcp add --transport http timeback-analytics-mcp-server https://platform.timeback.com/mcps/analytics
In ChatGPT, go to Settings → Connectors and add the MCP server URL:
https://platform.timeback.com/mcps/analytics
Tools
The server exposes the following MCP tools:
| Tool | Description |
|---|---|
timeback_get_help_topic |
Read this server's querying playbook, in short focused topics. This is the how-to-use-me guide: progressive-disclosure workflow, hard limits, timeout tactics, anti-patterns, error recovery, data-model orientation, and worked SQL examples. Call with no argument to list the available topics; call with a topic name to read its full markdown body. TIMING: instant (static guidance; nothing is executed). TOPICS: - workflow: The three-step discovery flow, the estimate→restructure loop, cheap first steps (name→ID), and verifying empty results. - limits: Hard limits: 500-row cap, 25s timeout, single read-only SELECT, no schema prefixes, automatic org-scoping, pagination. - avoiding-timeouts: The rollup fast-path (student_daily_engagement), the two-step cohort pattern, aggregate-vs-per-event grain, and aggregating in SQL. - use-case-and-intent: Recording the use case and intent behind every query — on both the served and the unserved paths. - anti-patterns: Common anti-patterns that stall sessions or produce wrong numbers, and what to do instead. - raw-tables: Raw operational tables (public schema) for internal callers: addressing, discovery, caveats, and when to prefer the views. - error-recovery: Error messages you may hit and how to recover from each, including verifying zero-row results. - data-model: Orientation on the relations: the rollup, raw activity, integrity (aggregate vs per-event), placement, assessments, mastery, structure. - examples: Runnable SQL for the core patterns: reference lookups, the rollup, the cohort pattern, integrity, placement, assessments, verification. New to this server? Read 'workflow' first, then 'avoiding-timeouts' and 'examples' before writing event-relation queries. An unknown topic name returns the topic index. |
timeback_get_schema_overview |
Get the catalog of the TimeBack analytics database: every relation (view) with its description and bare column names. ALWAYS your first call. Call it ONCE per conversation and keep the result in context — do not re-fetch it. For internal callers (system administrators and internal clients) the catalog also lists the raw operational tables under the 'public.' prefix. Raw tables carry no curated descriptions and no stability guarantee — prefer the documented views and reach for raw tables only when the views do not carry the data (see the 'raw-tables' help topic). TIMING: 1-2 seconds. Returns: - Current database version (for SQL syntax compatibility) - organizationScope: unrestricted (boolean), visibleOrganizationCount, and platformOrganizationCount for this credential. When the two counts differ, a partialScopeWarning explains that an empty per-organization result may be a scope limit rather than absence, and that the remedy is a scope-grant request rather than an unserved-query filing about a data pipeline. - Every available relation with its description and the list of its column names (names only — no types or per-column documentation at this level) This is layer 1 of a progressive-disclosure flow. Use it to pick the 2-5 relations your question needs, then call timeback_get_relation_metadata for their full column detail before writing SQL. Do not write queries from this overview alone, and never guess column semantics. Flow: this tool → timeback_get_relation_metadata (chosen relations) → timeback_execute_query. |
timeback_get_relation_metadata |
Get full column metadata for specific relations: name, type, and a rich description per column (semantics, null behavior, join keys, example values). Optionally includes sample rows. Layer 2 of the discovery flow. Call it for ONLY the relations your question needs (typically 2-5), after picking them from timeback_get_schema_overview. Required before writing SQL — column descriptions carry the join keys and value conventions the overview omits. TIMING: 1-3 seconds, plus ~1s per relation when sampleRows > 0. Parameters: - relations: view names without a schema prefix (e.g. ["students", "sessions"]). Internal callers may also request raw tables with the 'public.' prefix (e.g. ["public.one_roster_user"]). - sampleRows: 0-10 sample rows per relation (default 0). Use 3-5 when you are unsure about value formats; sampling is org-scoped and cheap. Relations that do not exist are reported in 'notFound' — check it before assuming a relation is available. For non-internal callers, 'public.'-prefixed names always land in 'notFound'. |
timeback_estimate_query |
Check whether a query is likely to fit the 25s execution budget, using PostgreSQL's query planner (EXPLAIN) WITHOUT executing the query. TIMING: 1-2 seconds (planner analysis only, no data scanned). Run this BEFORE timeback_execute_query whenever the query has multiple joins, a whole-table aggregation, or no date filter. Returns: - verdict: 'ok' (should run comfortably), 'warning' (may be slow — consider narrowing), or 'likely_timeout' (restructure before executing; it will almost certainly hit the 25s timeout) - Estimated row count and query plan operations - Specific optimization suggestions (filters to add, joins to restructure) Workflow: estimate → if verdict is not 'ok', apply the suggestions (narrow the date range, pre-aggregate in a CTE) → re-estimate → execute. |
timeback_execute_query |
Execute a single SELECT query against the TimeBack analytics database. Layer 3 of the flow — call it after timeback_get_schema_overview and timeback_get_relation_metadata. Use the exact relation and column names they returned; never guess. TIMING: 2-10 seconds typical; complex queries 10-25 seconds. Make the database do the work: - Full PostgreSQL SELECT syntax: CTEs, window functions, subqueries, aggregations (GROUP BY, corr(), percentile_cont(), ...) - Aggregate in SQL instead of pulling raw rows to post-process - Event relations (sessions, attempts, students_xp, sessions_waste, insight views) need BOTH a literal student_id IN (...) cohort list AND a date range — platform-wide aggregations over them time out. Fetch the cohort IDs with a cheap query first (students, student_schools). Limits: - Single SELECT/WITH statement only; the connection is read-only at the database level - Maximum 500 rows returned; 'hasMore: true' means the result was truncated - Maximum 25 seconds execution time (database-enforced) - Views need no schema prefix: "SELECT * FROM students", not "SELECT * FROM analytics.students" - Internal callers may reference raw operational tables with the 'public.' prefix (e.g. "public.one_roster_user"); other callers get a permission error (see the 'raw-tables' help topic) - Results are org-scoped automatically to your authorized organizations; raw tables are not org-scoped If hasMore is true and you truly need the rest, re-run with a stable ORDER BY plus OFFSET — but prefer aggregating instead. If the query times out, narrow the date window or pre-aggregate in CTEs; do not retry unchanged. The useCase and intent parameters are required and are recorded for every query: state the stakeholder's goal and this query's purpose honestly and specifically — they are how the platform learns which questions matter. |
timeback_report_unserved_query |
Record a question that could NOT be answered because the analytics database lacks the data objects or shapes it needs — together with the full requirement set gathered from the stakeholder. Knowing that a question is not achievable is NOT enough. Before calling this tool, have a conversation with the stakeholder: ask questions until you hold a complete set of requirements (what they are trying to learn, which entities and granularity, time range, breakdowns and filters, expected output, what decision the answer feeds). Then record everything here. This record is treated like a feature request from a product manager — it is how the missing data gets built, so its completeness determines whether the work can happen without coming back to the stakeholder. After recording, tell the stakeholder their question is not supported yet and that support is in progress. TIMING: instant (log-only; nothing is executed). Returns { recorded: true } on success. |
timeback_send_session_to_guardian |
Email a Vault session link to one of the session student's open guardians. Use this after discovering guardians from the student_guardians relation. The effect is irreversible: a successful call delivers mail and must not be replayed. Parameters: - sessionId (required): the session to share - guardianId (optional): which open guardian receives the link. Omit only when the student has exactly one open guardian; when several exist, the call is refused and the error lists every candidate so you can re-issue with guardianId. TIMING: 1-3 seconds (one org-scoped resolution query plus mail delivery). Returns a receipt with sessionId, sessionUrl, guardianId, guardianName, guardianEmail, and sentAt on success. |
