Hybrid · HighBond REST + AC subdomain JSON + QuickSight iframe

Activity Center,
composed by an agent.

103 tools across 20 categories. List managed + custom dashboards (the latter via the new /authoring/dashboards/{id} endpoint discovered in 0.3.1), drill into Issues and Actions, create + delete Boards-site connections, pre-flight snapshot/share permissions before driving the QS iframe, self-diagnose against the reverse-engineered backend, switch tenants at runtime, emit Prometheus metrics. Activity Center is Diligent's dashboards-and-reports product — an embedded Amazon QuickSight experience over Projects + Results data.

103
MCP Tools
58 live · 39 qs-iframe · 6 stubs
8
Backend Endpoints
5 GET + POST + DELETE + /authoring/dashboards/{id}
106
Unit Tests
+ 91 smoke scenarios live, all green
v0.3.1
Release
authoring metadata endpoint + 4 partial-live promotions
$
curl -fsSL https://mcp-activity-center.riskapture.ai/install.sh | bash
Installs to ~/.local/share/diligent-activity-center-mcp Node.js 20+, no sudo Re-run to update
Architecture

Three surfaces, one cookie.

There is no public Activity Center API (verified against developer.diligent.com). This MCP discovered five reverse-engineered endpoints on the per-tenant subdomain backend and confirmed by 404-probing that ~40 operations are QuickSight-iframe-native. The agent reads through one cookie session; mutations split across three layers depending on what's actually exposed.

HighBond REST (Bearer PAT)

For data the dashboards render — Projects, Results, Issues, Actions. Same JSON:API v1.0 + token bucket as the Projects MCP. Used by drill-through and the in-page Issue/Action editor.

AC backend JSON (cookie session)

5 confirmed endpoints on activity-centers-api.<region>.com: /session, /dashboards, /dashboards/{slug}/embed, /authoring/embed_url, /orgs/board_sites. OIDC login via headless Playwright; cookies cached 25 min.

QuickSight iframe (deferred)

Snapshot/schedule/share/visual-export/dashboard CRUD all live inside QS. Verified 404 on every probed Diligent path. Tools in this bucket return FEATURE_LIVES_IN_QUICKSIGHT_IFRAME with workaround pointer; drive via Playwright frameLocator on ac_open_preset.

Two-tier response cache

In-memory + persistent JSON at ~/.cache/diligent-activity-center-mcp/cache.json. Per-key TTL (5 min for AC dashboards, 15 min for templates, 2 min for instances). Survives MCP restarts so each Claude Code turn benefits. ac_clear_cache for targeted purge.

Dry-run by default

Every mutating tool defaults dry_run=true. Bulk mutations additionally require confirm_token matching the affected count. The live writeback smoke scenario round-trips an unpublished issue and reverts in a finally block.

Honest stubs

46 tools that can't be implemented through Diligent's API surface return either FEATURE_LIVES_IN_QUICKSIGHT_IFRAME (40, with workaround) or FEATURE_NOT_AVAILABLE (5, with capture-needed reason) or BRAIN_NOT_SEEDED (1). Smoke contract-tests every stub.

What you can do

Capabilities overview.

Browse dashboards

List all preset (Diligent-shipped) dashboards, custom user-created dashboards, and templates. Open a preset and get the live QuickSight embed URL with full options payload (locale, parameters, timezone).

Drill into Issues & Actions

The Issues & Actions preset has bi-directional sync to HighBond. List, filter, edit issues and actions inline. Updates proxy through the Projects API. Supports dry-run and live writeback with cache-bypassing readback.

Manage Boards-site connections

List, get, fuzzy-match the org's Diligent 360 / Boards sites. Validate snapshot-attach targets before driving the QuickSight iframe.

Authoring entry

Mint a short-lived QuickSight authoring URL for Reports Admins. Drive the iframe via Playwright if you need to programmatically create or edit a dashboard.

Schema & data dictionary

Canonical inventories: dashboard, preset, template, dataset, snapshot, schedule, share, role. Build a per-attribute population/distinct-values dictionary across every live inventory.

Bulk export & governance

Flatten dashboards + templates + board sites + session into a single CSV-ready payload. Pre-flight schedule/share payload validators check documented limits before driving the QS UI.

Worked examples

Recipes.

Junior-dev style guides for the realistic flows you'll actually run. Each recipe walks through one task end-to-end: what you're trying to do, the tool sequence with expected output, common pitfalls, and what's next. Read in order if you're new; skip around if you're not. Source markdown lives in knowledge/recipes/ in the repo.

play_circle

First-time setup

Connect the AC MCP to your agent →
Install via curl, wire up .env, register the server in .mcp.json, run --health. The "I just installed it" walkthrough.

folder_open

Browse

Browse the dashboard catalog →
Managed presets vs. templates vs. custom dashboards. Smart-match by name. Why hard-coded slugs are an anti-pattern.

monitor_heart

Health

Health-check the MCP + tenant →
The 6-tool sweep: liveness, drift, session, metrics, Prometheus export, cache state. Use as your on-call dashboard.

policy

Audit

Audit who can see a sensitive dashboard →
Read share scope + RLS + connected Boards sites for one dashboard, or loop across all customs in a single sweep.

task_alt

Issues

Find overdue SOX issues →
The AC → Projects bridge in action. Smart-match → list issues → client-side overdue filter → group by owner.

photo_camera

Snapshot

Take a snapshot before a board meeting →
Pre-flight canCreateSnapshot + Boards-site validation, then iframe handoff via the resolved embedUrl.

schedule_send

Schedule

Schedule a recurring executive PDF →
Validate the payload against documented limits (5/dashboard cap, 35MB, 2-yr horizon) before the iframe handoff.

admin_panel_settings

Permissions

Onboard a Reports Admin →
The three AC roles, the 64-author cap, and the AC admin-UI handoff for assignment.

troubleshoot

Diagnose

Diagnose a stale dashboard →
Refresh-pipeline triage: cache → dashboard last-refresh → underlying dataset. The "where is the staleness?" decision tree.

dashboard_customize

Templates

Use a template for a new audit cycle →
Start from SOX / Audit / 360 instead of a blank canvas. Pre-flight provisioning + dataset prereqs.

explore

Template tour

Quick template tour →
ERM Moody's, Cyber Risk, S&P Market, NetSuite, Diligent 360 — when to pick which, and the data prereq each one carries.

apartment

Multi-tenant

Operate across multiple tenants →
Register, switch, parallel-run. Per-tenant cookie isolation. The MSP-style flow.

inventory_2

Governance

Export the inventory for governance →
One-shot flat CSV across every dashboard / dataset / Boards site, plus a pre-built data dictionary for auditors.

open_in_new

Iframe handoff

Drive a QS-iframe handoff →
What FEATURE_LIVES_IN_QUICKSIGHT_IFRAME means, why it's by design, and how to consume the returned embedUrl manually or via Playwright.

Index: knowledge/recipes/INDEX.md — full table of contents with the suggested reading order.

Tool Reference

All tools.

97 tools split across 17 categories. live = call the AC backend or HighBond today. qs-iframe = QuickSight-iframe-native (no Diligent endpoint exists). stub = capture pending.

Meta & Control Plane (6)
ToolDescription
ac_health_checkliveRun a connectivity probe against all three auth surfaces this MCP uses: HighBond REST (Bearer PAT for Projects/Results/Issues data), the per-tenant Activity Center JSON backend (cookie session), and Playwright readiness. Returns {version, mcp, highbondApi, activityCenterSubdomain, playwright, sessionMetrics}. Run at the START of any long job — it warms the cookie session (which costs ~17s on a cold start) and surfaces config issues before any tool fails.
ac_get_session_metricsliveReturn per-surface observability metrics for the current MCP process: total calls, success/error counts, retry count, average duration, errors-by-type, plus logger event counts by level (debug/info/warn/error). Useful for "how is this MCP performing right now" snapshots. For Prometheus-format metrics suitable for textfile-collector scraping, use ac_get_metrics_prometheus instead.
ac_reset_session_metricsliveReset all per-surface call/error/retry counters to zero AND set the uptime clock to now. Call this at the start of a discrete job (e.g. "process this batch of 100 issues") so the subsequent metrics describe just that job, not the whole MCP lifetime.
ac_list_capabilitiesliveDiscover every tool registered in this MCP, grouped by category prefix (the second token of the snake_case name — "preset", "snapshot", etc.). Use this when you don't remember a specific tool name; the descriptions are already terse summaries (≤120 chars). Filter by substring with the `category` arg (e.g. category:"snapshot" → just snapshot tools).
ac_warmup_reference_cachelivePre-fetch all reference data the agent might need during a session: HighBond users, AC presets, AC templates, AC board sites. Populates the two-tier cache so subsequent calls return instantly. Run once at the start of a long agent conversation; saves ~5s per affected tool call thereafter. Returns a count per resource + total durationMs.
ac_query_allliveWalk every page of any HighBond JSON:API resource collection. Auto-paginates until exhausted (up to the API's rate-limit ceiling). Use this for full-tenant dumps: "list every issue across all projects" or "every control test in the org". Supported resources: projects, frameworks, objectives, risks, controls, issues, walkthroughs, control_tests, signoffs, project_types, users, groups, roles, entities, entity_categories. Returns flattened rows ({id, type, ...attributes}) — not the JSON:API envelope.
Presets (4)
ToolDescription
ac_list_presetsliveList every Diligent-shipped (preset / "managed") dashboard available in the current tenant. Returns count + sites array of {id, name, alias, type:"MANAGED"}. Use this as the entry point before drilling into a specific preset — slugs vary by tenant subscription, so never hard-code them. Cached for 10 min in the ac:dashboards bucket.
ac_get_presetliveLook up one preset by its slug (alias) and return its full metadata: id, name, alias, type. Returns {error:"preset_not_found", availableSlugs:[...]} if the slug is unknown — useful for fail-fast validation before calling ac_open_preset. Reads from the same /dashboards cache as ac_list_presets, so back-to-back calls cost nothing.
ac_open_presetliveMint a short-lived (~10-minute) signed QuickSight embed URL for a preset, plus the render-options payload (locale, parameters, timezone, l10n strings). The embed URL can be loaded in an iframe to display the live dashboard, or fed into Playwright via src/quicksight-driver.js → openDashboard() to drive the QS UI programmatically. NOT cached — every call mints a fresh URL because the previous one expires.
ac_get_dashboard_last_refreshliveSurface dataset-refresh metadata for a dashboard. Diligent does not expose a dedicated last-refresh endpoint, so this tool fetches the embed-options payload (which carries QS parameters injected at embed time) and filters keys matching /refresh|updated|generated/i. Use this to answer "is this dashboard's data fresh?" before screenshotting or sharing.
Dashboards (8)
ToolDescription
ac_list_dashboardsliveEnumerate every dashboard the current user can see — managed (Diligent-shipped presets), template (cloneable starters), and any custom dashboards present in the response. Returns {count, managedCount, templateCount, dashboards:[{id,name,alias,type,_category}]}. Filter by `type` (MANAGED/CUSTOM/TEMPLATE/ALL) for a specific subset. Cached for 5 min in ac:dashboards bucket.
ac_get_dashboardliveLook up one dashboard by slug across ALL categories (managed + template + custom). Returns the dashboard row or {error:"dashboard_not_found", availableSlugs:[...]}. Use this when you have a slug from another tool but don't know which category it lives in.
ac_get_dashboard_authoring_metadataliveLIVE. Reads /authoring/dashboards/{id} to return rich per-dashboard metadata: {id, name, createdBy, analysisId, status, canEdit, share, type, canConnectToBoards, connectedBoardSitesCount, dataAccessStatus, canCreateSnapshot}. This is the LIVE pre-flight for any snapshot/share/boards-connect operation. Note: only CUSTOM dashboards have authoring metadata; passing a managed slug returns 400 BadRequest.
ac_create_dashboardqs-iframeCreate a custom dashboard from scratch or by cloning a template. Inputs: {name, base_template_id?, description?}. NOT YET WIRED — drive QS authoring iframe.
ac_update_dashboardqs-iframeRename a custom dashboard or edit its layout/visuals/datasets. Inputs: {slug, attributes:{name?, description?}}. NOT YET WIRED — QS authoring iframe.
ac_delete_dashboardqs-iframePermanently delete a custom dashboard. Inputs: {slug, confirm_token (must equal slug)}. NOT YET WIRED — destructive operation in QS authoring iframe.
ac_clone_dashboard_from_templateqs-iframeClone a Diligent template (Audit Dashboard, SOX Program Mgmt, etc.) into a new editable custom dashboard. Inputs: {template_slug, new_dashboard_name}. Lets a Reports Admin start from a curated layout instead of a blank canvas. NOT YET WIRED.
ac_publish_analysis_to_dashboardqs-iframePromote a saved QS Analysis (work-in-progress) into a published dashboard so other users can see it. NOT YET WIRED — QS publish flow.
Datasets (7)
ToolDescription
ac_list_datasetsliveList the 14 built-in Projects datasets that AC ships with (Actions, Certifications, Controls, Control Performances, Control Tests, Fieldwork, Issues, Planning Files, Projects, Requests, Reviews, Risks, Timesheets, Todos). Returns {builtIn:[{id,name,source,refreshCadence}], builtInCount, results:{count:null, note}}. Live Results-publication discovery is not exposed by the AC backend.
ac_get_datasetliveLook up one of the 14 built-in datasets by id. Returns the row {id, name, source, refreshCadence} or {error:"dataset_not_found", available:[...]}. Static catalogue — no network call.
ac_replace_datasetqs-iframeSwap the dataset bound to a visual for a different one (e.g. switch a chart from Actions to Issues). Inputs: {dashboard_slug, visual_id, new_dataset_id}. Triggers field-map prompt. NOT YET WIRED.
ac_field_map_datasetqs-iframeProvide explicit column mappings when ac_replace_dataset shows a "fields don't match" wizard. Inputs: {dashboard_slug, visual_id, mappings:{old_field: new_field}}. NOT YET WIRED.
ac_get_dataset_refresh_statusqs-iframeRead the last successful refresh timestamp + next scheduled refresh for a dataset. Used to answer "is this dashboard's data fresh?". NOT YET WIRED — QS authoring view has the answer.
ac_trigger_dataset_refreshqs-iframeForce-refresh a dataset NOW instead of waiting for the next 45-min interval. Useful before a board meeting demo. NOT YET WIRED.
ac_list_results_table_publicationsqs-iframeList user-published Results-app tables that have been promoted into AC as ad-hoc datasets. NOT YET WIRED — the publication-discovery surface is unknown.
Templates (7)
ToolDescription
ac_list_templatesliveList dashboard templates available in the current tenant + the documented-but-not-provisioned ones. Returns {provisionedCount, notProvisionedCount, provisioned:[...], notProvisioned:[...]}. Templates are Diligent-shipped curated layouts that can be cloned into editable custom dashboards. Provisioning depends on subscription (Moody's/S&P need data feeds; NetSuite needs OAuth integration; etc.).
ac_get_template_moodysliveERM Reporting (Moody's): 3 tabs covering Internal Risk Management + Risk Insights + Country Risk Insights. Requires the Moody's data feed (provisioned per-tenant; not all orgs have it). See knowledge/05-erm-moodys-template.md.
ac_get_template_cyber_riskliveCyber Risk Report: 6 tabs — Board–Executive Summary, Compliance/Audit, Incident Mgmt, Vulnerability Mgmt, 3rd-Party, Threat Landscape. See knowledge/06-cyber-risk-template.md.
ac_get_template_market_insightsliveMarket Insights (S&P): 4 tabs — Market Update, Analyst View, Peer Comparison, Sentiment. Powered by S&P Capital IQ feed (per-tenant subscription). See knowledge/07-market-insights-template.md.
ac_get_template_financial_netsuiteliveFinancial Reporting (NetSuite): GL + AP/AR + budget visuals pulled from NetSuite ERP via OAuth integration. Setup must be done by an admin first. See knowledge/08-financial-netsuite-template.md.
ac_get_template_soxliveSOX Program Management: 6 tabs — Program Oversight, Risks, Walkthroughs, Control Testing, Issues, Certifications. The most-used compliance template; built directly on the 14 Projects datasets. See knowledge/04-sox-program-management.md.
ac_get_template_diligent_360liveDiligent 360 / Boards integration template: a starter dashboard layout designed to be snapshotted and connected to a Boards site for executive consumption. See knowledge/09-diligent-360-boards.md.
Board sites (6)
ToolDescription
ac_list_board_sitesliveList all Diligent 360 / Boards sites configured for this org. Each entry has boardSiteId, boardSiteName, boardSiteDisplayName. Use this to discover what sites a snapshot can be connected to. Backed by GET /orgs/board_sites on the AC backend.
ac_get_board_siteliveGet one Boards site by its boardSiteId. Returns the same fields as ac_list_board_sites filtered to one row. Useful before calling ac_connect_snapshot_to_boards_site to validate the target.
ac_smart_match_board_siteliveFuzzy-match a free-text name against the configured Boards sites (matches against both boardSiteDisplayName and boardSiteName).
ac_get_authoring_embed_urlliveGet a QuickSight authoring embed URL — a short-lived signed URL that opens the dashboard authoring UI inside an iframe. The actual editing (create/edit/save dashboards, take snapshots, share, schedule reports) happens INSIDE QuickSight; AC does not expose those as separate Diligent endpoints. This tool returns the entry URL so an agent could drive QuickSight via Playwright if needed. Backed by GET /authoring/embed_url.
ac_create_board_siteliveCreate a new Diligent 360 / Boards-site connection. POSTs to /orgs/board_sites/{boardSiteName} with body {boardSiteDisplayName}. The boardSiteName goes into the URL path and is IMMUTABLE after creation (per the UI helper text); use lowercase alphanumeric. Defaults dry_run=true; set false to actually create. Returns the created site object on success or {error, ...} on failure.
ac_delete_board_siteliveDelete a Diligent 360 / Boards-site connection. DELETEs /orgs/board_sites/{boardSiteName}. Destructive — requires confirm_token to match the boardSiteName exactly. Defaults dry_run=true. Note: snapshots previously connected to the site are NOT auto-detached; check ac_list_snapshots before deleting.
Issues & Actions Bridge (5)
ToolDescription
ac_list_issues_in_dashboardliveList the issues that the Issues & Actions preset surfaces. Pulls a page from the HighBond Issues API (the same data the dashboard renders) and applies client-side filters: status (open/closed/all), severity (High/Medium/Low/etc.), owner_id, project_id. Returns {count, meta, issues:[{id, ...attrs}]}. Use this BEFORE drilling into a specific issue with ac_update_issue_inline.
ac_update_issue_inlinelivePatch one issue's attributes through the HighBond Projects API — exactly what the AC Issues & Actions dashboard does when a user edits inline. Common writable fields: title, description, severity, status, due_at, owner relationships, custom_attributes. Defaults dry_run=true and returns {dry_run, would, beforeState, proposedAttributes}. Set dry_run:false to actually mutate. Note: HighBond rejects writes on signed-off issues (HTTP 422) — handle that error path.
ac_list_actions_in_dashboardliveList actions surfaced in the Issues & Actions preset. Actions are nested under issues in HighBond (no top-level /actions resource), so this tool walks a sample of issues and aggregates their actions. Filter: status, owner_id, project_id. Best for "what does the Actions tab look like right now?" — for production-grade walks, iterate ac_list_issues_in_dashboard then fetch nested actions yourself.
ac_update_action_inlinelivePatch one action's attributes via HighBond — same pattern as ac_update_issue_inline. Common writable fields: description, status, owner, due_at. Defaults dry_run=true; returns {dry_run, would, beforeState, proposedAttributes}. Actions are nested under issues server-side; updates use the global PATCH /actions/{id} endpoint exposed by HighBond.
ac_get_issues_actions_dashboardliveComposite snapshot of the Issues & Actions preset state: returns the preset row + open/closed issue counts + severity breakdown + a note about the actions count. ONE tool call instead of 3-4. Use this for "what does the Issues & Actions dashboard look like right now?" answers in conversation.
Snapshots (5)
ToolDescription
ac_list_snapshotslivePARTIAL LIVE. Returns dashboard snapshot capability + count: {dashboard_slug, canCreateSnapshot, connectedBoardSitesCount, status, share}. Per-snapshot listing requires the QS iframe (no JSON endpoint exists). Use this to know whether the user is even permitted to take a snapshot before opening the QS UI.
ac_take_snapshotqs-iframePARTIAL LIVE. Validates that the current user can take a snapshot of this dashboard before sending them to drive the QS iframe. Returns either {error: "snapshot_not_permitted", reason} or {error: "FEATURE_LIVES_IN_QUICKSIGHT_IFRAME", embedUrl} with the QS authoring URL pre-resolved.
ac_get_snapshotqs-iframeSTUB. There is no per-snapshot JSON endpoint on the AC backend (verified 2026-04-28). To read a single snapshot's metadata, drive the QS iframe — embed URL via ac_get_authoring_embed_url. The closest LIVE alternative is ac_list_snapshots which returns connectedBoardSitesCount.
ac_delete_snapshotqs-iframeSTUB. Destructive operation lives in the QS authoring iframe. Required: {snapshot_id, confirm_token}. Returns embedUrl so the caller can drive the delete dialog.
ac_connect_snapshot_to_boards_siteqs-iframePARTIAL LIVE. Validates that (a) the target boardSiteId exists in /orgs/board_sites, AND (b) the dashboard has canConnectToBoards=true. If both pass, returns the QS embed URL for the user to complete the connect step in the iframe.
Scheduled Reports (8)
ToolDescription
ac_list_scheduled_reportsqs-iframeSTUB. AC has no /schedules JSON endpoint (verified). Returns embedUrl so caller can read the list inside the QS iframe.
ac_get_scheduled_reportqs-iframeSTUB. No JSON read — drive QS iframe via embedUrl. Useful workaround: ac_validate_schedule_payload to confirm what a payload SHOULD look like, then read the live one via the iframe.
ac_create_scheduled_reportqs-iframeSTUB. Use ac_validate_schedule_payload first (LIVE — checks cadence/format/recipients shape + 5/dashboard cap). Then drive the QS iframe via embedUrl. Inputs: {dashboard_slug, sheet_id, cadence, format (PDF/CSV), recipients[], subject?, body?, start_date?, end_date?, dry_run?}.
ac_update_scheduled_reportqs-iframeSTUB. Drive QS iframe via embedUrl. Inputs: {schedule_id, attributes:{...}, dry_run?}.
ac_pause_scheduled_reportqs-iframeSTUB. Pause via QS iframe — embedUrl returned for caller to drive.
ac_resume_scheduled_reportqs-iframeSTUB. Resume via QS iframe — embedUrl returned for caller.
ac_delete_scheduled_reportqs-iframeSTUB. Destructive — requires {schedule_id, confirm_token}. Drive QS iframe via embedUrl.
ac_get_schedule_failuresqs-iframeSTUB. AC backend exposes no failure log — info lives in the QS iframe per-schedule. Returns embedUrl.
Sharing (5)
ToolDescription
ac_list_shareslivePARTIAL LIVE. Reads current sharing scope of a dashboard from /authoring/dashboards/{id} and returns {dashboard_slug, share, status}. share is one of "org" / "users" / null. Per-user share enumeration requires the QS iframe.
ac_share_dashboard_with_usersqs-iframeSTUB. Pre-flight via ac_validate_share_payload then drive the QS iframe — returns the embedUrl. Inputs: {dashboard_slug, user_ids[], accessLevel ("view-only"|"full-access"), dry_run?}.
ac_share_dashboard_with_orgqs-iframePARTIAL LIVE. Pre-checks current scope via /authoring/dashboards/{id}: if share=="org" already, no-ops with a "no_change_needed" notice; otherwise returns the QS embedUrl for the user to flip the scope in-iframe.
ac_revoke_shareqs-iframeSTUB. Drive the QS iframe (returned embedUrl) to find the per-user share and revoke it. AC backend has no /shares endpoint to call.
ac_set_share_access_levelqs-iframeSTUB. Drive the QS iframe (returned embedUrl) to flip a user's share level. Inputs: {dashboard_slug, user_id, accessLevel}.
Visuals + Sheets + Exports (7)
ToolDescription
ac_inspect_dashboard_iframeliveOpen the QuickSight dashboard iframe for one preset/dashboard via Playwright and dump every interactive element inside (button text, aria-label, role, data-test-id). Use this to discover selectors before wiring a real tool. Read-only; the iframe stays in viewer mode. Slug examples: "sox", "issues", "my_activities_internal".
ac_list_sheetsqs-iframeList sheets in a dashboard. Selector capture pending — see ac_inspect_dashboard_iframe.
ac_list_visualsqs-iframeList visuals on a sheet. Selector capture pending.
ac_get_visual_stateqs-iframeRead the rendered values from a visual. Selector capture pending.
ac_export_visual_csvqs-iframeExport one visual as CSV via the QS download menu. Selector capture pending.
ac_export_table_excelqs-iframeExport a table visual as Excel. Selector capture pending.
ac_get_drillthroughqs-iframeRead drillthrough metadata for a clicked visual cell. Selector capture pending.
Diagnostics (1)
ToolDescription
ac_diagnoseliveHits every confirmed AC backend endpoint and asserts the documented response shape. Returns a per-endpoint drift report so operators can spot a breaking Diligent release before users hit it. Also reports MCP version, HighBond PAT validity, and cookie session staleness. Read-only — safe to run anytime.
Admin & Permissions (9)
ToolDescription
ac_get_sessionliveRead the current user's AC session: orgId, orgName, uid, locale, subscriptionState ("internal"|"professional"|"oversight"), hasAuthoringPermissions (boolean — whether this user can edit dashboards), timezone, features (feature-flag map). Cached for 15 min. Use as the canonical "who/where am I" answer when an agent first connects.
ac_get_subscription_tierliveReturn just the subscription gating bits from /session: subscriptionState, hasAuthoringPermissions, features map, orgName. Use to answer "can this org create dashboards?" or "is the scheduled-reports feature enabled?" without pulling the whole session payload.
ac_get_region_infoliveReturn all region/tenant routing info — configured AC_BASE_URL (HighBond REST host), AC_TENANT_URL (per-tenant SPA), the inferred AC backend URL, configured + live region/locale/timezone. Use when debugging "why is this MCP hitting the wrong tenant?" or planning multi-tenant work.
ac_get_author_countliveReturn the documented hard cap on combined Reports Admin + Writer roles per org (currently 64) plus a placeholder for the live count. The AC backend doesn't expose the live count directly — a future Playwright-driven scrape of the Platform Admin UI would populate currentCount. Use to answer "are we close to the author limit?" planning questions.
ac_list_app_rolesliveReturn the three documented Activity Center app roles — Reports Admin (create dashboards, share, schedule, snapshot), Writer (edit existing, share-own), Reader (view-only). Static catalogue from knowledge/13-app-permissions.md; live per-tenant role list requires admin-UI scrape.
ac_get_app_roleliveLook up one role's capabilities matrix by id ("reports_admin" | "writer" | "reader"). Returns {id, name, capabilities:[...]} or {error:"role_not_found", available:[...]}.
ac_list_users_with_rolestubList every user in the org who holds a given AC role. Inputs: {role: "reports_admin"|"writer"|"reader"}. NOT YET WIRED — Diligent admin UI scrape is the route.
ac_assign_role_to_userstubGrant an AC role to one user. Inputs: {user_id, role, dry_run?, confirm_token?}. Counts toward the 64-author cap if role is reports_admin or writer. NOT YET WIRED.
ac_revoke_role_from_userstubRemove an AC role from a user (drops them to "no AC access" or downgrades). NOT YET WIRED.
Bulk Operations (6)
ToolDescription
ac_export_inventory_flatliveDump every dashboard / template / board-site row + the org session metadata into a SINGLE flat list — suitable for governance spreadsheets and audit evidence. Pulls from /dashboards + /orgs/board_sites + /session in parallel; cached for 5 min. Each row has {category, id/name/displayName/...} fields. Read-only.
ac_bulk_export_visualsqs-iframeExport N visuals as CSV in one operation, returning a list of {visual_id, status, url_or_data} rows. Inputs: {dashboard_slug, visual_ids[], format?, dry_run?, confirm_token?}. NOT YET WIRED — depends on per-visual export, which is QS-iframe.
ac_bulk_create_scheduled_reportsqs-iframeCreate N scheduled reports in one go. Inputs: {schedules:[{...}], dry_run?, confirm_token (must equal count)}. Each row pre-flighted with ac_validate_schedule_payload. NOT YET WIRED.
ac_bulk_share_dashboardsqs-iframeShare N dashboards with a list of users at one access level — for onboarding a new team. Inputs: {dashboard_slugs[], user_ids[], accessLevel, dry_run?, confirm_token?}. NOT YET WIRED.
ac_bulk_take_snapshotsqs-iframeSnapshot N dashboards in one operation — useful before a known data refresh or for end-of-quarter board prep. Inputs: {dashboard_slugs[], name_prefix, dry_run?, confirm_token?}. NOT YET WIRED.
ac_bulk_pause_schedulesqs-iframePause N schedules at once — useful when migrating between environments or during a maintenance window. NOT YET WIRED.
Schema & Data Dictionary (5)
ToolDescription
ac_list_canonical_inventoriesliveReturn the catalogue of inventory types this MCP recognises — dashboard, preset, template, dataset, snapshot, schedule, share, role, session — each with its list endpoint, writability, and current support level ("live" or "playwright-fallback"). Use to plan a data extraction or verify what's queryable today.
ac_list_inventory_recordsstubList every record of one inventory type tenant-wide — like ac_query_all but for AC inventories instead of HighBond resources. Live for: dashboard, preset, template, session. Returns {count, records:[...]} or {error:"FEATURE_NOT_AVAILABLE"} for non-live inventories.
ac_get_inventory_schemastubIntrospect an inventory by sampling its records and reporting per-attribute observed types, population rate (% of rows where the field is non-null), and distinct values for enums (capped at 12). Useful for "what fields can I count on for governance reports?". Returns {inventory, recordCount, attributes:[{key, populationRate, observedTypes, enumCandidates}]}.
ac_build_data_dictionaryliveComposite tool — runs ac_get_inventory_schema across every live inventory and returns a single {generatedAt, inventories:{...}} blob. Suitable for feeding into a downstream data-dictionary doc, a Brain harmonisation engine, or an Excel governance pack.
ac_compare_inventory_to_brainstubDiff an observed inventory schema against the Riskapture-Knowledge GRC Brain canonical (read-only — never mutates the Brain). Reports attributes that are aligned vs only-in-brain vs only-in-ac vs type-conflicts. Currently returns {error:"BRAIN_NOT_SEEDED"} until the Brain has an Activity Center canonical seed (PR pending in Riskapture-Knowledge).
Smart-match & Validators (6)
ToolDescription
ac_smart_match_dashboardliveResolve a free-text dashboard name to its canonical slug via fuzzy matching (Levenshtein + Jaccard + alias awareness). Use when an agent says "open the SOX dashboard" — this returns the right slug. Returns {query, matches:[{score, name, slug, type}]} sorted by score desc. Cap results with topN (default 3).
ac_smart_match_templateliveResolve a free-text name to one of the dashboard templates ("Cyber Risk", "SOX Program", etc.). Returns top-N matches with confidence scores. Use as a discovery aid before ac_clone_dashboard_from_template.
ac_smart_match_userliveResolve a free-text name or email to a HighBond user id. Used before ac_share_dashboard_with_users or ac_assign_role_to_user. Searches against full_name, given_name, and email. Returns {query, matches:[{score, id, name, email}]}.
ac_smart_match_datasetliveResolve a free-text dataset name to one of the 14 built-in Projects datasets (Actions / Issues / Risks / Controls / etc.). Use before ac_replace_dataset or ac_field_map_dataset. Live Results-publication discovery is not yet supported.
ac_validate_schedule_payloadlivePre-flight check a scheduled-report payload against the documented limits BEFORE sending it through the QS authoring iframe. Validates required fields (dashboardSlug, sheetId, cadence, format, recipients), allowed enum values, end-date horizon (2 yr default, 3 yr Yearly), CSV table cap (5), and warns on external email recipients. Returns {ok, errors:[{field,message}], warnings:[{field,message}]}. Knowledge: knowledge/11-scheduled-reports.md.
ac_validate_share_payloadlivePre-flight check a dashboard-share payload BEFORE driving the QS iframe. Validates dashboardSlug + accessLevel ("view-only"|"full-access") + that userIds[] is non-empty when scope != "org". Returns {ok, errors[], warnings[]}. Knowledge: knowledge/12-sharing.md.
Filters (2)
ToolDescription
ac_apply_filterqs-iframeApply a controls-bar or visual-level filter to a rendered dashboard (e.g. "status = Open", "owner = [email protected]"). Inputs: {dashboard_slug, filter_target ("controls-bar"|visual_id), field, operator, value}. The dashboard re-renders with the filter active for the rest of the session. NOT YET WIRED.
ac_clear_filterqs-iframeRemove an active filter from a rendered dashboard. Inputs: {dashboard_slug, filter_target, field?}. Omitting `field` clears all filters in that target. NOT YET WIRED.
Multi-tenant runtime (3)
ToolDescription
ac_list_tenantsliveList every tenant (Activity Center org) registered with this MCP process. Returns the active one + all others. The boot tenant comes from AC_UI_ORG; additional tenants are added via ac_register_tenant.
ac_register_tenantliveRegister an additional Activity Center tenant for this MCP process. After registration, call ac_switch_tenant({org}) to make it the active one. Cookie cache lives at ~/.cache/diligent-activity-center-mcp/session-<org>.json — isolated per tenant.
ac_switch_tenantliveMake a previously-registered tenant the active one. Subsequent ac_* tool calls in this conversation will hit that tenant. Call ac_list_tenants to see what is registered.
Metrics export (1)
ToolDescription
ac_get_metrics_prometheusliveEmit per-surface call counters, error counters, retry counts, and avg latencies in Prometheus exposition format. Suitable for the node_exporter textfile collector or a scheduled scrape. Returns a single string with HELP/TYPE/sample lines (one block per metric, labeled by surface=highbond|ac).
Cache observability (2)
ToolDescription
ac_cache_statusliveRead the two-tier response cache state without modifying it. Returns total keys, bytes used, hit/miss/write counters since process start, and a per-prefix breakdown (ac:dashboards, list:projects, etc.) showing count + bytes + max remaining TTL. Use to diagnose "is this MCP serving stale data?" or "why is this fast/slow?".
ac_clear_cacheliveForce a cache purge to make the next read fetch fresh data. Scopes: "all" (everything), "reference" (project_types, users, groups, roles, AC roles, AC templates — long-TTL reference lookups), "instances" (mutating data: projects, objectives, risks, controls, issues), "ac" (every Activity Center backend response), "ac-instances" (only mutable AC: dashboards, snapshots, schedules, shares, datasets), "ui-schema" (Playwright form-driven schema reads), "brain" (Riskapture Brain canonical reads — rare). Returns {scope, dropped, at} so callers can confirm the purge fired.
Configuration

Environment variables.

VariableRequiredDescription
AC_BASE_URLYesHighBond API base URL (e.g. https://apis-us.diligentoneplatform.com)
AC_API_TOKENYesBearer PAT from Diligent One > Profile > Application tokens
AC_ORG_IDYesOrganisation ID (numeric)
AC_TENANT_URLYesPer-tenant AC subdomain (e.g. https://piedpiper.activity-centers.diligentoneplatform.com)
AC_UI_EMAILYesOIDC login email — needed for the AC backend cookie session
AC_UI_PASSWORDYesOIDC password
AC_UI_ORGYesOrg slug (e.g. piedpiper) — must match the slug in AC_TENANT_URL
AC_UI_REGIONNoRegion code: us/ca/eu/ap/au/af/jp (default us)
AC_LOG_FILENoPath for JSONL request log
AC_CACHE_ENABLEDNoSet to false to disable the response cache
AC_CACHE_DIRNoCache location (default ~/.cache/diligent-activity-center-mcp)
AC_PLAYWRIGHT_HEADLESSNoSet to false to debug the OIDC flow with a visible browser

Regional base URLs: US, Canada, Europe, Asia, Australia, Africa, Japan, South America. The PAT can be reused from sibling MCPs (Issues, Projects, ERM) — same token, different application surface.

Constraints

Hard rules.

No Public AC API
The Diligent Developer Portal does not document an Activity Center API (verified 2026-04-27). The 5 backend endpoints used here are reverse-engineered and could change with any Diligent release.
Dry-Run Default
Every mutating tool defaults dry_run=true. Bulk mutations additionally require confirm_token matching the affected count.
No DELETE on HighBond
DELETE is hard-blocked in the HighBond client (soft-delete is destructive and irreversible via API).
QuickSight-Iframe Boundary
Snapshot, schedule, share, dashboard CRUD, visual export, and filters live entirely inside the QuickSight iframe. Tools in this bucket return FEATURE_LIVES_IN_QUICKSIGHT_IFRAME with a workaround pointer.
Browser-Style Headers
The AC backend rejects requests without Origin, Referer, and Sec-Fetch-* headers. The client sends them automatically; if you call directly via curl, mirror them.
Author Limit
Hard cap of 64 (Reports Admin + Writer combined) per org. ac_get_author_count surfaces this.
Schedule Limits
5 schedules per dashboard, 1 sheet per schedule, 5 tables max for CSV, 35 MB attachment cap, 2-yr horizon (3-yr yearly). ac_validate_schedule_payload pre-flight-checks all of these.
Quick start

Getting started.

1. Install via the one-liner above, or clone from GitHub

2. Set your environment variables — AC_BASE_URL, AC_API_TOKEN, AC_ORG_ID, AC_TENANT_URL, AC_UI_EMAIL, AC_UI_PASSWORD, AC_UI_ORG

3. Restart Claude Code: /mcp reset diligent-activity-center

4. Start with ac_health_check to verify both surfaces (HighBond + AC backend) are reachable

5. Run ac_list_capabilities to discover all 96 tools and their categories

6. ac_warmup_reference_cache before bulk operations

7. ac_open_preset({slug: "my_activities_internal"}) to get a QuickSight embed URL for the default landing dashboard