Flowgraf
Create and edit architecture diagrams from your AI agent; get an SVG and a live editable canvas.
Should I use this
Quality & Safety
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"flowgraf": {
"command": "npx",
"args": [
"flowgraf-mcp"
]
}
}
}Runnable packages
0.1.2stdioRemote endpoints
https://flowgraf.in/api/mcpstreamable-httpWhat it can do
Tool inventory
Tools (3)
π‘create_diagram(title, graph, domain)
Create a NEW architecture diagram from a graph that YOU author, and get back a shareable, editable canvas URL plus a rendered SVG and Mermaid. You produce only the SEMANTICS β nodes, the groups (VPC/cluster/...) they live in, and the directed edges between them. You do NOT lay anything out: never send x/y/position/pinned. A deterministic layout engine computes all geometry and an icon layer picks the pictures from each node's kind. kind.catalog is one of aws | gcp | azure | k8s | saas | generic, each with rich per-catalog kind.types (e.g. aws:lambda, gcp:bigquery, azure:cosmos_db, k8s:deployment, saas:kafka): - "aws" (api_gateway, lambda, s3, rds, dynamodb, sqs, bedrock, kinesis, fargate, eventbridge, aurora, ...). - "gcp" (compute_engine, gke, cloud_run, cloud_sql, spanner, firestore, bigquery, pubsub, dataflow, vertex_ai, ...). - "azure" (virtual_machine, aks, app_service, functions, blob_storage, sql_database, cosmos_db, service_bus, event_hubs, key_vault, ...). - "k8s" (pod, deployment, statefulset, daemonset, job, cronjob, service, ingress, configmap, secret, hpa, ...). - "saas" for hosted third-parties (redis, postgresql, mysql, mongodb, kafka, stripe, twilio, auth0, github, cloudflare, ...). - "generic" primitive when nothing branded fits: service, database, cache, queue, user, external_system, storage, gateway, function, note. - "generic" FLOWCHART kinds for processes/flowcharts: process, decision, terminator, data, document, subprocess. edge.kind is one of: request, response, async_event, data_flow, dependency, network, generic. WORKED EXAMPLE β a user hitting an API in a VPC that talks to Postgres: { "title": "Web API", "domain": "cloud_architecture", "graph": { "groups": [{ "id": "g_vpc", "label": "VPC", "type": "vpc" }], "nodes": [ { "id": "n_user", "label": "User", "kind": { "catalog": "generic", "type": "user" } }, { "id": "n_api", "label": "API", "kind": { "catalog": "aws", "type": "api_gateway" }, "parentId": "g_vpc" }, { "id": "n_db", "label": "Postgres", "kind": { "catalog": "aws", "type": "rds" }, "parentId": "g_vpc" } ], "edges": [ { "id": "e1", "source": "n_user", "target": "n_api", "kind": "request" }, { "id": "e2", "source": "n_api", "target": "n_db", "kind": "data_flow" } ] } } Returns { diagramId, url, svg, mermaid, version }. Give the user the url β opening it shows the same diagram on an editable canvas (anonymous; it's theirs to claim by signing in). To change the diagram afterwards, use get_diagram then edit_diagram.
Input Schema
{
"type": "object",
"properties": {
"title": {
"type": "string",
"minLength": 1,
"description": "A short title for the diagram."
},
"graph": {
"type": "object",
"properties": {
"nodes": {
"description": "The nodes (services, databases, users, ...).",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "Stable snake_case id you assign, e.g. n_api. Referenced by edges."
},
"label": {
"type": "string",
"description": "Human label shown on the node, e.g. 'API Gateway'."
},
"kind": {
"type": "object",
"properties": {
"catalog": {
"type": "string",
"enum": [
"aws",
"gcp",
"azure",
"k8s",
"saas",
"generic"
]
},
"type": {
"type": "string",
"minLength": 1,
"description": "Catalog-specific type, e.g. api_gateway, rds, redis, service."
}
},
"required": [
"catalog",
"type"
],
"additionalProperties": false
},
"parentId": {
"description": "id of the group this node lives in (a VPC, cluster, ...).",
"type": "string",
"minLength": 1
}
},
"required": [
"id",
"label",
"kind"
],
"additionalProperties": false
}
},
"groups": {
"description": "Containers that nodes live in (VPCs, clusters, ...).",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "Stable snake_case id you assign, e.g. g_vpc."
},
"label": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"vpc",
"subnet",
"availability_zone",
"region",
"cluster",
"trust_boundary",
"logical"
]
},
"parentId": {
"description": "id of the parent group, for nested containers.",
"type": "string",
"minLength": 1
},
"style": {
"type": "object",
"properties": {
"color": {
"type": "string"
},
"dashed": {
"type": "boolean"
}
},
"additionalProperties": false
}
},
"required": [
"id",
"label",
"type"
],
"additionalProperties": false
}
},
"edges": {
"description": "Directed connections between node ids.",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"source": {
"type": "string",
"minLength": 1,
"description": "id of the source node."
},
"target": {
"type": "string",
"minLength": 1,
"description": "id of the target node."
},
"kind": {
"type": "string",
"enum": [
"request",
"response",
"async_event",
"data_flow",
"dependency",
"network",
"generic"
]
},
"label": {
"type": "string"
},
"directed": {
"type": "boolean"
}
},
"required": [
"id",
"source",
"target",
"kind"
],
"additionalProperties": false
}
}
},
"additionalProperties": false
},
"domain": {
"description": "Optional domain hint (default: generic).",
"type": "string",
"enum": [
"cloud_architecture",
"system_design",
"sequence",
"flow",
"generic"
]
}
},
"required": [
"title",
"graph"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}π΄edit_diagram(diagramId, baseVersion, ops)
Apply a list of operations to an EXISTING diagram. The ops re-use this tool's op vocabulary; you author them, we validate + apply + re-layout + re-render. ALWAYS call get_diagram(diagramId) first: it returns the current ids and the `version`. Pass that version as `baseVersion`. If the diagram changed since you fetched it, you get a STALE_VERSION error telling you the current version β refetch with get_diagram, recompute your ops, and retry. The operations (each element of `ops`): - add_node { op, node:{ id, label, kind, parentId? } } - remove_node { op, id } (also drops edges touching the node) - update_node { op, id, patch:{ label?, kind?, parentId?, metadata? } } - add_edge { op, edge:{ id, source, target, kind, label?, directed? } } - remove_edge { op, id } - update_edge { op, id, patch:{ source?, target?, label?, kind?, directed? } } - add_group { op, group:{ id, label, type, parentId? } } - remove_group{ op, id } - move_to_group { op, nodeId, groupId } (groupId null un-nests the node) - set_layout { op, patch:{ direction?, spacing? } } - insert_between { op, newNode:{ id, label, kind, parentId? }, sourceId, targetId, inKind?, outKind? } insert_between IS THE KEY OP for "add X between A and B" requests. It splices newNode onto the existing AβB edge: removes that edge, adds the node, and wires AβnewNodeβB so the connection re-routes through it automatically. WORKED EXAMPLE β "add a Redis cache between the API and the DB" on the diagram above: 1) get_diagram(diagramId) β shows nodes n_api, n_db and version 1. 2) edit_diagram({ diagramId, baseVersion: 1, ops: [ { "op": "insert_between", "sourceId": "n_api", "targetId": "n_db", "newNode": { "id": "n_redis", "label": "Redis", "kind": { "catalog": "saas", "type": "redis" }, "parentId": "g_vpc" }, "inKind": "request", "outKind": "data_flow" } ] }) The APIβDB edge is gone and now flows APIβRedisβDB. Never send x/y/position β geometry is computed for you. Node kinds: catalog β {aws, gcp, azure, k8s, saas, generic} with rich per-catalog types (e.g. aws:lambda, gcp:bigquery, azure:cosmos_db, k8s:deployment, saas:kafka), plus generic flowchart kinds (process, decision, terminator, data, document, subprocess). Returns { url, svg, mermaid, appliedOps, version }.
Input Schema
{
"type": "object",
"properties": {
"diagramId": {
"type": "string",
"minLength": 1,
"description": "The diagram to edit (from create_diagram or get_diagram)."
},
"baseVersion": {
"type": "integer",
"minimum": 1,
"maximum": 9007199254740991,
"description": "The version you are editing against β get it from get_diagram. Stale β STALE_VERSION."
},
"ops": {
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "add_node"
},
"node": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"label": {
"type": "string",
"maxLength": 512
},
"kind": {
"type": "object",
"properties": {
"catalog": {
"type": "string",
"enum": [
"aws",
"gcp",
"azure",
"k8s",
"saas",
"generic"
]
},
"type": {
"type": "string",
"minLength": 1,
"maxLength": 512
}
},
"required": [
"catalog",
"type"
],
"additionalProperties": false
},
"parentId": {
"type": "string",
"minLength": 1
},
"metadata": {
"type": "object",
"propertyNames": {
"type": "string",
"maxLength": 256
},
"additionalProperties": {}
},
"style": {
"type": "object",
"properties": {
"fill": {
"type": "string",
"enum": [
"gray",
"slate",
"blue",
"teal",
"green",
"amber",
"orange",
"red",
"pink",
"violet"
]
},
"border": {
"type": "string",
"enum": [
"gray",
"slate",
"blue",
"teal",
"green",
"amber",
"orange",
"red",
"pink",
"violet"
]
},
"textSize": {
"type": "string",
"enum": [
"s",
"m",
"l"
]
},
"bold": {
"type": "boolean"
}
},
"additionalProperties": false
}
},
"required": [
"id",
"label",
"kind"
],
"additionalProperties": false
}
},
"required": [
"op",
"node"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "remove_node"
},
"id": {
"type": "string",
"minLength": 1
}
},
"required": [
"op",
"id"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "update_node"
},
"id": {
"type": "string",
"minLength": 1
},
"patch": {
"type": "object",
"properties": {
"label": {
"type": "string",
"maxLength": 512
},
"kind": {
"type": "object",
"properties": {
"catalog": {
"type": "string",
"enum": [
"aws",
"gcp",
"azure",
"k8s",
"saas",
"generic"
]
},
"type": {
"type": "string",
"minLength": 1,
"maxLength": 512
}
},
"required": [
"catalog",
"type"
],
"additionalProperties": false
},
"parentId": {
"type": "string",
"minLength": 1
},
"metadata": {
"type": "object",
"propertyNames": {
"type": "string",
"maxLength": 256
},
"additionalProperties": {}
},
"style": {
"type": "object",
"properties": {
"fill": {
"type": "string",
"enum": [
"gray",
"slate",
"blue",
"teal",
"green",
"amber",
"orange",
"red",
"pink",
"violet"
]
},
"border": {
"type": "string",
"enum": [
"gray",
"slate",
"blue",
"teal",
"green",
"amber",
"orange",
"red",
"pink",
"violet"
]
},
"textSize": {
"type": "string",
"enum": [
"s",
"m",
"l"
]
},
"bold": {
"type": "boolean"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
},
"required": [
"op",
"id",
"patch"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "add_edge"
},
"edge": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"source": {
"type": "string",
"minLength": 1
},
"target": {
"type": "string",
"minLength": 1
},
"label": {
"type": "string",
"maxLength": 512
},
"kind": {
"type": "string",
"enum": [
"request",
"response",
"async_event",
"data_flow",
"dependency",
"network",
"generic"
]
},
"directed": {
"type": "boolean"
},
"style": {
"type": "object",
"properties": {
"color": {
"type": "string",
"enum": [
"gray",
"slate",
"blue",
"teal",
"green",
"amber",
"orange",
"red",
"pink",
"violet"
]
},
"width": {
"type": "string",
"enum": [
"thin",
"normal",
"thick"
]
},
"textSize": {
"type": "string",
"enum": [
"s",
"m",
"l"
]
},
"bold": {
"type": "boolean"
}
},
"additionalProperties": false
}
},
"required": [
"id",
"source",
"target",
"kind"
],
"additionalProperties": false
}
},
"required": [
"op",
"edge"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "remove_edge"
},
"id": {
"type": "string",
"minLength": 1
}
},
"required": [
"op",
"id"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "update_edge"
},
"id": {
"type": "string",
"minLength": 1
},
"patch": {
"type": "object",
"properties": {
"source": {
"type": "string",
"minLength": 1
},
"target": {
"type": "string",
"minLength": 1
},
"label": {
"type": "string",
"maxLength": 512
},
"kind": {
"type": "string",
"enum": [
"request",
"response",
"async_event",
"data_flow",
"dependency",
"network",
"generic"
]
},
"directed": {
"type": "boolean"
},
"style": {
"type": "object",
"properties": {
"color": {
"type": "string",
"enum": [
"gray",
"slate",
"blue",
"teal",
"green",
"amber",
"orange",
"red",
"pink",
"violet"
]
},
"width": {
"type": "string",
"enum": [
"thin",
"normal",
"thick"
]
},
"textSize": {
"type": "string",
"enum": [
"s",
"m",
"l"
]
},
"bold": {
"type": "boolean"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
},
"required": [
"op",
"id",
"patch"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "add_group"
},
"group": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"label": {
"type": "string",
"maxLength": 512
},
"type": {
"type": "string",
"enum": [
"vpc",
"subnet",
"availability_zone",
"region",
"cluster",
"trust_boundary",
"logical"
]
},
"parentId": {
"type": "string",
"minLength": 1
},
"style": {
"type": "object",
"properties": {
"color": {
"type": "string",
"enum": [
"gray",
"slate",
"blue",
"teal",
"green",
"amber",
"orange",
"red",
"pink",
"violet"
]
},
"dashed": {
"type": "boolean"
}
},
"additionalProperties": false
}
},
"required": [
"id",
"label",
"type"
],
"additionalProperties": false
}
},
"required": [
"op",
"group"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "remove_group"
},
"id": {
"type": "string",
"minLength": 1
}
},
"required": [
"op",
"id"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "update_group"
},
"id": {
"type": "string",
"minLength": 1
},
"patch": {
"type": "object",
"properties": {
"label": {
"type": "string",
"maxLength": 512
},
"type": {
"type": "string",
"enum": [
"vpc",
"subnet",
"availability_zone",
"region",
"cluster",
"trust_boundary",
"logical"
]
},
"style": {
"type": "object",
"properties": {
"color": {
"type": "string",
"enum": [
"gray",
"slate",
"blue",
"teal",
"green",
"amber",
"orange",
"red",
"pink",
"violet"
]
},
"dashed": {
"type": "boolean"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
},
"required": [
"op",
"id",
"patch"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "move_to_group"
},
"nodeId": {
"type": "string",
"minLength": 1
},
"groupId": {
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
}
},
"required": [
"op",
"nodeId",
"groupId"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "set_layout"
},
"patch": {
"type": "object",
"properties": {
"engine": {
"type": "string",
"enum": [
"elk",
"dagre"
]
},
"direction": {
"type": "string",
"enum": [
"TB",
"LR",
"BT",
"RL"
]
},
"spacing": {
"type": "object",
"properties": {
"node": {
"type": "number",
"minimum": 0,
"maximum": 10000
},
"layer": {
"type": "number",
"minimum": 0,
"maximum": 10000
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
},
"required": [
"op",
"patch"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "set_theme"
},
"patch": {
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": [
"light",
"dark",
"blueprint"
]
},
"background": {
"type": "string",
"enum": [
"dots",
"grid",
"plain"
]
},
"styleMode": {
"type": "string",
"enum": [
"plain",
"shadow"
]
}
},
"additionalProperties": false
}
},
"required": [
"op",
"patch"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "set_title"
},
"title": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
},
"required": [
"op",
"title"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"op": {
"type": "string",
"const": "insert_between"
},
"newNode": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"label": {
"type": "string",
"maxLength": 512
},
"kind": {
"type": "object",
"properties": {
"catalog": {
"type": "string",
"enum": [
"aws",
"gcp",
"azure",
"k8s",
"saas",
"generic"
]
},
"type": {
"type": "string",
"minLength": 1,
"maxLength": 512
}
},
"required": [
"catalog",
"type"
],
"additionalProperties": false
},
"parentId": {
"type": "string",
"minLength": 1
},
"metadata": {
"type": "object",
"propertyNames": {
"type": "string",
"maxLength": 256
},
"additionalProperties": {}
},
"style": {
"type": "object",
"properties": {
"fill": {
"type": "string",
"enum": [
"gray",
"slate",
"blue",
"teal",
"green",
"amber",
"orange",
"red",
"pink",
"violet"
]
},
"border": {
"type": "string",
"enum": [
"gray",
"slate",
"blue",
"teal",
"green",
"amber",
"orange",
"red",
"pink",
"violet"
]
},
"textSize": {
"type": "string",
"enum": [
"s",
"m",
"l"
]
},
"bold": {
"type": "boolean"
}
},
"additionalProperties": false
}
},
"required": [
"id",
"label",
"kind"
],
"additionalProperties": false
},
"sourceId": {
"type": "string",
"minLength": 1
},
"targetId": {
"type": "string",
"minLength": 1
},
"inKind": {
"type": "string",
"enum": [
"request",
"response",
"async_event",
"data_flow",
"dependency",
"network",
"generic"
]
},
"outKind": {
"type": "string",
"enum": [
"request",
"response",
"async_event",
"data_flow",
"dependency",
"network",
"generic"
]
}
},
"required": [
"op",
"newNode",
"sourceId",
"targetId"
],
"additionalProperties": false
}
]
}
}
},
"required": [
"diagramId",
"baseVersion",
"ops"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}π‘get_diagram(diagramId)
Fetch a diagram's raw IR (nodes, groups, edges with their real ids) and its current `version`. Call this before edit_diagram so your ops reference ids that actually exist and you pass the correct baseVersion. Returns { diagram, version }.
Input Schema
{
"type": "object",
"properties": {
"diagramId": {
"type": "string",
"minLength": 1,
"description": "The diagram to fetch."
}
},
"required": [
"diagramId"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}Community
Evidence