@runsnative/mcp-server 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/README.md +7 -1
  2. package/dist/components-inline.js +15478 -0
  3. package/dist/dev-host.js +68 -0
  4. package/dist/iframe-runtime.js +103 -0
  5. package/dist/index.js +2 -103
  6. package/dist/server.js +127 -0
  7. package/dist/surface/assets.js +89 -0
  8. package/dist/surface/gathering-card.js +162 -0
  9. package/dist/surface/iframe-runtime-entry.js +8 -0
  10. package/dist/surface/package-surface.js +59 -0
  11. package/dist/tokens/tokens-arctic-frost.css +1320 -0
  12. package/dist/tokens/tokens-botanical-garden.css +1320 -0
  13. package/dist/tokens/tokens-bridgesai.css +1269 -0
  14. package/dist/tokens/tokens-clay-studio.css +1320 -0
  15. package/dist/tokens/tokens-daisy-acid.css +1320 -0
  16. package/dist/tokens/tokens-daisy-aqua.css +1320 -0
  17. package/dist/tokens/tokens-daisy-autumn.css +1320 -0
  18. package/dist/tokens/tokens-daisy-black.css +1321 -0
  19. package/dist/tokens/tokens-daisy-bumblebee.css +1320 -0
  20. package/dist/tokens/tokens-daisy-business.css +1320 -0
  21. package/dist/tokens/tokens-daisy-cmyk.css +1321 -0
  22. package/dist/tokens/tokens-daisy-coffee.css +1320 -0
  23. package/dist/tokens/tokens-daisy-corporate.css +1320 -0
  24. package/dist/tokens/tokens-daisy-cupcake.css +1320 -0
  25. package/dist/tokens/tokens-daisy-cyberpunk.css +1320 -0
  26. package/dist/tokens/tokens-daisy-dark.css +1320 -0
  27. package/dist/tokens/tokens-daisy-dim.css +1320 -0
  28. package/dist/tokens/tokens-daisy-dracula.css +1320 -0
  29. package/dist/tokens/tokens-daisy-emerald.css +1320 -0
  30. package/dist/tokens/tokens-daisy-fantasy.css +1320 -0
  31. package/dist/tokens/tokens-daisy-forest.css +1320 -0
  32. package/dist/tokens/tokens-daisy-garden.css +1320 -0
  33. package/dist/tokens/tokens-daisy-halloween.css +1320 -0
  34. package/dist/tokens/tokens-daisy-lemonade.css +1320 -0
  35. package/dist/tokens/tokens-daisy-light.css +1320 -0
  36. package/dist/tokens/tokens-daisy-lofi.css +1321 -0
  37. package/dist/tokens/tokens-daisy-luxury.css +1320 -0
  38. package/dist/tokens/tokens-daisy-night.css +1320 -0
  39. package/dist/tokens/tokens-daisy-nord.css +1320 -0
  40. package/dist/tokens/tokens-daisy-pastel.css +1320 -0
  41. package/dist/tokens/tokens-daisy-retro.css +1320 -0
  42. package/dist/tokens/tokens-daisy-sunset.css +1320 -0
  43. package/dist/tokens/tokens-daisy-synthwave.css +1320 -0
  44. package/dist/tokens/tokens-daisy-valentine.css +1320 -0
  45. package/dist/tokens/tokens-daisy-winter.css +1320 -0
  46. package/dist/tokens/tokens-daisy-wireframe.css +1321 -0
  47. package/dist/tokens/tokens-daisyui-base.css +1269 -0
  48. package/dist/tokens/tokens-desert-rose.css +1320 -0
  49. package/dist/tokens/tokens-dotorg-site.css +1269 -0
  50. package/dist/tokens/tokens-forest-canopy.css +1320 -0
  51. package/dist/tokens/tokens-golden-hour.css +1320 -0
  52. package/dist/tokens/tokens-harlow-pets.css +1320 -0
  53. package/dist/tokens/tokens-kehribar.css +1320 -0
  54. package/dist/tokens/tokens-midnight-galaxy.css +1320 -0
  55. package/dist/tokens/tokens-modern-minimalist.css +1270 -0
  56. package/dist/tokens/tokens-ocean-depths.css +1320 -0
  57. package/dist/tokens/tokens-showcase-base.css +1269 -0
  58. package/dist/tokens/tokens-smoke-bold.css +1269 -0
  59. package/dist/tokens/tokens-smoke-friendly.css +1269 -0
  60. package/dist/tokens/tokens-smoke-minimal.css +1281 -0
  61. package/dist/tokens/tokens-smoke-premium.css +1280 -0
  62. package/dist/tokens/tokens-smoke-professional.css +1269 -0
  63. package/dist/tokens/tokens-smoke-retail.css +1321 -0
  64. package/dist/tokens/tokens-smoke-startup.css +1269 -0
  65. package/dist/tokens/tokens-solvlys.css +1320 -0
  66. package/dist/tokens/tokens-sunset-boulevard.css +1320 -0
  67. package/dist/tokens/tokens-tech-innovation.css +1320 -0
  68. package/dist/tokens/tokens-theme-atrium.css +1320 -0
  69. package/dist/tokens/tokens-theme-catalyst.css +1320 -0
  70. package/dist/tokens/tokens-theme-circuit.css +1320 -0
  71. package/dist/tokens/tokens-theme-dispatch.css +1320 -0
  72. package/dist/tokens/tokens-theme-dither.css +1320 -0
  73. package/dist/tokens/tokens-theme-ember.css +1320 -0
  74. package/dist/tokens/tokens-theme-fanfare.css +1320 -0
  75. package/dist/tokens/tokens-theme-ferro.css +1321 -0
  76. package/dist/tokens/tokens-theme-folio.css +1320 -0
  77. package/dist/tokens/tokens-theme-hamara.css +1270 -0
  78. package/dist/tokens/tokens-theme-komorebi.css +1321 -0
  79. package/dist/tokens/tokens-theme-kyo.css +1269 -0
  80. package/dist/tokens/tokens-theme-lattice.css +1320 -0
  81. package/dist/tokens/tokens-theme-ma.css +1321 -0
  82. package/dist/tokens/tokens-theme-marquee.css +1320 -0
  83. package/dist/tokens/tokens-theme-meridian.css +1320 -0
  84. package/dist/tokens/tokens-theme-nimbus.css +1320 -0
  85. package/dist/tokens/tokens-theme-plasma.css +1320 -0
  86. package/dist/tokens/tokens-theme-plinth.css +1320 -0
  87. package/dist/tokens/tokens-theme-quartz.css +1320 -0
  88. package/dist/tokens/tokens-theme-sus.css +1320 -0
  89. package/dist/tokens/tokens-theme-trellis.css +1269 -0
  90. package/dist/tokens/tokens-theme-vesper.css +1320 -0
  91. package/dist/tokens/tokens-theme-wabi.css +1320 -0
  92. package/dist/tools/render-gathering.js +88 -0
  93. package/package.json +5 -2
  94. package/dist/tools/surface-preview.js +0 -36
@@ -0,0 +1,88 @@
1
+ import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
2
+ import { getWorkerApi } from '../bridge-client.js';
3
+ import { componentsBundle, iframeRuntime, themeCss } from '../surface/assets.js';
4
+ import { buildGatheringCardHtml, GATHERING_CARD_URI } from '../surface/gathering-card.js';
5
+ import { SURFACE_MIME_TYPE } from '../surface/package-surface.js';
6
+ // Display labels for the brands offered by the create-gathering form
7
+ // (compare.js). Unknown brand_ids fall back to the id itself client-side.
8
+ const BRAND_LABELS = {
9
+ 'dotorg-site': 'RunsNative',
10
+ 'harlow-pets': 'Harlow Pets',
11
+ 'clay-studio': 'Kiln & Clay Studio',
12
+ };
13
+ export const RENDER_GATHERING_TOOL = {
14
+ name: 'render_gathering',
15
+ description: "Render the user's most recent Convene gathering as a live, branded, interactive card " +
16
+ 'inside this conversation (an MCP App surface — real run-* components, the tenant\'s own ' +
17
+ 'theme, a working View action). Use as the finale of the create-a-gathering exercise, ' +
18
+ 'right after the user has created their gathering on the site. Requires the tenant ' +
19
+ 'API token (RUNSNATIVE_TENANT_TOKEN) so the gathering can be fetched from the tenant store.',
20
+ inputSchema: {
21
+ type: 'object',
22
+ properties: {},
23
+ required: [],
24
+ },
25
+ _meta: {
26
+ ui: { resourceUri: GATHERING_CARD_URI },
27
+ // Legacy key for hosts predating _meta.ui (ext-apps compatibility shim).
28
+ 'ui/resourceUri': GATHERING_CARD_URI,
29
+ },
30
+ };
31
+ export const GATHERING_CARD_RESOURCE = {
32
+ uri: GATHERING_CARD_URI,
33
+ name: 'Gathering Card',
34
+ description: 'Self-contained MCP App shell that renders a Convene gathering as a branded RunsNative card. ' +
35
+ 'Data arrives via the tool-result notification; nothing external is loaded.',
36
+ mimeType: SURFACE_MIME_TYPE,
37
+ };
38
+ export async function readGatheringCardResource() {
39
+ const html = buildGatheringCardHtml({
40
+ componentsBundle: componentsBundle(),
41
+ iframeRuntime: iframeRuntime(),
42
+ });
43
+ return {
44
+ contents: [{ uri: GATHERING_CARD_URI, mimeType: SURFACE_MIME_TYPE, text: html }],
45
+ };
46
+ }
47
+ export async function handleRenderGathering() {
48
+ const res = await getWorkerApi('/tenant/gatherings');
49
+ if (res.status === 401) {
50
+ throw new McpError(ErrorCode.InvalidParams, 'Not authenticated with the tenant store. Set RUNSNATIVE_TENANT_TOKEN in the MCP server ' +
51
+ 'config (the same tenant the user signs into on the site — a linked session guarantees they match).');
52
+ }
53
+ if (!res.ok) {
54
+ const body = await res.text().catch(() => '');
55
+ throw new McpError(ErrorCode.InternalError, `Worker error ${res.status}: ${body}`);
56
+ }
57
+ const data = (await res.json());
58
+ const gatherings = data.gatherings ?? [];
59
+ if (gatherings.length === 0) {
60
+ return {
61
+ content: [
62
+ {
63
+ type: 'text',
64
+ text: 'No gatherings found for this tenant yet. Create one first — on the Convene page ' +
65
+ '(/compare/), sign in and submit the create-gathering form (exercise step 2) — then call this tool again.',
66
+ },
67
+ ],
68
+ };
69
+ }
70
+ // Rows arrive ORDER BY created_at DESC — the first is the most recent.
71
+ const gathering = gatherings[0];
72
+ const css = await themeCss(gathering.brand_id);
73
+ return {
74
+ content: [
75
+ {
76
+ type: 'text',
77
+ text: `Rendered "${gathering.title}" (${gathering.brand_id}) as a live card in the conversation. ` +
78
+ 'The card is the real surface — same components and theme as the site, with a working View action.',
79
+ },
80
+ ],
81
+ structuredContent: {
82
+ gathering,
83
+ theme_css: css,
84
+ theme_landed: css !== null,
85
+ brand_label: BRAND_LABELS[gathering.brand_id] ?? null,
86
+ },
87
+ };
88
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runsnative/mcp-server",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/"
@@ -15,7 +15,7 @@
15
15
  "runsnative-mcp": "./dist/index.js"
16
16
  },
17
17
  "scripts": {
18
- "build": "tsc",
18
+ "build": "tsc && node scripts/build-iframe-runtime.mjs",
19
19
  "dev": "tsc --watch",
20
20
  "start": "node dist/index.js",
21
21
  "http-server": "node dist/http-server.js",
@@ -24,10 +24,13 @@
24
24
  "prepublishOnly": "npm run build"
25
25
  },
26
26
  "dependencies": {
27
+ "@modelcontextprotocol/ext-apps": "^1.7.4",
27
28
  "@modelcontextprotocol/sdk": "^1.0.0"
28
29
  },
29
30
  "devDependencies": {
31
+ "@runsnative/components": "^0.5.0",
30
32
  "@types/node": "^25.6.0",
33
+ "esbuild": "^0.25.0",
31
34
  "playwright": "^1.58.2",
32
35
  "sharp": "^0.33.0",
33
36
  "typescript": "^5.5.3",
@@ -1,36 +0,0 @@
1
- import { readFileSync } from 'node:fs';
2
- import { resolve, dirname } from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
- const __filename = fileURLToPath(import.meta.url);
5
- const __dirname = dirname(__filename);
6
- export const SURFACE_PREVIEW_TOOL = {
7
- name: 'surface_preview',
8
- description: 'Renders a RunsNative component fixture (run-table + run-button) inside an MCP App ' +
9
- 'iframe. Used to verify that RunsNative web components hydrate correctly in the claude.ai ' +
10
- 'MCP Apps sandbox. Returns HTML content. This tool exists for RUN-477 verification — ' +
11
- 'it is not a production surface.',
12
- inputSchema: {
13
- type: 'object',
14
- properties: {},
15
- required: [],
16
- },
17
- };
18
- export function handleSurfacePreview() {
19
- // Read fixture from the fixtures/ sibling dir at call time, not compile time,
20
- // so hot-reloading the fixture doesn't require rebuilding the server.
21
- // In dist/, __dirname resolves to dist/tools/; fixture is at ../../fixtures/.
22
- const fixturePath = resolve(__dirname, '../../fixtures/surface-preview.html');
23
- const html = readFileSync(fixturePath, 'utf8');
24
- return {
25
- content: [
26
- {
27
- type: 'resource',
28
- resource: {
29
- uri: 'data:text/html;charset=utf-8,surface-preview',
30
- mimeType: 'text/html',
31
- text: html,
32
- },
33
- },
34
- ],
35
- };
36
- }