Skip to content

Commit 76c6073

Browse files
authored
feat: interactive ticket card via MCP Apps (SEP-1865) (#52)
syncro_tickets_get results render as an interactive ticket card in MCP Apps hosts, with resolved customer/contact names, recent comments, and an in-card "Add comment" round-trip via syncro_tickets_add_comment that defaults to internal-only (hidden: true) visibility resolved server-side. - _meta (ui/resourceUri + nested ui.resourceUri) on the two renderable tools, pointing at ui://syncro/ticket-card.html - new resources capability: resources/list + resources/read serve the card as text/html;profile=mcp-app from a committed build-time embed (src/generated/ticket-card-html.ts) so stdio, Node HTTP, and Workers runtimes all serve it identically - _card normalization is best-effort: any failure degrades or drops the card, never the tool result - neutral by default (system fonts, no vendor identity, no external fetches); brandable at serve time via window.__BRAND__ injection or MCP_BRAND_* env vars (BRAND_INJECT marker, <-escaped, empty brand serves the HTML byte-identical) - DOM-construction-only rendering; vendor text never hits innerHTML - 17 contract tests in tests/mcp-apps.test.ts Part of the fleet rollout tracked in WYREAI-163.
1 parent 04a8315 commit 76c6073

14 files changed

Lines changed: 1762 additions & 527 deletions

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
## [Unreleased]
22

3+
### Added
4+
5+
- **Interactive ticket card via MCP Apps (SEP-1865).** `syncro_tickets_get` results now render as an interactive card in MCP Apps hosts (Claude Desktop/web, and other hosts advertising the `io.modelcontextprotocol/ui` extension), instead of a wall of JSON. The card shows the ticket subject, status, problem type, resolved customer/contact names, key dates, and recent comments — and includes a working "Add comment" round-trip that calls `syncro_tickets_add_comment` with a safe internal-only (`hidden: true`) default resolved server-side. Non-App hosts are unaffected: the tool's JSON payload is unchanged apart from a new `_card` field.
6+
- The two renderable tools advertise the UI via `_meta` (`ui/resourceUri`, plus the nested `ui.resourceUri` form) pointing at a new `ui://syncro/ticket-card.html` resource served as `text/html;profile=mcp-app`. The card HTML is a self-contained vite single-file bundle embedded at build time (`src/generated/ticket-card-html.ts`, committed), so it serves identically from stdio, Node HTTP, and the fs-less Cloudflare Workers runtime. The server now declares the `resources` capability and answers `resources/list` / `resources/read` (`src/resources.ts`).
7+
- The card is neutral by default (system fonts, no vendor identity, no external fetches) and brandable via `window.__BRAND__` injection or `MCP_BRAND_*` env vars (`MCP_BRAND_NAME`, `MCP_BRAND_LOGO_URL`, `MCP_BRAND_PRIMARY_COLOR`, `MCP_BRAND_ACCENT_COLOR`, `MCP_BRAND_BG`, `MCP_BRAND_TEXT`): at serve time the server replaces the card's BRAND_INJECT marker with an inline, `<`-escaped `window.__BRAND__` script, so self-hosters can theme the card without rebuilding. No brand configured = HTML served unchanged.
8+
39
### Changed
410

511
- **Published to GitHub Packages.** Enabled npm publishing for the already-scoped `@wyre-technology/syncro-mcp` package: `@semantic-release/npm` `npmPublish` is now `true` and `publishConfig.registry` points at `npm.pkg.github.com`. The release workflow already configured an authenticated `.npmrc` and `packages: write`. Updated the README, which previously stated there was no npm package. The GHCR image name and `io.github.wyre-technology/syncro-mcp` MCP Registry identifier are unchanged.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ A Model Context Protocol (MCP) server for Syncro MSP, implementing a decision tr
2828
- **Domain Navigation**: Navigate between customers, tickets, assets, contacts, and invoices
2929
- **Lazy Loading**: Domain handlers and the Syncro client are loaded on-demand
3030
- **Full Syncro API Coverage**: Access to key Syncro MSP functionality
31+
- **Interactive Ticket Card (MCP Apps)**: `syncro_tickets_get` renders as an interactive card in MCP Apps hosts (Claude Desktop/web) with an in-card "Add comment" round-trip via `syncro_tickets_add_comment` (internal-only by default); plain-JSON behavior is unchanged in other hosts. The card is neutral by default, brandable via `window.__BRAND__` injection or `MCP_BRAND_*` env vars (`MCP_BRAND_NAME`, `MCP_BRAND_LOGO_URL`, `MCP_BRAND_PRIMARY_COLOR`, `MCP_BRAND_ACCENT_COLOR`, `MCP_BRAND_BG`, `MCP_BRAND_TEXT`) — no rebuild needed.
3132

3233
## Installation
3334

0 commit comments

Comments
 (0)