Lines 1-56javascript
5 * Filesystem-style tools for agents to read/write/edit frames on the canvas.
6 * Calls the Drafted HTTP API directly (no CLI subprocess).
9import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
10import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
11import { execFile } from 'child_process';
12import { createHash } from 'node:crypto';
HighChild Process
Package source references child process execution.
mcp/server.mjsView on unpkg · L10 13import { readFileSync, existsSync, realpathSync, writeFileSync, mkdirSync, unlinkSync, appendFileSync, readdirSync, statSync } from 'fs';
14import { join, dirname, basename, extname, resolve } from 'path';
15import { homedir, platform, release as osRelease, arch as osArch } from 'os';
16import { fileURLToPath } from 'url';
17import { AsyncLocalStorage } from 'node:async_hooks';
18import { z } from 'zod';
19import { registerAppResource, RESOURCE_MIME_TYPE } from '@modelcontextprotocol/ext-apps/server';
20import WebSocket from 'ws';
21import { LAYERS } from '../src/shared/constants.mjs';
22import { emptyExcalidrawScene, stringifyExcalidrawScene } from '../src/shared/excalidraw.mjs';
23import { formatOkfLogEntry, appendOkfLogEntry } from '../src/shared/okf-log.mjs';
24import { createGateState, markSearched, g1Block, g2Block, g3Block, selectWithinBudget, wouldExceedBudget, budgetError, formatWikiIndex, PROJECT_CONTEXT_BUDGET_CHARS } from './gates.mjs';
25import { loadPersistedProject, savePersistedProject } from './active-project-store.mjs';
27// Frame actions that mutate content — gated by G1 (wiki search before editing).
28// Read-style actions (read, search, versions, get_*/read_*) are exempt.
29const G1_MUTATING_FRAME_ACTIONS = new Set([
30 'write', 'write_excalidraw', 'edit', 'mv', 'anchor', 'restore_version',
31 'write_sheet_values', 'append_sheet_rows', 'clear_sheet_range', 'update_sheet',
32 'write_doc_content', 'append_doc_content', 'clear_doc_content', 'update_doc',
33 'write_slide_content', 'append_slides', 'clear_slides', 'update_slide',
35const { UMAMI_EVENTS, trackUmamiEvent } = await (async () => {
37 return await import('../server/lib/umami.mjs');
38 } catch {
MediumDynamic Require
Package source references dynamic require/import behavior.
mcp/server.mjsView on unpkg · L36 40 UMAMI_EVENTS: Object.freeze({
41 MCP_CONNECTED: 'mcp_connected',
42 MCP_TOOL_CALLED: 'mcp_tool_called',
43 DRAFTED_MCP_REQUEST: 'drafted_mcp_request',
44 DRAFTED_MCP_ERROR: 'drafted_mcp_error',
46 trackUmamiEvent: () => {},
51const __dirname = dirname(fileURLToPath(import.meta.url));
53// Read the npm package version once so the MCP server, get_org, and the
54// `drafted://info` resource all report the same number — and it stays in
55// sync with package.json automatically (no hardcoded duplicate).
56const PACKAGE_VERSION = (() => {