Skip to main content
Glama

Workplace MCP Apps

Eight thoughtful workplace widgets, one standard MCP server. A small, open-source example of how to build a company's own MCP Apps without coupling its UI or data adapter to a particular host.

Live demo · MCP endpoint · MIT licensed

All people, meetings, incidents, balances, and progress are synthetic. No account, API key, database, or paid data provider is needed. The public site previews the same React components used by the MCP Apps; inside an MCP host, snapshots come from actual MCP tool calls.

Try it in OpenWork

  1. Add https://workplace-mcp-apps.vercel.app/mcp as a remote Streamable HTTP connector. Choose no authentication for this public demo.

  2. Test tools. You should see eight launch tools. The ninth tool, get_workplace_snapshot, is an app-only refresh helper—not another dashboard card.

  3. Create a dashboard and add each App in the order below. Paste this Launch input (JSON) for each:

    { "config": {} }
  4. Enable Run automatically for these read-only demo widgets, or run each once as the host permits. Share the dashboard using your normal organization controls.

  5. Open Dashboard. In builds with the compact masonry layout, the tall agenda sits beside shorter stacked cards. Change the saved order with Den's up/down arrows. A merge into dev alone does not mean an installed release includes that layout.

The hosted /mcp URL is an API, not a webpage to embed as an iframe. A normal browser GET returns a helpful 405. Compatible hosts discover tools and ui:// resources over MCP.

Order

App / tool

Shape

Demo interaction

1

Today at a glance / show_agenda

Tall, about 700px

Select a schedule block

2

Your daily brief / show_brief

Short, about 230px

Changing metrics and activity trend

3

Needs your attention / show_attention

Medium, about 500px

Filter and expand items

4

My goals / show_goals

Short, about 230px

Expand goal checkpoints

5

Time off / show_leave

Short, about 190px

Preview a fictional leave request

6

Keep learning / show_learning

Short, about 250px

Try a sample lesson

7

Around the company / show_updates

Medium, about 330px

Choose a department and read a story

8

Quick actions / show_actions

Short, about 270px

Local previews; no real submissions

These are approximate collapsed heights at typical dashboard widths, not forced heights. Cards use one column each—no cross-column spans. Expanded content renegotiates height. A host may clamp height (OpenWork currently caps inline frames at 800px), so particularly long expanded states may scroll within that limit. Fewer available columns naturally change packing.

Related MCP server: Boardstate MCP Server

Configure without editing code

Use Configure on the live demo to choose a persona, accent, density, scenario, and refresh pace, then Copy JSON. Paste the complete object into each tile's launch input:

{
  "config": {
    "company": "Example Company",
    "viewer": "Alex",
    "team": "Product",
    "accent": "blue",
    "density": "comfortable",
    "scenario": "balanced",
    "live": true,
    "refreshSeconds": 30,
    "seed": 7
  }
}

Only config itself is required; every setting inside it is optional. Use the same configuration across tiles for a cohesive demo. Different input can give the same tool another persona on hosts that permit duplicate tools with distinct launch arguments.

Setting

Accepted values

company, viewer

Fictional labels, max 48 / 32 characters

team

Product, Engineering, Operations, Design

accent

blue, violet, teal

density

comfortable, compact

scenario

balanced, busy, focus

live

true or false

refreshSeconds

15, 30, 60

seed

Integer 09999; repeatable demo variations

The website does not save or send its configuration. Copying settings into an MCP host sends those launch arguments to this public server, so do not use sensitive labels or credentials. Company/viewer/team are not an authentication or authorization mechanism.

How the changing data works

createSnapshot() combines a time bucket, seed, and optional preview step into six deterministic demo moments. Counts, incident states, goals, and learning progress change; the sample schedule remains a readable fictional workday rather than pretending to be your actual calendar.

  • In an MCP host, the App uses callServerTool("get_workplace_snapshot") through its existing host connection. There is no direct browser fetch to a third party.

  • Pause, Refresh, and Next demo moment control the sample. No concurrent refresh requests are sent.

  • Hidden views pause. Teardown cancels requests and removes timers/observers. A failed refresh keeps the last valid data and pauses automatic updates until retry.

  • Read-only hosts can show the initial result but do not advertise or receive refresh calls.

  • live: false removes wall-clock changes. Next demo moment still works as an explicit read; reopening starts from the configured seed. Nothing persists server-side.

Run locally

Requires Node 24.x and pnpm 10.28.0 (declared in package.json).

corepack enable
pnpm install --frozen-lockfile
pnpm dev

Open http://127.0.0.1:3000/. The MCP endpoint is http://127.0.0.1:3000/mcp. Set PORT=3001 if needed. pnpm dev builds then starts the server; restart it after edits. Some remote hosts require a public HTTPS URL instead of a loopback address.

Deploy your own copy to Vercel

Fork or clone this repository into your own GitHub account, then import it into Vercel.

  • Framework: Hono

  • Root directory: repository root

  • Node: 24.x

  • Build command: pnpm build

  • No environment variables, database, or paid integration required

Or, from your clone with Vercel CLI already signed in:

vercel link
vercel --prod

Your new endpoint is https://<your-project>.vercel.app/mcp. The Copy MCP URL button derives this from the page's own origin, so it automatically works on your deployment.

vercel.json includes generated/widget.html and the generated public/ assets in the function. Keep that setting: the static showcase alone is not an MCP App deployment. Hono serves an explicit fallback for the page and content-hashed assets, with CDN cache headers, because Vercel may inventory static files before the build creates them. public/ and generated/ are dedicated generated outputs; the build replaces them. Do not put hand-maintained files there.

For a public demo, ensure Vercel deployment protection is not blocking the production endpoint. Preview deployments can remain protected. Choose your own plan/budgets; public anonymous requests still consume hosting resources. No firewall bypass token belongs in this repository or a connector URL.

Where to make changes

File

Responsibility

src/shared/config.ts

Widget catalog, tool names, recommended order, launch defaults and validation

src/shared/data.ts

Typed snapshot contract and stateless synthetic-data adapter

src/ui/Widgets.tsx, widgets.css

The actual card components shared by website and MCP views

src/ui/embedded.ts

Standard MCP Apps lifecycle, tool refresh, cancellation and height reporting

src/server/mcp.ts

Eight tool/resource bindings and the app-only helper

src/server/http.ts

Origin, request-size, method, and cache boundaries

src/ui/showcase.tsx

Public demo and developer configurator

scripts/build.ts

Inline the App resource, check its size, build the public site

Add your own widget

  1. Add its ID, title and tool name to config.ts.

  2. Extend snapshotSchema and the data adapter with its typed result.

  3. Add a React card and register it in widgetComponents in Widgets.tsx.

  4. Add it to recommendedOrder if it belongs in the default board. The server loops over the catalog to register launch tools and resources.

  5. Extend the protocol and browser tests, then deploy. Test at 320px width and after expanding/collapsing content.

Each launch tool advertises _meta.ui.resourceUri, such as ui://workplace/agenda.html. resources/read returns exactly one self-contained HTML document with MIME text/html;profile=mcp-app. All eight resource URIs share one bundled React renderer; the validated tool result selects the widget. Text fallback and explicit structured output remain available to clients without an App renderer.

Height is measured from content with ResizeObserver and reported via the official SDK's sendSizeChanged({ height }). No viewport-sized cards, 100vh, or fixed dashboard row heights; the host owns the width and placement. CSS and JavaScript are bundled inline, with no CDN/font/image dependencies or sandbox network permissions. The build enforces a resource smaller than 768 KiB.

Replace mock data with company data

Replace the adapter, not the protocol or the card layout. Add real authentication and server-side tenant/member authorization before reading private systems. Derive identity from a verified session/token, never config.viewer or config.company. Validate inputs and output, minimize returned data, and keep credentials server-side. Design write tools with explicit approval, audit, and idempotency instead of attaching them to a timer.

This example is intentionally not a production employee portal or OAuth implementation.

Checks

pnpm typecheck
pnpm test
pnpm build
pnpm test:runtime                      # plain Node import of emitted server, without a TypeScript loader
pnpm exec playwright install chromium   # first time, if no Chrome/cached Chromium
pnpm test:browser
pnpm audit --prod --audit-level high
pnpm smoke https://your-project.vercel.app  # after deployment; compares resource bytes to your local build

Tests cover validation, deterministic demo moments, real HTTP MCP negotiation/tool calls/resources, three-/one-column layout, light/dark rendering, config export, local-only interactions, and a separate-origin MCP Apps SDK host with real tool refresh and height notifications. They are not a claim of full OpenWork or every third-party host certification.

The local SDK fixture is test-only, never deployed. /healthz checks that the resource is present and valid; /catalog.json lists Apps, defaults, and readiness. The MCP endpoint accepts bounded POST requests and OPTIONS, not long-lived GET streams. Browser access is same-origin; server-side MCP clients may omit Origin. No wildcard CORS, cookies, analytics, external providers, or business writes.

License

Original project code is MIT, copyright 2026 Jalil. Bundled dependencies keep their own licenses; see THIRD_PARTY_NOTICES.md. This is an independent example using the MCP and MCP Apps standards, not an official service of those projects.

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    B
    maintenance
    MCP server that lets agents create, display, and export rich UI widgets (cards, dashboards, charts, forms) inline in conversations, with interactive iframe support in MCP Apps hosts and PNG image fallback for other clients.
    3
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables local employee onboarding, leave tracking, meeting coordination, and workplace requests through any MCP-compatible client, with optional SMTP notifications.
    2
    -