Skip to main content
Glama
199,110 tools. Last updated 2026-06-13 12:10

"Firebase" matching MCP tools:

  • Run a JavaScript orchestration script in a sandboxed QuickJS runtime. This is a REPLACEMENT for chaining individual tool calls, not a supplement — one runScript call does what would otherwise take 10+ sequential tool invocations. ── READ-ONLY (analytics and reporting only) ── runScript is a READ-ONLY analytics sandbox. ads.gaql() and ads.gaqlParallel() only execute SELECT GAQL queries — they cannot pause, update, create, or delete anything. To mutate the account (pause keywords, update bids, create campaigns, add negatives, etc.), call the dedicated mutation tools (pauseKeyword, updateBid, bulkPauseKeywords, pauseCampaign, createCampaign, addNegativeKeyword, etc.) directly. Never try to perform mutations inside a runScript call. ── WHEN TO USE THIS ── This is the DEFAULT tool for any open-ended analytical question about a Google Ads account. Reach for it first when you see: - "How is my account doing?" / "What's working?" / "What's broken?" / "How did last week go?" - "Audit my account" / "Find wasted spend" / "What should I change?" / "Any quick wins?" - Any question where you would otherwise fire 3+ read tools back-to-back - Any question that benefits from correlating surfaces (spend + search terms + quality scores + change events) in a single pass runScript owns EVERY read of Google Ads data. There are no point-query read tools anymore — if the caller asks for spend, CPA, search terms, keywords, ads, impression share, or anything else expressible in GAQL, you write a runScript that queries it. The only non-runScript reads are for specialized services that aren't GAQL-expressible: searchGeoTargets, getChanges (NotFair's own change log), reviewChangeImpact, getKeywordIdeas. For schema discovery before a query, use getResourceMetadata and listQueryableResources. ── BATCHING DISCIPLINE (read this first) ── Prefer ONE runScript call that fans out with ads.gaqlParallel (up to 20 queries concurrently) and does the full analysis in-script. Each runScript invocation costs ~5–10s of model deliberation PLUS the max GAQL latency across its queries. Batching 15 queries in one call ≈ 1 round-trip; doing the same across 5 calls ≈ 5 round-trips (5x slower). Rules of thumb: - Cast a wide net on the first call. You have 20 parallel slots — use them even if you're not sure yet what you'll need. Filtering in-script is free. - Do NOT make follow-up runScript calls just to pull one more surface you should have included. If you catch yourself about to call runScript a second time, ask: "could I have put this in the first batch?" (almost always yes). - Return the finished analysis (rankings, top offenders, aggregates), not raw GaqlReport.rows arrays. The caller reads your return value into context — summarize first. ── API SURFACE (all on the `ads` namespace) ── Async RPCs: - ads.gaql(query, limit?, options?) -> GaqlReport — single GAQL query. THIS IS THE ENTRY POINT FOR AD-HOC QUERIES. For one-off data pulls, use `return await ads.gaql('SELECT ...')` — there is no separate runGaqlQuery tool. - ads.gaqlParallel([{name, query, limit?}, ...], options?) -> { [name]: GaqlReport } — max 20 per call. USE THIS for multi-surface analysis. Fails the whole call if any subquery errors; pass `{ partial: true }` only when you explicitly want `{ error }` entries mixed with successful reports. - options.excludeRemovedParents defaults to true. Rows under REMOVED campaigns/ad groups are filtered out server-side because most audits need current serving state. Pass `{ excludeRemovedParents: false }` only for historical analysis. Canonical gaqlParallel shape: const r = await ads.gaqlParallel([ { name: "campaigns", query: `SELECT campaign.id, campaign.name, metrics.cost_micros FROM campaign WHERE segments.date DURING LAST_30_DAYS`, limit: 50 }, { name: "searchTerms", query: `SELECT search_term_view.search_term, metrics.clicks, metrics.conversions FROM search_term_view WHERE segments.date DURING LAST_30_DAYS`, limit: 100 }, ]); const campaigns = r.campaigns.rows ?? []; For intentional partial success: const r = await ads.gaqlParallel([...], { partial: true }); const rows = "error" in r.searchTerms ? [] : r.searchTerms.rows; Pre-built GAQL strings (sync, no RPC cost): - Parameterless: ads.queries.accountInfo | geoTargeting | qualityScores | adGroups | conversionActions | recommendations | billingSetups | audienceSegmentCheck | negativeKeywords | campaignAssets | adGroupAssets | sharedNegativeKeywordLists | sharedNegativeKeywordMembers | pausedCampaigns | customerManagerLinks - Date-windowed builders (call with YYYY-MM-DD): ads.queries.campaigns(start,end) | keywords | searchTerms | convertingSearchTerms | zeroConversionKeywords | ads | devicePerformance | networkSegmentation | landingPages | changeEvents | dailyCampaignMetrics | conversionActionPerformance - Canonical audit pack: ads.queries.auditPack(start,end) -> 23 named queries covering setup, campaigns, keywords, search terms, ads/assets, negatives, conversion actions/performance, recommendations, billing setup, paused campaigns, manager links, and recent Google-side change events. Prefer this for account audits instead of hand-selecting a narrow subset. Sync helpers: ads.helpers.getDateRange(days), formatDate, micros, toMicros, normalizeCustomerId, daysBetween, extractChangedFields, generateBrandVariants Constants: ads.constants.RESOURCE_CHANGE_OP, CHANGE_RESOURCE_TYPE, CHANGE_CLIENT_TYPE (numeric enum → label maps) ── HUMANIZED RESPONSES + REPORT METADATA ── Every GaqlReport includes meta: asOf, resource, dateRange/days, currencyCode/timeZone when selected, reportingLagDays, row limits/truncation, removed-parent behavior, campaign/ad-group status filters, campaign type filters, and data-completeness warnings. Read meta before making freshness/exhaustiveness claims. Rows are augmented post-fetch so you can read the LLM-friendly form directly: - Enum integer fields get a sibling `<field>_name` (canonical Google Ads enum name). Read `bidding_strategy_type_name === "MAXIMIZE_CONVERSIONS"`, not the integer 10. Avoids the BiddingStrategyType landmines (10=MAX_CONVERSIONS, 11=MAX_CONVERSION_VALUE, 9=TARGET_SPEND/MaxClicks, 15=TARGET_IMPRESSION_SHARE). - Money fields ending `_micros` get a sibling `<base>_value` in major units (`cost_micros: 11_000_000` ⇒ `cost_value: 11`). Currency-agnostic — works for USD/EUR/JPY. Raw `_micros` is preserved. ⚠ IMPORTANT: `_name` / `_value` siblings are NOT GAQL fields — do NOT put them in SELECT or WHERE. They appear automatically in result rows when the corresponding raw field is selected (`_name` → base enum field; `_value` → the `_micros` field). ── DATE LITERALS (GAQL only supports a fixed set) ── Valid `DURING` literals: TODAY, YESTERDAY, LAST_7_DAYS, LAST_14_DAYS, LAST_30_DAYS, THIS_MONTH, LAST_MONTH, LAST_BUSINESS_WEEK, LAST_WEEK_MON_SUN, LAST_WEEK_SUN_SAT, THIS_WEEK_MON_TODAY, THIS_WEEK_SUN_TODAY. **There is no LAST_60_DAYS, LAST_90_DAYS, LAST_180_DAYS, THIS_YEAR, or LAST_YEAR.** For windows >30 days, use a custom range: const { start, end } = ads.helpers.getDateRange(90); const q = `SELECT campaign.id, metrics.cost_micros FROM campaign WHERE segments.date BETWEEN '${start}' AND '${end}'`; (As a backstop, the server auto-rewrites unsupported `DURING LAST_N_DAYS`/`THIS_YEAR`/`LAST_YEAR` to BETWEEN, but writing it correctly is faster and clearer.) Note: `change_event` only supports the last 30 days regardless of how you express the range. ── COMMON GOTCHAS (the validator will reject these before they reach Google) ── - **change_event REQUIRES `change_event.change_date_time` in WHERE.** `segments.date DURING ...` does NOT work for this resource (Google rejects with change_event_error=3). Window cap is 30 rolling days. Easiest: `ads.queries.changeEvents(start, end)` builds the right shape. - **GAQL has no SQL JOIN.** Select compatible related-resource fields directly from one FROM resource (`campaign_budget.amount_micros` can be selected from `FROM campaign`), or run two queries and join rows in JavaScript. - **Enums in WHERE are STRING names, not numbers.** Write `WHERE campaign.status = 'PAUSED'`, never `= 3`. Same for `ad_group.status`, `ad_group_ad.status`, `ad_group_criterion.status`, `conversion_action.status`, `asset_group.status`. Valid status values: ENABLED, PAUSED, REMOVED. For other enums (advertising_channel_type, bidding_strategy_type, etc.), call `getResourceMetadata` with the query's FROM resource, e.g. `getResourceMetadata('campaign')`. - **Manager-link status has no REMOVED enum.** For `customer_manager_link.status`, use ACTIVE, INACTIVE, PENDING, REFUSED, or CANCELED; omit the filter if you only want all rows. - **`metrics.*` is NOT selectable from `FROM conversion_action`.** That resource carries dimensional fields only (name, type, status, counting). To break down metric counts by conversion action: query `FROM campaign` (or `ad_group`) and SELECT `segments.conversion_action_name`. To list configured actions: drop the metrics and keep only `conversion_action.*` fields. - **Local Services conversion actions are often segment-only.** LSA / `local_services_*` conversion names can appear in `segments.conversion_action_name` but not as mutable rows in `FROM conversion_action`. Before calling `updateConversionAction` / `removeConversionAction`, check `conversion_action.type` and `conversion_action.owner_customer` (e.g. via `ads.gaql(ads.queries.conversionActions)`); if the type is GA4/UA/Floodlight/Firebase/Salesforce/SA360 imports, Smart Campaign auto-actions, Store Visits, app-store actions, or the owner_customer points at a different customer (manager-inherited), treat as Google-managed/read-only. - **`segments.conversion_action_name` and friends don't pair with `metrics.cost_micros`.** Google reports cost at the campaign/ad_group level, not per conversion action — pick one or the other (query_error=53). For per-action cost-per-conversion, divide `cost_micros` (campaign-total) by per-action `metrics.conversions` in-script. - **Fields used in WHERE must also be in SELECT** (query_error=16). The server auto-injects `campaign.status`/`ad_group.status` for REMOVED-parent filters and promotes non-date `segments.*` predicate fields into SELECT automatically. Date segments are left unselected to avoid changing row granularity. - **`segments.date BETWEEN` takes explicit ISO dates only.** Do not write `BETWEEN 'LAST_30_DAYS' AND 'undefined'`; use `segments.date DURING LAST_30_DAYS`, or use `ads.helpers.getDateRange(days)` and interpolate `YYYY-MM-DD` dates. - **`search_term_view` requires a finite `segments.date` filter.** Include `segments.date DURING LAST_30_DAYS` or a `BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'` clause. - **`keyword_view` includes ad-group-level NEGATIVES.** Filter `ad_group_criterion.negative = FALSE` for positives only — and add `ad_group_criterion.negative` to your SELECT (predicate-fields-must-be-in-SELECT applies). Negatives have 0 impressions/clicks/cost/conversions by definition (they block serving), so any `metrics.* = 0` filter without this predicate sweeps up every negative in the account. - **Keyword quality fields are split by resource.** Query delivery metrics (`metrics.clicks`, `metrics.cost_micros`, conversions, etc.) from `FROM keyword_view`. Query quality-score fields from `FROM ad_group_criterion` without metrics: `ad_group_criterion.quality_info.quality_score`, `creative_quality_score`, `post_click_quality_score`, and `search_predicted_ctr`. There is no `metrics.quality_info.quality_score`, `ad_group_criterion.quality_info.ad_relevance`, or `ad_group_criterion.quality_info.landing_page_experience`. - **Known hallucinated fields:** there is no `metrics.average_cpc_micros`, `metrics.cost_per_conversion_micros`, `metrics.impression_share`, `metrics.search_lost_is_rank`, `metrics.search_lost_is_budget`, `metrics.conversion_rate`, `metrics.quality_info.quality_score`, `asset.status`, `asset_group_asset.performance_label`, `asset.sitelink_asset.final_urls`, `campaign.url_expansion_opt_out`, `campaign.budget_micros`, `campaign.budget_amount_micros`, `campaign_criterion.proximity.address.city`, `campaign_criterion.audience.audience`, `change_event.campaign.name`, `change_event.resource_type`, `ad_group_criterion.quality_info.ad_relevance`, `ad_group_criterion.quality_info.landing_page_experience`, `campaign_experiment.*`, `conversion_action.default_value`, `conversion_action.last_conversion_date`, `conversion_action.most_recent_conversion_date`, `recommendation.impact.base_metrics.*`, `recommendation.keyword_match_type`, `billing_setup.payments_account_info.*`, `auction_insight.domain`, or bare `resource_name`. Use `metrics.average_cpc`; use `metrics.cost_per_conversion`; for Search campaigns use `metrics.search_impression_share`, `metrics.search_rank_lost_impression_share`, and `metrics.search_budget_lost_impression_share`; calculate conversion rate from `metrics.conversions / metrics.clicks`; budget lives on `campaign_budget.amount_micros`; asset serving status lives on the link resource (`campaign_asset.status`, `ad_group_asset.status`, `asset_group_asset.status`, `customer_asset.status`); use `campaign_criterion.proximity.address.city_name`; use `change_event.change_resource_type`; use `conversion_action.value_settings.default_value`; use `ads.queries.billingSetups` for safe billing reads; replace `resource_name` with `<resource>.resource_name`; call `getResourceMetadata(<resource>)` for the rest. Rules: top-level await works; no fetch/require/process/fs; return value must be JSON-serializable; defaults are 30s timeout (max 45s), 500KB return cap, 100K log chars. ── CANONICAL AUDIT (one call, wide net, filter in-script) ── const { start, end } = ads.helpers.getDateRange(30); const r = await ads.gaqlParallel(ads.queries.auditPack(start, end)); // Inspect r.campaigns.meta / r.searchTerms.meta for freshness, filters, and truncation before concluding. const worstCampaigns = (r.campaigns.rows ?? []) .map(c => ({ name: c.campaign.name, spend: c.metrics.cost_micros / 1e6, cpa: (c.metrics.cost_micros / 1e6) / (c.metrics.conversions || 1), convRate: c.metrics.conversions / (c.metrics.clicks || 1), })) .sort((a, b) => b.cpa - a.cpa).slice(0, 5); const topZeroConvKws = (r.zeroConversionKeywords.rows ?? []).slice(0, 10).map(k => ({ text: k.ad_group_criterion.keyword.text, spend: k.metrics.cost_micros / 1e6, })); return { worstCampaigns, topZeroConvKws, /* ... aggregates only, not raw rows ... */ }; ── ANTI-PATTERNS (don't) ── - Calling runScript 5+ times in sequence to fetch different surfaces — that's exactly what gaqlParallel replaces. - Using ads.gaql in a JS loop when the queries are independent — use gaqlParallel. - Returning entire GaqlReport.rows arrays — summarize, rank, or aggregate first. - Passing non-SELECT statements to ads.gaql() — GAQL is read-only, the call will throw immediately. Mutations go through dedicated tools, not runScript.
    Connector
  • Update an existing conversion action's settings — promote secondary to primary, change value, rename, fix currency. Conversion actions imported from GA4/UA/Floodlight/Firebase/Salesforce/Search Ads 360, Smart Campaign auto-actions, Store Visits, app-store actions, local_services_* / Local Services Ads actions, and manager-inherited actions are read-only via the API — the update call will be rejected locally before reaching Google. To check before calling: read `conversion_action.type` and `conversion_action.owner_customer` via `runScript` (e.g. `await ads.gaql(ads.queries.conversionActions)`) or write a direct `FROM conversion_action` query. LSA conversion names may appear in segments.conversion_action_name without appearing as mutable FROM conversion_action rows. To delete a conversion action, use removeConversionAction (status=REMOVED is not accepted by Google for updates). Returns changeId.
    Connector
  • P109 — pull a Hacker News post's score + comments + top replies via the public HN API and write them to the action's metadata.proof. USE WHEN a published Hacker News action is ripe for 24h measurement (checks the publishedUrl on the action, parses the item id, calls the Firebase API). Auto-creates a next-move action based on the outcome (trending → reply + cross-post; engaged → reply; stalled → rewrite angle). Idempotent — second call returns the existing measurement. No API key required; HN is public-read.
    Connector
  • Authenticated — append a free-text evidence note to a specific stage in the caller's active course. Notes record concrete implementation observations, decisions, or artefacts that demonstrate progress through a Blueprint principle (e.g. how a delegation boundary was implemented, what approval flow was chosen and why). Persisted as UserStageEvidence rows scoped to (user_id, course_slug, stage_slug). WHEN TO CALL: AFTER the user has articulated something concrete they have built, observed, or decided — not to capture intent or speculation. Pair with me.coaching_context to close evidence gaps. WHEN NOT TO CALL: to log every conversation turn; to record planning, ideas, or todos; on behalf of another user; without the user's awareness (they should know their progress is being recorded). BEHAVIOR: write-only, single insert. Auth: Bearer <token> (Firebase ID token, any plan). UK/EU residency. Notes are visible only to the owning user and are surfaced on me.learning_path / me.coaching_context. Confirms the stage_slug + course_slug pair in the response so the user can see which stage was credited.
    Connector
  • Authenticated — submit an agency engagement enquiry on behalf of the caller for a founder-led discovery call. Persists an AgencyHandoff row routed to the agency inbox; the user is contacted by the team for a scoped proposal. Engagement scopes: workflow sprint (rapid agentic workflow implementation), proof-of-concept (validate a specific agent design in a bounded timeframe), pilot support (co-design and validate a production-ready pilot), advisory (ongoing architectural guidance across a product team). WHEN TO CALL: the user has identified a paid hands-on expert engagement need beyond self-service learning, and explicitly asks to talk to the team or book a discovery call. ALWAYS confirm with the user before firing — this creates a sales-visible record. WHEN NOT TO CALL: for free training / partnerships discussion (use handoffs.partnership); for support / billing / access (use handoffs.operator); proactively or as a sales push. BEHAVIOR: write-only, single insert, side-effecting. Auth: Bearer <token> (Firebase ID token, any plan). UK/EU residency. Response confirms the ticket id + scope so the user can reference it.
    Connector
  • Use this tool to find documentation about Google developer products. The documents contain official APIs, code snippets, release notes, best practices, guides, debugging info, and more. It covers the following products and domains: * ADK: adk.dev * Android: developer.android.com * Apigee: docs.apigee.com * Chrome: developer.chrome.com * Dart: dart.dev * Firebase: firebase.google.com * Flutter: docs.flutter.dev * Fuchsia: fuchsia.dev * Gemini CLI: geminicli.com * Go: go.dev * Google AI: ai.google.dev * Google Antigravity: antigravity.google * Google Cloud: cloud.google.com & docs.cloud.google.com * Google Developers, Ads, Search, Google Maps, Youtube: developers.google.com * Google Home: developers.home.google.com * Google Maps Platform: mapsplatform.google.com * TensorFlow: www.tensorflow.org * Web: web.dev This tool returns chunks of text, names, and URLs for matching documents. If the returned chunks are not detailed enough to answer the user's question, use `get_documents` with the `parent` from this tool's output to retrieve the full document content.
    Connector

Matching MCP Servers

  • A
    license
    -
    quality
    D
    maintenance
    The Firebase MCP server provides a standardized interface to interact with Firebase services, including Firebase Authentication, Firestore, and Firebase Storage.
    Last updated
    1,024
    245
    MIT
  • -
    license
    -
    quality
    -
    maintenance
    A Model Context Protocol server that exposes Firebase Firestore and Authentication to AI agents, supporting multi-project configurations and read operations.
    Last updated

Matching MCP Connectors

  • Automate business cases, articulate customer outcomes & analyze your value-selling motion with Minoa

  • The industry standard reference for safe, observable, and steerable AI agent UX. Browse and search the 10 Blueprint principles, principle clusters, curated implementation examples, and application guides. 13 public tools require no credentials. Tools for learning path, coaching context, and handoffs require a Firebase Bearer token. Validation and usage summary tools require a Pro or Teams membership.

  • Authenticated — submit an agency engagement enquiry on behalf of the caller for a founder-led discovery call. Persists an AgencyHandoff row routed to the agency inbox; the user is contacted by the team for a scoped proposal. Engagement scopes: workflow sprint (rapid agentic workflow implementation), proof-of-concept (validate a specific agent design in a bounded timeframe), pilot support (co-design and validate a production-ready pilot), advisory (ongoing architectural guidance across a product team). WHEN TO CALL: the user has identified a paid hands-on expert engagement need beyond self-service learning, and explicitly asks to talk to the team or book a discovery call. ALWAYS confirm with the user before firing — this creates a sales-visible record. WHEN NOT TO CALL: for free training / partnerships discussion (use handoffs.partnership); for support / billing / access (use handoffs.operator); proactively or as a sales push. BEHAVIOR: write-only, single insert, side-effecting. Auth: Bearer <token> (Firebase ID token, any plan). UK/EU residency. Response confirms the ticket id + scope so the user can reference it.
    Connector
  • P109 — pull a Hacker News post's score + comments + top replies via the public HN API and write them to the action's metadata.proof. USE WHEN a published Hacker News action is ripe for 24h measurement (checks the publishedUrl on the action, parses the item id, calls the Firebase API). Auto-creates a next-move action based on the outcome (trending → reply + cross-post; engaged → reply; stalled → rewrite angle). Idempotent — second call returns the existing measurement. No API key required; HN is public-read.
    Connector
  • Authenticated — append a free-text evidence note to a specific stage in the caller's active course. Notes record concrete implementation observations, decisions, or artefacts that demonstrate progress through a Blueprint principle (e.g. how a delegation boundary was implemented, what approval flow was chosen and why). Persisted as UserStageEvidence rows scoped to (user_id, course_slug, stage_slug). WHEN TO CALL: AFTER the user has articulated something concrete they have built, observed, or decided — not to capture intent or speculation. Pair with me.coaching_context to close evidence gaps. WHEN NOT TO CALL: to log every conversation turn; to record planning, ideas, or todos; on behalf of another user; without the user's awareness (they should know their progress is being recorded). BEHAVIOR: write-only, single insert. Auth: Bearer <token> (Firebase ID token, any plan). UK/EU residency. Notes are visible only to the owning user and are surfaced on me.learning_path / me.coaching_context. Confirms the stage_slug + course_slug pair in the response so the user can see which stage was credited.
    Connector
  • Lists connected and missing GA4, Google Analytics properties, property IDs, web streams, app streams, measurement IDs, Firebase app IDs, Google Search Console sites, Bing Webmaster sites, and current analysis surface mappings. Use this before reporting when property/site selectors are unknown.
    Connector
  • Permanently delete a conversion action. Not undoable. Use this instead of updateConversionAction with status=REMOVED — Google rejects that with request_error=18. Conversion actions imported from GA4/UA/Floodlight/Firebase/Salesforce/Search Ads 360, Smart Campaign auto-actions, Store Visits, app-store actions, local_services_* / Local Services Ads actions, and manager-inherited actions are read-only via the API — the remove call will be rejected locally before reaching Google. To check before calling: read `conversion_action.type` and `conversion_action.owner_customer` via `runScript` (e.g. `await ads.gaql(ads.queries.conversionActions)`) or write a direct `FROM conversion_action` query. Modify read-only actions in the Google Ads UI or in the source system (GA4, Firebase, Salesforce, Floodlight). Returns changeId.
    Connector
  • Approve a device authorization request. Called by the browser approval page after user signs in and confirms. Verifies Firebase ID token from Authorization header to ensure the caller is a real authenticated user. Extracts uid from the verified token. Dev mode: ALLOW_SELF_APPROVE=true skips Firebase verification (for testing).
    Connector
  • Retrieve a stored request/response pair for replay. Requires authentication: Firebase JWT or dp_ API key. The request must belong to the authenticated user (user_id match). Accepts optional outputFormat (blocks/markdown/html/a2ui) to re-render the stored blocks server-side using the ailang_parse pipeline.
    Connector
  • Authenticated — submit an agency engagement enquiry on behalf of the caller for a founder-led discovery call. Persists an AgencyHandoff row routed to the agency inbox; the user is contacted by the team for a scoped proposal. Engagement scopes: workflow sprint (rapid agentic workflow implementation), proof-of-concept (validate a specific agent design in a bounded timeframe), pilot support (co-design and validate a production-ready pilot), advisory (ongoing architectural guidance across a product team). WHEN TO CALL: the user has identified a paid hands-on expert engagement need beyond self-service learning, and explicitly asks to talk to the team or book a discovery call. ALWAYS confirm with the user before firing — this creates a sales-visible record. WHEN NOT TO CALL: for free training / partnerships discussion (use handoffs.partnership); for support / billing / access (use handoffs.operator); proactively or as a sales push. BEHAVIOR: write-only, single insert, side-effecting. Auth: Bearer <token> (Firebase ID token, any plan). UK/EU residency. Response confirms the ticket id + scope so the user can reference it.
    Connector
  • List recent parse requests for a user. Returns up to 50 entries. Accepts Firebase ID token (dashboard) OR dp_ API key (programmatic). Dashboard sends Authorization: Bearer <firebase_token> with {args: [uid]}. API clients send {args: [apiKey]}. Uses Firestore structured query to filter by user_id server-side and order by timestamp descending. Only reads matching docs (not full scan).
    Connector
  • Authenticated — append a free-text evidence note to a specific stage in the caller's active course. Notes record concrete implementation observations, decisions, or artefacts that demonstrate progress through a Blueprint principle (e.g. how a delegation boundary was implemented, what approval flow was chosen and why). Persisted as UserStageEvidence rows scoped to (user_id, course_slug, stage_slug). WHEN TO CALL: AFTER the user has articulated something concrete they have built, observed, or decided — not to capture intent or speculation. Pair with me.coaching_context to close evidence gaps. WHEN NOT TO CALL: to log every conversation turn; to record planning, ideas, or todos; on behalf of another user; without the user's awareness (they should know their progress is being recorded). BEHAVIOR: write-only, single insert. Auth: Bearer <token> (Firebase ID token, any plan). UK/EU residency. Notes are visible only to the owning user and are surfaced on me.learning_path / me.coaching_context. Confirms the stage_slug + course_slug pair in the response so the user can see which stage was credited.
    Connector
  • Get usage stats for a user's API key. Accepts Firebase JWT or apiKey. Verifies that the requested keyId belongs to the authenticated user.
    Connector