open_in_app
Open a DGMO diagram in the Diagrammo desktop app on macOS, with automatic fallback to browser preview if the app is missing.
Instructions
Open a DGMO diagram in the Diagrammo desktop app (macOS only). Falls back to browser preview if the app is not installed.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| dgmo | Yes | DGMO diagram markup |
Implementation Reference
- src/index.ts:272-350 (handler)The main handler function for the 'open_in_app' tool. Encodes the DGMO diagram as a URL, attempts to open via deep link (diagrammo://open?dgmo=...) using macOS 'open' command. Falls back to rendering as SVG and opening in a browser if the app is not installed.
async ({ dgmo }) => { const result = encodeDiagramUrl(dgmo); if (result.error === 'too-large') { return { content: [ { type: 'text' as const, text: `Diagram is too large for URL encoding. Compressed size: ${result.compressedSize} bytes (limit: ${result.limit} bytes).`, }, ], isError: true, }; } // Extract the hash from the URL and construct a deep link const url = result.url; const hash = url.split('#')[1] ?? ''; const deepLink = `diagrammo://open?dgmo=${hash}`; return new Promise((resolve) => { exec(`open ${JSON.stringify(deepLink)}`, async (error) => { if (error) { // Fallback: render to SVG and open in browser try { const rendered = await tryRender(dgmo, 'light', 'nord'); if (!rendered.svg) { resolve({ content: [ { type: 'text' as const, text: `App not installed and render failed: ${rendered.error}`, }, ], isError: true, }); return; } const paletteConfig = getPalette('nord'); const html = buildPreviewHtml({ svg: rendered.svg, title: 'Diagram Preview', dgmoSource: dgmo, palette: paletteConfig, shareUrl: url, }); const filePath = writeTempHtml(html, 'dgmo-preview'); await openInBrowser(filePath); resolve({ content: [ { type: 'text' as const, text: `Diagrammo app not found — opened preview in browser: ${filePath}`, }, ], }); } catch (fallbackErr) { resolve({ content: [ { type: 'text' as const, text: `Failed to open Diagrammo app and browser fallback failed: ${fallbackErr instanceof Error ? fallbackErr.message : String(fallbackErr)}`, }, ], isError: true, }); } } else { resolve({ content: [ { type: 'text' as const, text: 'Opened diagram in Diagrammo app.', }, ], }); } }); }); }, - src/index.ts:258-351 (registration)Registration of the 'open_in_app' tool via server.tool(), including description, input schema (dgmo string), tool metadata (title, readOnlyHint, destructiveHint, openWorldHint), and the async handler callback.
// --- Tool 3: open_in_app --- server.tool( 'open_in_app', 'Open a DGMO diagram in the Diagrammo desktop app (macOS only). Falls back to browser preview if the app is not installed.', { dgmo: z.string().describe('DGMO diagram markup'), }, { title: 'Open in Diagrammo App', readOnlyHint: false, destructiveHint: false, openWorldHint: true, }, async ({ dgmo }) => { const result = encodeDiagramUrl(dgmo); if (result.error === 'too-large') { return { content: [ { type: 'text' as const, text: `Diagram is too large for URL encoding. Compressed size: ${result.compressedSize} bytes (limit: ${result.limit} bytes).`, }, ], isError: true, }; } // Extract the hash from the URL and construct a deep link const url = result.url; const hash = url.split('#')[1] ?? ''; const deepLink = `diagrammo://open?dgmo=${hash}`; return new Promise((resolve) => { exec(`open ${JSON.stringify(deepLink)}`, async (error) => { if (error) { // Fallback: render to SVG and open in browser try { const rendered = await tryRender(dgmo, 'light', 'nord'); if (!rendered.svg) { resolve({ content: [ { type: 'text' as const, text: `App not installed and render failed: ${rendered.error}`, }, ], isError: true, }); return; } const paletteConfig = getPalette('nord'); const html = buildPreviewHtml({ svg: rendered.svg, title: 'Diagram Preview', dgmoSource: dgmo, palette: paletteConfig, shareUrl: url, }); const filePath = writeTempHtml(html, 'dgmo-preview'); await openInBrowser(filePath); resolve({ content: [ { type: 'text' as const, text: `Diagrammo app not found — opened preview in browser: ${filePath}`, }, ], }); } catch (fallbackErr) { resolve({ content: [ { type: 'text' as const, text: `Failed to open Diagrammo app and browser fallback failed: ${fallbackErr instanceof Error ? fallbackErr.message : String(fallbackErr)}`, }, ], isError: true, }); } } else { resolve({ content: [ { type: 'text' as const, text: 'Opened diagram in Diagrammo app.', }, ], }); } }); }); }, ); - src/index.ts:263-265 (schema)Input schema for the 'open_in_app' tool - requires a single string parameter 'dgmo' (DGMO diagram markup).
{ dgmo: z.string().describe('DGMO diagram markup'), }, - src/open-browser.ts:1-18 (helper)The openInBrowser helper function used by the fallback path. Cross-platform: uses 'open' on macOS, 'start' on Windows, 'xdg-open' on Linux.
import { exec } from 'node:child_process'; import { platform } from 'node:os'; /** * Open a file path in the default browser. Cross-platform. */ export function openInBrowser(filePath: string): Promise<void> { const os = platform(); const cmd = os === 'darwin' ? 'open' : os === 'win32' ? 'start ""' : 'xdg-open'; return new Promise((resolve, reject) => { exec(`${cmd} ${JSON.stringify(filePath)}`, (error) => { if (error) reject(error); else resolve(); }); }); }