Skip to content

Org-managed Dashboards: define, assign, and render granted MCP App dashboards - #4056

Merged
reachjalil merged 8 commits into
devfrom
feature/org-managed-dashboards
Aug 25, 2026
Merged

reachjalil merged 8 commits into
devfrom
feature/org-managed-dashboards

Conversation

@reachjalil

@reachjalil reachjalil commented Aug 25, 2026 •

Copy link
Copy Markdown
Member

Follow-up to #4045: the org-managed side of the MCP Apps dashboard. Organizations define Dashboards (ordered lists of MCP App elements), assign them to members and teams through the same grants mechanism connector assignment uses, and signed-in desktop users see the granted dashboards rendered above their own local tiles.

Den data model + API (den-db, den-api)

  • New dashboard table (org-owned: name, ordered elements_json, creator/created/updated audit fields, soft delete) and dashboard_access_grant table — an exact structural mirror of connector_instance_access_grant (one of orgMembershipId | teamId | orgWide=true per row, role, removedAt soft revoke, the same unique indexes). Migration 0078 generated with db:generate (renumbered after dev's 0077_drop_memory_bank); dsb/dsg typeid prefixes appended.
  • Element shape is the same reference shape desktop entries use: serverName, optional connectionId, toolName, projectedToolName, resourceUri (must be ui://), title, optional launchArguments, optional requiresApproval. Per-user consent is never stored in Den.
  • New routes in routes/org/dashboards.ts (all admin-gated with orgRoleRoute(["admin"]) except the member listing):
    • GET/POST /v1/dashboards, GET/PATCH/DELETE /v1/dashboards/:dashboardId
    • GET/POST /v1/dashboards/:dashboardId/access, DELETE .../access/:grantId — the same exactly-one-subject write schema, in-org target validation, and revoke/reactivate lifecycle the plugin-arch grants use
    • GET /v1/me/dashboards — dashboards granted to the caller directly, via team, or org-wide (orgMemberRoute() + member-teams resolution), consumed by the desktop
  • New GET /v1/mcp-connections/:connectionId/mcp-apps (in mcp-connections.ts, beside the /tools inspector): enumerates a connection's app-visible MCP App launch tools in the exact element reference shape, mirroring the desktop app-host rules (gateway tools excluded, tool policy respected, ui:// resource binding required, the single approval rule reported). Admin-only; the remoteMcpAppsEnabled rollout gate was dropped after dev retired that flag in feat(den): enable Code Mode and MCP Apps by default, retiring their rollout flags #4053 (MCP Apps are enabled by default now). Nothing is built on the internal capability catalog.

Den web Manage section (den-web)

  • "Dashboards" item in the second (Manage) sidebar section, admin-only, after Sources; page-title branch and sidebar IA test updated.
  • /dashboard/dashboards: list + create dialog. /dashboard/dashboards/[dashboardId]: rename, add apps (per-connector picker backed by the new mcp-apps endpoint, with JSON launch input for apps that require it), reorder/remove elements, delete.
  • Assign control reuses the established access pattern from plugin/marketplace assignment: org-wide toggle plus person and team pickers, grant/revoke against the new access endpoints.

Desktop consumption (apps/app)

  • createDenClient().listGrantedDashboards(orgId) → GET /v1/me/dashboards with strict payload parsing (DenGrantedDashboard/DenDashboardElement wire types).
  • When signed in, the dashboard page fetches granted dashboards for the active org and renders each one above the user's local tiles, labeled with the dashboard name and "Managed by your organization". Granted tiles have no Remove control; local add/remove is unchanged.
  • Consent parity with dev's rules, per user: granted tiles start manual (autoLaunch unlocked only after this user's first successful manual run), requiresApproval elements stay run-on-request, and callMcpAppTool's server-side approval enforcement still backstops everything — a grant never bypasses launch approval. Consent lives in a local dashboardGrantedConsent store scoped to Den user + org, mirroring the local entry scoping.
  • Only wiring changes to the merged desktop feature: onRemove became optional on McpAppTile/DashboardTileShell, and dashboard-page.tsx gained the granted sections.

Proof

  • ee/apps/den-api: bun test test/dashboards.test.ts — 6 pass (CRUD + element validation, admin-only management, exactly-one-subject + cross-org target rejection, grant list/revoke/reactivate lifecycle, and /v1/me/dashboards positive and negative visibility across direct/team/org-wide/revoked/deleted). bun test test/mcp-connection-apps.test.ts — 4 pass (desktop naming convention parity, app-audience visibility rule, required-input detection).
  • Typecheck green in every touched package: tsc --noEmit for ee/apps/den-api, den-web (pnpm typecheck), @openwork/app, openwork-server; @openwork-ee/den-db + @openwork-ee/utils rebuilt; db:generate reruns clean ("No schema changes").
  • Desktop checks re-run: apps/app + apps/server typecheck green; bun --conditions=development test src/mcp-app-host.test.ts — 23 pass.
  • den-web: full pnpm test suite (including the updated sidebar IA test) — 138 pass.
  • Route policy scans: the new routes all carry explicit access markers and pass the guard scan. test/route-access-policy.test.ts / test/route-guard-policy.test.ts flag only pre-existing registrations in untouched files (codemode-scripts.ts, codemode-runs.ts, automations/index.ts, etc.) that flag identically on dev.

Manual test steps (Manage flow)

  1. As an org admin on Den web (org with the MCP Apps rollout and at least one connected external MCP whose tools advertise ui:// app bindings): open Manage → Dashboards, create a dashboard.
  2. In the dashboard detail, Add app → pick the connector → add an app (enter JSON launch input if the app requires it). Reorder/remove to taste.
  3. Under "Who sees this dashboard", assign a person or team (or toggle Everyone in the organization).
  4. As that assigned member, sign in to OpenWork Desktop, enable the openwork.mcpAppsDashboard flag (Settings → Advanced → Developer), and open Dashboard: the granted dashboard appears above the local tiles, labeled with its name, without Remove controls.
  5. Consent: each granted tile shows the Run card first; a read-only app auto-launches only after that user runs it once, and a data-modifying app asks for approval and keeps running only on request. Revoking the grant (or deleting the dashboard) removes the section on the next fetch.

Out of scope, per plan: manifest export/import, layout/drag-drop, per-element grant overrides, pinned-panel changes, end-user editing of granted dashboards.

@vercel

vercel Bot commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openwork-app Ready Ready Preview Aug 25, 2026 4:48pm
openwork-den Ready Ready Preview Aug 25, 2026 4:48pm
openwork-den-worker-proxy Ready Ready Preview Aug 25, 2026 4:48pm
openwork-landing Ready Ready Preview, v0 Aug 25, 2026 4:48pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
openwork-diagnostics Skipped Skipped Aug 25, 2026 4:48pm

Comment thread apps/app/src/react-app/domains/dashboard/dashboard-page.tsx Outdated
Comment thread apps/app/src/react-app/domains/dashboard/dashboard-page.tsx Outdated
Comment thread ee/apps/den-api/src/routes/org/dashboards.ts
Comment thread apps/app/src/react-app/domains/dashboard/granted-dashboard-store.ts Outdated
Comment thread ee/apps/den-web/app/(den)/dashboard/_components/org-dashboards-data.tsx Outdated
Comment thread ee/apps/den-api/src/routes/org/core.ts
Comment thread ee/apps/den-api/src/routes/org/core.ts
diff-warden[bot]
diff-warden Bot previously approved these changes Aug 25, 2026

@diff-warden diff-warden Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warden security clearance: clear. No blocking findings (security or desktop↔den sync) in this diff (d113c5d86c990e1271f158332e5f0c0825691dce). 1 advisory desktop↔den sync note(s) were posted as review comments; they do not affect clearance. Automated clearance satisfies the required-review gate only — a human still reviews and merges. Analysis run

… mcp-apps endpoint

dev retired DEN_REMOTE_MCP_APPS_ENABLED and the per-org remoteMcpApps
capability (#4053), so the new /v1/mcp-connections/:id/mcp-apps route is
now available whenever the caller is an org admin, matching the rest of
the MCP Apps surface.
…nvokes

The consent id for a granted dashboard element now fingerprints every
material launch field (connection, tool, projected tool, resource URI,
launch arguments), so editing any of them discards the member's stored
approval and auto-launch and the changed app must be run manually again.
Regenerated with db:generate against dev's 0077 snapshot; the SQL is
byte-identical to the previous 0077_warm_carlie_cooper migration and a
rerun reports no schema changes.
Replace the 32-bit fingerprint with the URI-encoded canonical encoding of
the element's launch-material fields, so no crafted element edit can
collide with a previously approved identity, and fold requiresApproval in
so an approval-policy change also resets stored consent.

@diff-warden diff-warden Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warden security clearance: clear. No blocking findings (security or desktop↔den sync) in this diff (9cb7381e586fae973dbf98956b3c7fc86a603067). 1 advisory desktop↔den sync note(s) were posted as review comments; they do not affect clearance. Automated clearance satisfies the required-review gate only — a human still reviews and merges. Analysis run

@reachjalil
reachjalil merged commit 3c0b038 into dev Aug 25, 2026
31 checks passed
@reachjalil
reachjalil deleted the feature/org-managed-dashboards branch August 25, 2026 16:56

This branch was successfully deployed

4 active and 1 inactive deployments
Preview – openwork-den-worker-proxy — 9cb7381e Deployed Aug 25, 2026 by vercel[bot]
Preview – openwork-landing — 9cb7381e Deployed Aug 25, 2026 by vercel[bot]
Preview – openwork-den — 9cb7381e Deployed Aug 25, 2026 by vercel[bot]
Preview – openwork-app — 9cb7381e Deployed Aug 25, 2026 by vercel[bot]
Preview – openwork-diagnostics — 9cb7381e Deployed Aug 25, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant