Skip to content

uml-mcp: From an MCP tool call to a diagram

uml-mcp exposes diagram tools to MCP clients. The client supplies diagram source and options; the server validates and routes the request to rendering services, then returns diagram results and useful editor links.

Application and services API
  • Updated
  • 108
  • Python · 90.9%
  • MIT
Repository languagesPython 90.9%9

Shares calculated from GitHub Linguist bytes.

Language%Bytes
Python90.9%1,642,190
TypeScript7.99%144,367
Shell0.31%5,667
CSS0.26%4,713
Go Template0.23%4,227
Makefile0.14%2,522
3 more languages
Dockerfile0.11%1,964
JavaScript0.03%587
HTML0.02%422

GitHub · README · Language statistics

Overview

Why it exists

Flagship Model Context Protocol (MCP) server generating PlantUML, Mermaid, and Kroki directly from LLMs (Claude, Cursor, ChatGPT) with zero local dependencies.

Best fit

Interactive architectural diagram generation for AI pair programming and automated design docs.

Getting started

These commands come from the repository documentation. They were not run during this review.

README.md · Quick start
git clone https://github.com/antoinebou12/uml-mcp.git
cd uml-mcp
uv sync
uv run python server.py
README.md · Quick start
git remote add origin https://github.com/antoinebou12/uml-mcp.git
tests/mcp-rig/README.md · Running
make mcp-rig
tests/mcp-rig/README.md · Running
uvx [email protected] run tests/mcp-rig/
uvx [email protected] run tests/mcp-rig/ --tag smoke
uvx [email protected] run tests/mcp-rig/generate.yaml --case "batch*"
uvx [email protected] run tests/mcp-rig/ --server-logs   # show server stderr when debugging
Tasks declared in manifests

frontend/package.json

dev
vite
build
npm run typecheck && vite build
typecheck
node node_modules/typescript-7/bin/tsc --noEmit
lint
eslint .
test
vitest run

Repository references

Excerpts from the repository’s guides, in their original language. Links open the inspected source revision.

Prerequisites and first run

Quick start

README.md

Remote (recommended) — add to your MCP client: Use /mcp, not the site root. Then ask: “Draw a sequence diagram of a user logging in through an API gateway.” or paste PlantUML / Mermaid / Kroki source. Repo defaults: .cursor/mcp.json · .vscode/mcp.json · .codex/config.toml.

ClientConfigGuide
Cursor.cursor/mcp.jsondocs/integrations/cursor.md
VS Code / Copilot.vscode/mcp.jsondocs/integrations/vscode_copilot.md
OpenAI Codex.codex/config.tomldocs/integrations/openai_codex.md
Ollama / Open WebUIconfig/openwebui_mcp.jsondocs/integrations/ollama.md
Claude Desktopconfig/claude_desktop_*.jsondocs/integrations/claude_desktop.md
All snippets: config/README.md
Install locally (guided):
PathCommand
——
Installer (needs only Python + typer + tqdm)python scripts/install.py
Setup wizarduv tool…
Read the full instructions ↗

Prerequisites

CONTRIBUTING.md

  • Python 3.12+ (supported range is >=3.12,<3.16 in pyproject.toml; CI exercises 3.12 and 3.15; Docker uses 3.15)
  • uv, Poetry, or pip
Read the full instructions ↗

Lockfile and `requirements.txt`

CONTRIBUTING.md

uv.lock is the runtime source of truth for CI, Vercel, and release validation. Deploy/install paths export from the lockfile at runtime. Keep requirements.txt updated for users that still install with pip: Run this after changing runtime dependencies in pyproject.toml / uv.lock, then commit the updated requirements.txt. Transitive pins: Some packages are pinned only in [tool.uv] override-dependencies in pyproject.toml (they are not direct Poetry deps). Dependabot is configured for the uv ecosystem so PRs target uv.lock consistently. After merging a dependency PR, re-export requirements.txt if the lockfile changed so CI’s “export matches requirements.txt” step stays green.
Read the full instructions ↗

Installation

docs/installation.md

PathBest forCommand
InstallerAnyone; needs only Python 3.12+, typer and tqdmpython scripts/install.py
Setup wizardTerminal usersuv tool install uml-mcp && uml-mcp setup
Web setupA guided form in the browseruml-mcp setup –web
Server / KubernetesTeamsDocker · Helm + SSO
Read the full instructions ↗

1. Quick install

docs/installation.md

The installer picks uv (uv tool install), then pipx, then pip –user, shows progress and then starts the setup wizard.

OptionMeaning
–method uv|pipx|pipForce an installer
–version 1.4.0Pin a version
–extras otelOptional extras (otel = OpenTelemetry)
–webRun the browser setup form instead of the terminal wizard
–no-setupInstall only
–dry-runPrint the commands, change nothing
Prefer doing it yourself? uv tool install uml-mcp (or pipx install uml-mcp).
Read the full instructions ↗
Configuration and usage

Development setup

CONTRIBUTING.md

  1. Fork and clone the repo:
  2. Create a virtual environment and install dependencies (including dev): With uv (recommended): With Poetry: With pip:
  3. (Optional) Install pre-commit hooks so lint/format run before each commit:
Read the full instructions ↗

MCP Client Configuration Examples

config/README.md

Read the full instructions ↗

Client matrix

config/README.md

ClientHosted HTTPLocal stdioGuide
Cursorcursor_http.json · .cursor/mcp.jsoncursor_config.jsondocs/integrations/cursor.md
Claude Desktopclaude_desktop_http.jsonclaude_desktop_config.jsondocs/integrations/claude_desktop.md
VS Code / GitHub Copilotvscode_mcp.json · .vscode/mcp.jsonvscode_mcp_stdio.jsondocs/integrations/vscode_copilot.md
OpenAI Codexcodex_config.toml · .codex/config.tomlcodex_stdio.tomldocs/integrations/openai_codex.md
Open WebUI + Ollamaopenwebui_mcp.jsonOptional via mcpodocs/integrations/ollama.md
Continue + Ollamacontinue_config.yamlSee comments in that filedocs/integrations/ollama.md
Read the full instructions ↗

OpenAI Codex (CLI + IDE)

config/README.md

  • User: ~/.codex/config.toml
  • Project: .codex/config.toml (loads only when the project is trusted)
  • Verify: codex mcp list or /mcp in a session
Read the full instructions ↗

2. Setup wizard (`uml-mcp setup`)

docs/installation.md

The wizard asks for:

  • a profile (local, docker or enterprise)
  • which features to turn on (each one is explained, with whether it applies live or needs a restart)
  • a Kroki server
  • which MCP clients to register It then runs, with a progress bar:
  1. validate the configuration
  2. write ~/.config/uml-mcp/config.yaml (mode 0600, with a backup of any previous file)
  3. register the clients
  4. run a health check
    Feature keyWhat it doesApplies
    memory_onlyKeep diagrams in memory; return URLs/bytes, no filesrestart
    diagram_fallbackRetry with PlantUML server or mermaid.ink when Kroki failsrestart
    auditMXCP-style audit trail of every call (redacted)live
    json_logsOne JSON object per log linelive
    metrics_endpointPrometheus /metricsrestart
    otelOpenTelemetry traces (needs uml-mcp[otel])live
    rate_limit…
Read the full instructions ↗
Operations and troubleshooting

Uninstall

docs/installation.md

Then remove the uml-mcp entry from your client’s MCP config. A backup of the previous config is kept next to it.
Read the full instructions ↗

Troubleshooting

docs/installation.md

SymptomFix
uml-mcp: command not foundOpen a new terminal, or run uv tool update-shell or pipx ensurepath
Setup page says “Enter the setup token”Use the token printed by uml-mcp admin, or set UML_MCP_ADMIN_TOKEN
Diagrams fail to renderCheck rendering.kroki_server reachability; enable diagram_fallback
Settings are read-onlyThe file is mounted read-only (e.g. Kubernetes); use Download YAML and apply it through your deployment
uml-mcp lint reports CFG010pip install “uml-mcp[otel]” or turn OpenTelemetry off
Read the full instructions ↗

Health check (HTTP deployment)

docs/configuration.md

When running the FastAPI app (app.py) for HTTP deployment (e.g. Vercel, Docker, uvicorn), a health endpoint is available:

  • Endpoint: GET /health (no authentication required)
  • Response: {“status”: “healthy”, “modules_available”: true|false}
  • status: Always “healthy” when the server is up.
  • modules_available: Whether diagram backends (Kroki, PlantUML, etc.) could be loaded. Use /health for load balancers, Kubernetes or Docker liveness/readiness probes, Vercel checks, and similar monitoring whenever you run the FastAPI app (app.py). When running the MCP server via fastmcp run with HTTP transport only (no FastAPI app), the standalone server does not expose /health unless you add a custom route; use the FastAPI app if you need the health endpoint.
Read the full instructions ↗

Troubleshooting

docs/admin/install.md

SymptomCause and fix
404 on /admin of a serverAuth is off and admin.allow_local_without_auth is not true, or the request didn’t come from loopback
Buttons are disabled, “Enter the setup token”Use the link printed by uml-mcp admin, or paste the token into the key icon in the top bar
docker is not installed / the Docker daemon is not runningInstall Docker Desktop or Engine, start it, then run uml-mcp kroki up again
port is already allocatedAnother service uses 8001: uml-mcp kroki up –port 8002 –use
A companion shows HTTP 500 right after startIt is still starting. Run uml-mcp kroki status again after a few seconds; up already waits up to 5 minutes
KROKI_SERVER is set by the environment (409)An environment variable wins over uml-mcp.yaml. Change or unset it where the server is started
Rendering works in the playground but…
Read the full instructions ↗
Development and contributions

Contributing to UML-MCP

CONTRIBUTING.md

Thank you for considering contributing. This document explains how to set up your environment, run tests, and submit changes.
Read the full instructions ↗

Running tests

CONTRIBUTING.md

With coverage: Black-box tests of the stdio server (real transport, YAML suites, no network) run with MCP Rig: See tests/mcp-rig/README.md for the suites, tags and how to update snapshots.
Read the full instructions ↗

Development install (from a clone)

docs/installation.md

To work on the console, see Frontend. Poetry (poetry install –with dev) and pip (pip install -e .) also work.
Read the full instructions ↗

Contributing

docs/developers/contributing.md

Thanks for your interest in improving UML-MCP. The full guidelines live in the repo root; this page summarises the most useful entry points.

DocumentWhy
CONTRIBUTING.mdLocal setup, branching model, commit and PR conventions.
CODE_OF_CONDUCT.mdCommunity expectations.
SECURITY.mdHow to responsibly report a security issue.
Read the full instructions ↗
Source documentation

17 documents read from 17 candidates.

Features and components 2

A quiet entry point
server.py delegates startup to mcp_core.core.server. It resolves the mcp object lazily through __getattr__, avoiding server construction and stdout output merely from importing the module. That matters when stdout carries the stdio protocol.
Transport and rendering
The server supports stdio and HTTP entry paths. The core groups tool registration, configuration and Kroki integration. Rendering is a downstream operation: the MCP layer describes tools and carries their inputs and results.

Architecture

The components and their connections remain available as text. The diagram adds an interactive view.

System context Context
  1. MCP client
  2. stdio or HTTP transport
  3. FastMCP tools and validation
  4. Kroki renderer
  5. Diagram result and links

Links verified in the repository.

Mermaid Interactive diagram (loads on open)

System overview of the components and connections verified in the repository.

Static architecture view for uml-mcp
Static preview. The interactive diagram replaces it after Mermaid loads.
flowchart LR

subgraph group_runtime["MCP Runtime"]
  node_mcp_server["MCP Server<br/>[server.py]"]
  node_diagram_tools["Diagram Tools<br/>[diagram_tools.py]"]
  node_plugin_loader["Plugin Loader<br/>[loader.py]"]
end

subgraph group_diagrams["Diagram Workflow"]
  node_validation["Input Validation"]
  node_diagram_service["Diagram Service<br/>[diagram_service.py]"]
  node_rendering["Diagram Rendering"]
  node_kroki["Kroki Renderers<br/>[kroki.py]"]
  node_render_cache["Render Cache<br/>[render_cache.py]"]
  node_delivery["Chat and Image Output<br/>[chat_packet.py]"]
  node_catalog["Diagram Catalog<br/>[diagram_catalog.py]"]
end

subgraph group_agent["Agent Interfaces"]
  node_prompts["Diagram Prompts<br/>[diagram_prompts.py]"]
  node_resources["Diagram Resources"]
  node_agui["AG-UI Events<br/>[agui.py]"]
end

subgraph group_admin["Admin Console"]
  node_admin_api["Admin API<br/>[routes.py]"]
  node_admin_settings["Settings Service"]
  node_kroki_admin["Kroki Playground<br/>[kroki_routes.py]"]
  node_console_ui["Admin Web Console<br/>[App.tsx]"]
end

subgraph group_operations["Security and Operations"]
  node_enterprise_auth["Bearer Authentication<br/>[mcp_auth.py]"]
  node_audit["Audit and Metrics<br/>[audit.py]"]
end

node_client(("AI Client"))
node_kroki_service["Kroki Service"]

node_client -->|"requests tools"| node_mcp_server
node_mcp_server -->|"registers tools"| node_diagram_tools
node_diagram_tools -->|"validates input"| node_validation
node_diagram_tools -->|"requests generation"| node_diagram_service
node_diagram_service -->|"generates diagram"| node_rendering
node_diagram_service -->|"reads and writes"| node_render_cache
node_rendering -->|"renders source"| node_kroki
node_kroki -.->|"sends render request"| node_kroki_service
node_diagram_service -->|"builds display output"| node_delivery
node_diagram_tools -->|"lists diagram types"| node_catalog
node_mcp_server -->|"registers prompts"| node_prompts
node_mcp_server -->|"registers resources"| node_resources
node_mcp_server -.->|"serves event interface"| node_agui
node_console_ui -.->|"uses console API"| node_admin_api
node_admin_api -->|"reads and saves"| node_admin_settings
node_admin_api -->|"adds Kroki routes"| node_kroki_admin
node_kroki_admin -->|"renders playground"| node_diagram_service
node_enterprise_auth -.->|"protects requests"| node_mcp_server
node_admin_api -->|"records operations"| node_audit
node_mcp_server -->|"loads plugins"| node_plugin_loader
node_plugin_loader -.->|"routes plugin types"| node_kroki


class node_mcp_server,node_diagram_tools,node_plugin_loader,node_client toneBlue
class node_validation,node_diagram_service,node_rendering,node_kroki,node_render_cache,node_delivery,node_catalog toneAmber
class node_prompts,node_resources,node_agui toneMint
class node_admin_api,node_admin_settings,node_kroki_admin,node_console_ui toneRose
class node_enterprise_auth,node_audit,node_kroki_service toneIndigo

An MCP server for diagram discovery, validation, rendering and delivery. Its runtime registers tools, prompts and resources, then routes source to renderers, caching and chat-friendly output; administration and observability form a separate operations path.

Components
21
Connections
21
Links supported by code or README
16/21
Text version of the diagram
  • MCP client → stdio or HTTP transport
  • stdio or HTTP transport → FastMCP tools and validation
  • FastMCP tools and validation → Kroki renderer
  • Kroki renderer → Diagram result and links
  • Diagram result and links → MCP client
Follow one path through the code

Start at server.py, follow main into mcp_core, then inspect the registered diagram tool before its renderer. A tool invocation supplies structured arguments; it does not make arbitrary prose valid Mermaid or PlantUML.

MCP tool contract

The hosted service accepts MCP JSON-RPC at /mcp. tools/list returns input and output schemas. A client sends tools/call with a tool name and structured arguments.

Request example
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "generate_uml",
    "arguments": {
      "diagram_type": "mermaid",
      "code": "flowchart LR\n  Client --> Server",
      "output_format": "svg"
    }
  }
}

Response and errors

Read result.structuredContent: success, url, playground and output_format describe the render. On failure, inspect error and error_detail; MCP protocol errors and tool-level isError must be handled separately. A URL response does not mean that image bytes are embedded in the reply.
Use validate_uml for syntax checks without a render. generate_uml_batch renders several items with per-item results. Send only public diagram text to the hosted service; renderer URLs can encode that text.
Authentication, limits and pagination

This public endpoint answered the documentation build without an Authorization header. That observation does not define authentication for every deployment. No fixed quota was advertised by tools/list. Rendering is a single-result operation; catalog discovery should follow MCP pagination if the server returns a cursor.

Service schema checked 2026-10-24 · MCP

Types and file structure

264 declared types, with 12 in the base-relationship overview.

Type diagram
classDiagram
direction TB
class t8c933d751656["_MCPAcceptHeaderMiddleware"] {
  __init__()
  __call__()
}
class tbbd7d80c6537["_MCPOriginValidationMiddleware"] {
  __init__()
  __call__()
}
class t633b66ae0a60["DiagramRequest"] {
  validate_code_length()
}
class tb2bc4a0b3d1b["DiagramResponse"] {
}
class t57c712c6e160["KrokiEncodeRequest"] {
}
class t3cbf0983a349["KrokiEncodeResponse"] {
}
class teae27f6a16b7["AguiRunRequest"] {
  _normalize_format()
}
class t32b0b600cbbf["AguiRunResponse"] {
}
class t3cbf9378a674["AguiProtocolRunInput"] {
}
class tb9167f0f3b08["D3Renderer"] {
  __init__()
  configure()
  validate()
  render()
}
class t69997369a348["ForceModel"] {
}
class t69a1ba4997d9["Provider"] {
}
class bda110f9bf6d7["BaseModel"] {
  <<unresolved_base>>
}
bda110f9bf6d7 <|-- t633b66ae0a60
bda110f9bf6d7 <|-- tb2bc4a0b3d1b
bda110f9bf6d7 <|-- t57c712c6e160
bda110f9bf6d7 <|-- t3cbf0983a349
bda110f9bf6d7 <|-- teae27f6a16b7
bda110f9bf6d7 <|-- t32b0b600cbbf
bda110f9bf6d7 <|-- t3cbf9378a674

Unresolved bases remain labelled; full signatures are not reconstructed.

Type index

Reference

297 / 297 eligible files read (706 in the tree); 0 oversized, 0 failed reads and 0 syntax diagnostics.

What the scan covers

Known dependency/build folders, credential files and binaries are excluded. The scan covers READMEs, recognized manifests and parser-supported source files.

Linguist statistics cover the whole repository and may include other languages.

File map
flowchart TD
  root["uml-mcp"]
  f0["README.md"]
  root --> f0
  f1["server.py"]
  root --> f1
  f2["mcp_core/core/server.py"]
  root --> f2
  f3["Makefile"]
  root --> f3
  f4["app.py"]
  root --> f4
  f5["docker-compose.yml"]
  root --> f5
  f6["pyproject.toml"]
  root --> f6
  f7[".plan/README.md"]
  root --> f7
  f8["api/app.py"]
  root --> f8
  f9["config/README.md"]
  root --> f9
  f10["examples/README.md"]
  root --> f10
  f11["examples/generate_example_files.py"]
  root --> f11
  f12["examples/generate_kroki_url.py"]
  root --> f12
  f13["examples/kroki_standalone_encoding.py"]
  root --> f13
  f14["examples/test_fallback.py"]
  root --> f14
  f15["frontend/eslint.config.js"]
  root --> f15

Files to read 3

References