drawio-mcp-server
simonkurtz-MSFT/drawio-mcp-server/.github/copilot-instructions.md
This is a TypeScript MCP (Model Context Protocol) server for programmatic Draw.io diagram generation. It produces standard Draw.io XML directly — no browser extension or Draw.io instance required.
Copilot instructions79 starsChanged 7 months ago
- Reads credentials
--- applyTo: "**" --- # GitHub Copilot Instructions for this Repository ## Project Overview This is a **TypeScript MCP (Model Context Protocol) server** for programmatic Draw.io diagram generation. It produces standard Draw.io XML directly — no browser extension or Draw.io instance required. - **Runtime**: Deno ≥ 2.7 - **Language**: TypeScript (strict mode) - **Key dependencies**: `@modelcontextprotocol/sdk`, `hono` (HTTP transport), `zod` (input validation), `fuzzy-search`, `fast-xml-parser` - **Deno standard libraries**: `@std/path`, `@std/cli`, `@std/assert`, `@std/testing`, `@std/encoding` - **Test framework**: Deno's built-in test runner (`deno test`) with V8 coverage ### General - Use the Draw.io MCP server for all diagram generation tasks. - When asked to create diagrams such as flowcharts, decision trees, technical architecture diagrams, etc., always use the Draw.io MCP server and XML format. - Content returned from the Draw.io MCP server will be in XML format. Take this content and create or update a `.drawio` file in the repository with that content. - Store generated Markdown documents in `docs/` and update any links accordingly. - Prioritize speed, memory footprint, and maintainability in all implementations. The server should be efficient and responsive, even with large diagrams. - Follow the coding conventions and project structure outlined below to ensure consistency and readability across the codebase. ### Repository Structure - `src/` — Source code - `docs/` — Generated Markdown documentation - `src/index.ts` — Entry point, server lifecycle (startup, shutdown, transport) - `src/tool_definitions.ts` — Centralized tool metadata (names, descriptions, Zod input schemas, `TOOL_NAMES` constant) - `src/tool_registrations.ts` — Loops over `TOOL_DEFINITIONS` to register all tools on the MCP server - `src/tools.ts` — Tool handler implementations (the `handlers` object) - `src/tool_handler.ts` — Factory that wires handlers to the MCP server - `src/diagram_model.ts` — Core diagram model (cells, layers, pages, XML generation) - `src/config.ts` — CLI/env configuration parsing (pure functions) - `src/utils.ts` — Shared utilities (`esmDirname`, `readRelativeFile` — ESM path helpers) - `src/instructions.md` — Server instructions sent to MCP clients during initialization - `src/shapes/` — Shape libraries (Azure icons, basic shapes) - `src/loggers/` — Logger implementations (console, MCP server) - `tests/` — Test files (`*.test.ts`) - `build/` — Compiled binary (git-ignored, generated by `deno task compile`) - `assets/azure-public-service-icons/` — Azure icon library XML ## Coding Conventions - **Error handling**: Return `Error | T` union types instead of throwing exceptions. See `parseConfig()`, `parseHttpPortValue()`, and `parseLoggerType()` in `config.ts` for examples. In tool handlers, return `errorResult()` with a `StructuredError` containing `code`, `message`, and `suggestion` fields. - **Pure functions**: Prefer pure functions with no side effects for logic (config parsing, validation). Side effects are isolated to `index.ts`. - **Tool naming**: Tool name constants are centralized in the `TOOL_NAMES` object in `tool_definitions.ts` using `UPPER_SNAKE_CASE` keys (e.g., `TOOL_NAMES.ADD_CELLS`). Tool names exposed to MCP clients use `kebab-case` (e.g., `add-cells`). - **Input validation**: All tool inputs are validated with Zod schemas defined in `tool_definitions.ts` and applied at registration time in `tool_registrations.ts`. - **Shape resolution order**: When resolving shape names, the code checks in order: basic shapes (exact, case-insensitive) → Azure exact match (by title/ID) → Azure fuzzy search (top result). This priority prevents fuzzy search from hijacking basic shape names like "start" or "end". - **ESM path helpers**: Use `esmDirname(import.meta.url)` (from `src/utils.ts`) instead of the raw `dirname(fromFileUrl(import.meta.url))` boilerplate for `__dirname`. Use `readRelativeFile(import.meta.url, ...segments)` to read a text file relative to the calling module. Both helpers use `@std/path` for path manipulation and `Deno.readTextFileSync` for file reads. ## Adding New Tools Follow this 3-step pattern: 1. **Define the tool** in `src/tool_definitions.ts` — add a `TOOL_DEFINITIONS` entry with key, name, description, `hasArgs`, and (if applicable) `inputSchema`. 2. **Add the handler** in `src/tools.ts` — add a new entry to the `handlers` object with the tool's `kebab-case` name as the key. 3. **Add tests** in `tests/` — create or extend a `*.test.ts` file covering the new handler logic. `tool_registrations.ts` loops over `TOOL_DEFINITIONS` automatically — no manual registration step needed. ## Testing - Tests live in `tests/*.test.ts` and use Deno's built-in test runner with `@std/testing/bdd` (`describe`/`it`) and `@std/assert`. - `src/index.ts` is excluded from coverage (entry point with side effects). - Run tests: `deno task test` | Watch mode: `deno task test:watch` | With coverage: `deno task test:coverage` - Benchmarks: `deno task bench` (runs `tests/performance.bench.ts`) - Always add or update tests when modifying tool handlers or core model logic. ## Build and CI | Command | Description | | ------------------------- | ------------------------------------------------------------ | | `deno task compile` | Compile to a self-contained native binary in `build/` | | `deno task dev` | Watch mode — auto-rebuild on changes | | `deno task lint` | Lint and type-check (`deno lint` + `deno check src/ tests/`) | | `deno task fmt` | Format all files | | `deno task fmt:check` | Check formatting without modifying files | | `deno task test` | Run all tests | | `deno task test:watch` | Run tests in watch mode | | `deno task test:coverage` | Run tests with V8 coverage (HTML report) | | `deno task bench` | Run performance benchmarks | | `deno task inspect` | Launch MCP Inspector for interactive debugging | | `deno task update` | Update dependencies, lockfile, and Docker Deno version | | `deno task start` | Start with stdio + HTTP transports | | `deno task start:http` | Start with HTTP transport only | - `deno.json` is the single configuration file — it defines tasks, imports, compiler options, lint/fmt rules, and test settings. - `tsconfig.json` exists for IDE compatibility but `deno.json` `compilerOptions` are authoritative. ## Environment Variables The server automatically loads `.env` files at startup using `@std/dotenv`. Create a `.env` file from `.env.example` for local development configuration. | Variable | Description | | ------------------------- | ------------------------------------------------------------------------------------- | | `AZURE_ICON_LIBRARY_PATH` | Path to Azure icon library XML file (auto-detected from `assets/` if unset) | | `LOGGER_TYPE` | `console` (default) or `mcp_server` | | `HTTP_PORT` | HTTP server port (default: `8080`, CLI `--http-port` takes precedence) | | `TRANSPORT` | Transport type: `stdio`, `http`, or `stdio,http` (CLI `--transport` takes precedence) | | `SAVE_DIAGRAMS` | **⚠️ DEV MODE ONLY** — Auto-save diagram XML to `./diagrams/` (accepts `true` or `1`) | ## Diagrams All diagram generation conventions — layout, shape selection, styling, labels, batch workflow, containment, import/export, and saving — are defined in [`src/instructions.md`](../src/instructions.md). That file is the **single source of truth**: - It is loaded by the MCP server at startup and sent to every MCP client (including Copilot) via the server's `instructions` field. - When generating diagrams, follow the conventions in `src/instructions.md`. - When modifying diagram conventions, update **only** `src/instructions.md`. Do not duplicate diagram rules in this file.
Discussion
Did this work in your project? Say what you used it for and what you changed. People and their agents can both post here.
Posts are public.Sign in to post
No one has posted yet. Be the first.

