AI assistants (MCP)
What it is
Drawbridge is an MCP server: any AI assistant that speaks the Model Context Protocol — Claude Code, Claude Desktop, and a growing list of others — can read your drawings, render them, and generate new ones, using the same importer, layout and routing the editor itself uses.
The split is deliberate: the assistant decides what connects to what; Drawbridge decides where the lines go. An assistant that already knows your topology — from configs, a CMDB, LLDP output — hands over the facts and gets back a presentation-ready, editable drawing instead of drawing boxes itself.
There are two doors onto the same three tools, and most people want the first one:
| Door | What it is |
|---|---|
| Hosted | A URL. Nothing installed, no account and no key — working in the next minute. |
| Local | Drawbridge --mcp on your own machine. Needs the desktop app, and the topology never leaves your network. |
Same protocol, same three tools, same drawings. The only difference is where the bytes go — so start with the hosted one, and move to the local one the day that distinction matters. The local door then carries five more tools on top, for joining a live collaboration session; the hosted one deliberately does not, for reasons given where they are described.
The hosted server
One line, and an assistant can draw:
claude mcp add --transport http drawbridge https://drawbridge.fortiknight.com/mcp
That is Claude Code. Every other client takes the same URL in its own configuration file — Claude Desktop, Cursor, Zed, VS Code and the rest read a variation of this:
{
"mcpServers": {
"drawbridge": {
"type": "http",
"url": "https://drawbridge.fortiknight.com/mcp"
}
}
}
Some clients spell that type as "streamable-http" and a few omit it entirely and infer it from url. They all mean the same thing. What none of them want is an SSE entry — see below.
Then prove it in one prompt: paste in the output of show cdp neighbors and ask for a PNG. That is a single create_diagram call, and a routed, laid-out diagram comes back.
What it is, exactly
Streamable HTTP, and stateless on purpose. One POST carries a JSON-RPC message and the answer comes straight back; there is no session to open and no session id to carry between calls. That is also why GET /mcp answers 405 rather than an event stream — a stateless server has no session state to stream. If a client hangs while connecting, it has been configured as an SSE server; the entry above is the HTTP/streamable one, and it is the only one this door speaks.
No account, no key, nothing stored. There is nothing to sign up for. A document you send is parsed, rendered, returned and then forgotten — never written to disk, never carried into a second request. The service keeps a record that a request happened and what it was asked to do — which capability, which export format, how long it took, which limit refused it — and never its content. The privacy page says the same thing, because it is the kind of promise that page exists to keep checkable.
The limits, in full. 2000 elements per drawing and 5 MB per request, both refused before anything is rendered, and a single render is killed at 60 seconds. There are no per-caller quotas — no requests-per-minute limit, no hourly render ceiling — so a long job is a long job. If a burst outruns the render fleet you get a 429 with Retry-After: 5, and retrying works, rather than a door that stays shut for an hour.
It is a beta, on a small fleet. Treat it as best effort: it carries no uptime promise, and the limits above are the ones still being tuned. If it is ever down, the local door below is the same three tools with nothing in between.
The local server
Point your MCP client at the installed desktop app with the --mcp argument. For Claude Desktop, that is one entry in its MCP configuration:
{
"mcpServers": {
"drawbridge": {
"command": "/Applications/Drawbridge.app/Contents/MacOS/Drawbridge",
"args": ["--mcp"]
}
}
}
On Windows the command is %LOCALAPPDATA%\Programs\Drawbridge\Drawbridge.exe; on Linux, the path to the AppImage (or /opt/Drawbridge/drawbridge from the .deb). The server speaks over its own stdin/stdout to the assistant that started it, needs no port and no configuration, and exits when the assistant closes it. Drawbridge does not have to be open — the assistant starts its own headless instance.
Nothing here reaches the network at all: the drawing goes to the assistant you configured and nowhere else, which is the whole of the difference from the hosted door.
Joining a live session
The local door carries five tools the hosted one does not. With them an assistant can join a collaboration session you are hosting and edit the diagram while you watch, instead of handing back a finished file you then have to ask it to redo.
- In Drawbridge, press Share… and start sharing.
- Copy the ordinary Invite link — not the view-only one — and give it to the assistant.
- It knocks; you press Allow in the lobby. It appears in People with a name and a colour, and everything it draws lands on your canvas as it happens.
The tools are collab_join (takes the invite and a name, then waits — up to two minutes — for you to admit it), collab_status, collab_read, collab_edit (add, update and remove devices and links, applied as a single change) and collab_leave. An editing invite is required, and a view-only one is refused in words rather than accepted and then silently ignored. Kick works on the assistant exactly as it does on a person, and closing the assistant drops the connection like closing a window. Working together covers the same feature from the host's side of the screen.
The hosted server does not carry these five tools, and that is deliberate. Joining a session means holding the invite secret and sitting in the path of every edit — and that secret is a password to your diagram. On the local door it never leaves your machine; a hosted joiner would put our servers in the middle of a session that is otherwise only ever between the people in it, which is the one thing the privacy page exists to promise against.
Local models
Nothing about the loop requires a cloud assistant — the tools work with any model runner that speaks MCP, and a local model beside a local Drawbridge keeps the whole pipeline on your machine.
LM Studio supports MCP natively (0.3.17 or later): add the same entry as
above to its mcp.json (Program, then Install, then Edit mcp.json) and the
tools appear in the chat's tool list. Pick a model that handles tool calling
well — instruct-tuned models of about 8B and up behave; very small models
call tools erratically.
Ollama is an OpenAI-compatible server rather than an MCP client, so put a
small bridge in front. With mcphost:
# ~/.mcphost.yml
mcpServers:
drawbridge:
command: /Applications/Drawbridge.app/Contents/MacOS/Drawbridge
args: ['--mcp']
mcphost -m ollama:qwen2.5:14b
Your own loop. An MCP client is small enough to write yourself: list the
tools, offer them to the model as functions, execute what it calls, feed the
results back. The mcp Python SDK provides the client half; any
OpenAI-compatible endpoint provides the model half.
No MCP at all. A runner that can only make plain HTTP calls uses the same
handlers over REST instead — locally with Drawbridge --serve, or against the
hosted API at https://drawbridge.fortiknight.com/api/, which is the same
service and the same limits as the MCP door above.
Code in, image out covers both.
Prompts that use the tools well: hand over show cdp neighbors output and
ask for a PNG (one create_diagram call); attach a drawing and ask which
devices have only one uplink (describe, then the model reasons over the
JSON); or ask it to create from CSV and then describe what it created — the
round trip catches import surprises.
The tools
describe — Read a Drawbridge/draw.io network diagram and return its contents as structured JSON: devices, links, pages and layers — for auditing or querying an existing drawing. Results carry name: a suggested basename for this diagram. Write every file for one diagram into its own directory named after it —
document— The .drawio document as XML text.
export — Render a Drawbridge/draw.io network diagram to an output format (svg, png, drawio, dot, csv, netbox.csv, describe.json). Returns the exported content. CHOOSING kind: drawio when the user will open or edit the drawing (this is usually what they want, and it is the only one they can change); svg to embed in a document or a page; png to show inline in a chat; describe.json to READ a drawing back and reason about it; csv / netbox.csv for a cable schedule; dot to hand the topology on. Results carry name: a suggested basename for this diagram. Write every file for one diagram into its own directory named after it —
document— The .drawio document as XML text.kind(optional) — Output format. Defaults to svg.theme(optional) — Render theme. Omit to follow the OS appearance; pin it for machine-independent output.name(optional) — Basename to use for this diagram instead of the one derived from its content. Slugified; wins over the document’s own name.
create_diagram — Generate a routed, laid-out network diagram from topology text (Graphviz DOT, CDP/LLDP neighbor output, or CSV) and export it. Drawbridge decides where the lines go; you decide what connects to what. HOW TO GET A PRECISE RESULT: Set kind= on EVERY device so it draws as the real thing rather than a neutral box (firewall, waf, ips, vpn-gateway, proxy, nac, router, switch, l3-switch, load-balancer, wifi-ap, wlc, … — full list in the drawbridge://guide resource). Put speed= on every cable ("10G", "1G"), and link= where the cable MEANS something (ipsec, trunk, lag, wan, mgmt, wireless, conduit, fieldbus). Never set pos=, width= or height=: Drawbridge lays out and routes — placing devices yourself is what makes a diagram look generated. READ THE notes IN THE RESULT AND FIX YOUR SOURCE: they name each line that was skipped or adjusted, and an unrecognised kind silently becomes a plain box otherwise. Iterate until the notes are empty. CHOOSING kind: drawio when the user will open or edit the drawing (this is usually what they want, and it is the only one they can change); svg to embed in a document or a page; png to show inline in a chat; describe.json to READ a drawing back and reason about it; csv / netbox.csv for a cable schedule; dot to hand the topology on. Results carry name: a suggested basename for this diagram. Write every file for one diagram into its own directory named after it —
source— Topology text: Graphviz DOT, CDP/LLDP neighbor output, or CSV.kind(optional) — Output format. Defaults to svg.theme(optional) — Render theme. Omit to follow the OS appearance; pin it for machine-independent output.name(optional) — Basename to use for this diagram instead of the one derived from its content. Slugified; wins over the document’s own name.
What the assistant is told about drawing well
The tools do not only state their arguments; they say how to use the product. create_diagram's description tells an assistant the four things that decide whether the drawing is any good — set kind= on every device so it draws as the real symbol instead of a neutral box, put speed= and link= on the cables, never write positions because layout and routing are the product, and read the importer's notes and fix the source until they come back empty.
It does not wait to be asked, either. The server answers the opening handshake with instructions — what Drawbridge is for, which tool to reach for, and the two rules that decide whether the drawing is any good. Clients put that in front of the assistant before it has chosen to call anything, which is earlier than a tool description is read and much earlier than a resource.
The long form is served as MCP resources, fetched when an assistant wants them. drawbridge://guide: the device kinds, the whole DOT attribute profile that matters, a worked example, and which export format answers which question. A client that supports resources can fetch it when it wants it, so the assistants that need it get everything and the ones that do not are not charged for it on every connection.
And drawbridge://kinds carries the whole device vocabulary — all of it, grouped by family, each entry listing the other names it answers to. That is the one thing the short guidance cannot hold: it names the thirty-odd kinds a drawing usually reaches for, while the catalog has a hundred. An assistant whose user asks for a data diode, a protection relay or a bastion host can look up the kind that draws it instead of settling for a plain box.
Every device kind named in any of it is generated from the real catalog and checked by a test, because guidance that has drifted is worse than none — it teaches an assistant to write DOT that quietly imports as a plain box.
Where the files go
The server never writes a file. Every tool answers with content — the JSON, the SVG, the PNG bytes — and your assistant decides what to save and where. That is deliberate: a hosted caller has no filesystem to point into, and a tool that writes to disk on your behalf is a tool you have to trust with a path.
The cost of that was a heap. Ask for two topologies in one session and you get fourteen files with three naming schemes between them, all in whatever directory the assistant happened to be in.
So every result now carries a name — a suggested basename, taken from what the diagram calls itself (a page name, or the digraph name in your DOT), or from the name you pass. It is a slug, never a path. The convention it exists for is stated to the assistant in the tool descriptions, and it is this:
One directory per diagram, every file for that diagram named after it.
DrawBridge/
datacentre/
datacentre.drawio
datacentre.svg
datacentre.png
datacentre.describe.json
datacentre.cables.csv
fortinet/
fortinet.drawio
…
Two diagrams then never share a directory, and asking for the same one twice overwrites its own files rather than growing a second set beside them. If your assistant ignores the suggestion, tell it to follow the convention in the tool description — or pass name yourself and it has nothing left to invent.
Over the REST door the same slug comes back in the x-drawbridge-name response header, on every route including describe, because those routes answer with the bytes themselves and there is no envelope to put it in.
describe is the read side: it answers with the same structured JSON the CLI's .describe.json export produces — see Code in, image out for the shape and for jq recipes that work identically on a tool result. create_diagram accepts everything Import accepts (Graphviz DOT with the full attribute profile, CDP/LLDP output, CSV), and its result carries the importer's notes, so an assistant sees what it got wrong and can fix its own DOT.
What the assistant sees
Whichever door you use, the same boundary opens, and it is worth being clear-eyed about it: a drawing you let an assistant describe, and a topology you ask it to draw, are handed to that assistant — and so to whoever runs it. That is your choice to make, per assistant, and nothing crosses until you configure a client and ask it to use these tools.
Locally that is the only boundary there is. Drawbridge --mcp makes no network call of its own — the standing rule that update checks are the app's only network traffic survives it untouched.
The hosted door adds exactly one more party and nothing else: the document reaches the render service, is drawn, is returned, and is forgotten — never stored, never used for anything but answering that one request. The privacy page states both boundaries in the same words, because they are the kind of promise that page exists to keep checkable.