Skip to content
Connect an agent
Workflows

import_source

Turns a file into a finished diagram in one call: a database schema, an API spec, infrastructure as code, manifests, a software catalog, a CI workflow, CSV or JSON data, a folder listing, or a git log. It is a workflow of the MCP server and the HTTP API, with the title "Import source".

TL;DR

QuestionAnswer
What is it?A workflow: one call does the work of several tools and returns one combined answer.
What does it do?Turns a file into a finished diagram in one call: a database schema, an API spec, infrastructure as code, manifests, a software catalog, a CI workflow, CSV or JSON data, a folder listing, or a git log.
What does it replace?validate_diagram and outline_diagram.
How do I call it over HTTP?POST /v1/import
Does it change anything?No. It is read-only and idempotent, and it talks to nothing outside itself. It saves no file and returns its answer as data.
Which bounds apply?maxImportLength, maxImportLocalLength, maxImportTextLength, maxImportFiles, maxImportLocalFiles, maxImportParts, maxImportNodes, maxImportTables, maxImportRows, maxImportColumns, maxImportPoints, maxImportSeries, maxImportEntries, maxImportCommits, maxImportMessages. See the bounds below.
Where do I read its schema as data?An MCP client gets the name, description, and JSON Schema of every tool from tools/list.

What it does

Workflow. Turns a file into a finished diagram in one call: a database schema, an API spec, infrastructure as code, manifests, a software catalog, a CI workflow, CSV or JSON data, a folder listing, or a git log. get_diagram_syntax with topic import-formats says what each format reads, draws, and takes. Prefer it to drawing by hand whenever the person has such a file: send its text, never a path, or every file of a folder in files. Returns the source, diagnostics pointing into the file for anything left out, coverage, parts (every diagram of a split file), the validation, an outline, viewUrl, and saveCommand. It runs no code and reads no file or URL. Replaces validate_diagram and outline_diagram.

Steps

OperationRunsWhat it does
importSourcealwaysRead a file of another format (SQL, Prisma, Drizzle, OpenAPI, Terraform, a Terraform plan or state, Bicep, ARM, Pulumi, CloudFormation, CDK, Compose, Kubernetes, Helm, Kustomize, Backstage, Structurizr, AsyncAPI, GitHub Actions, GitLab CI/CD, Azure Pipelines, CSV, JSON, a tree, or a git log) into Plotwork source.
validateonly when neededParse the source and lint it: every error, and the quality, icon, and group-type warnings.
outlineonly when neededDescribe a valid diagram as plain text.

One call performs at most 26 operations.

Example call

The arguments of the call, as JSON:

json
{  "format": "compose",  "text": "services:\n  api:\n    build: ./api\n    ports: [\"8080:8080\"]\n    depends_on: [db, cache]\n  db:\n    image: postgres:16\n  cache:\n    image: redis:7\n"}

The text argument, written out one line at a time:

text
services:  api:    build: ./api    ports: ["8080:8080"]    depends_on: [db, cache]  db:    image: postgres:16  cache:    image: redis:7

Prompts that lead to it

  • Draw our database schema from this SQL.
  • Make a diagram of this docker-compose file.
  • Which roles can call which endpoints in this OpenAPI spec?
  • Chart this CSV.

Arguments

FieldTypeRequiredDescription
format"sql" | "prisma" | "drizzle" | "openapi" | "terraform" | "terraform-plan" | "bicep" | "arm" | "pulumi" | "cloudformation" | "cdk" | "compose" | "kubernetes" | "helm" | "kustomize" | "backstage" | "structurizr" | "asyncapi" | "github-actions" | "gitlab-ci" | "azure-pipelines" | "csv" | "json" | "tree" | "git-log"yesWhat the text is; get_diagram_syntax with topic import-formats describes each.
textstringnoThe file content, as text. Send text or files, not both.
filesobject[]noThe files of a folder, for a format that spans files; the others read the first.
files[].pathstringyesThe file path, such as infra/network.tf; diagnostics name it. at least 1 character; at most 300 characters.
files[].textstringyesThe file content, as text.
titlestringnoThe diagram title; taken from the file when left out. at most 200 characters.
partsPageintegernoWhich page of parts to return when a split import has more than 24 diagrams: 1 (default) is the first 24. minimum 1; maximum 100000.
optionsobjectnodefault {}.
options.view"endpoints" | "map" | "sequence" | "git" | "timeline" | "context" | "container" | "component"noThe picture of a format drawn several ways.
options.operationIdstringnoopenapi sequence: the operation. at most 200 characters.
options.chart"auto" | "xychart" | "pie" | "sankey" | "treemap" | "matrix"nocsv, json: the chart; auto picks.
options.tablesstring[]noTables to draw, by name or prefix*.
options.pathsstring[]noopenapi: path prefixes to read.
options.tagsstring[]noopenapi: tags to read.
options.varFilesstring[]noVariables files to apply.
options.groupBy"module" | "network" | "file" | "owner"noHow things are framed; module is the default.
options.rootstringnoThe root, stack, or template of several to draw. at most 300 characters.

Result

FieldTypeRequiredDescription
okbooleanyesTrue when source is valid Plotwork source. False means nothing was imported and source is empty: read diagnostics.
kindstring | nullyesThe kind of diagram the file became, or null when nothing was imported.
formatstringyesThe format the text was read as.
sourcestringyesThe Plotwork source, or an empty string when nothing could be imported.
diagnosticsDiagnostic[]yesEverything left out, changed, or wrong, with a hint. Codes start with I and point into the text you sent: I1xx errors stopped the import, I2xx warnings did not.
diagnostics[].code"E100" | "E101" | "E110" | "E111" | "E120" | "E121" | "E122" | "E123" | "E124" | "E125" | "E130" | "E131" | "E132" | "E133" | "E134" | "E135" | "E136" | "E137" | "E138" | "E139" | "E140" | "W200" | "W201" | "W202" | "W203" | "W204" | "W205" | "W206" | "W207" | "W500" | "M100" | "M101" | "M102" | "M103" | "M104" | "M110" | "M200" | "M201" | "M202" | "M203" | "M204" | "M205" | "M206" | "M207" | "M208" | "M209" | "M210" | "M211" | "M212" | "M213" | "M214" | "M215" | "M216" | "M217" | "M218" | "E300" | "E301" | "E302" | "E303" | "E304" | "W300" | "W301" | "W302" | "W303" | "M120" | "M220" | "M221" | "M222" | "E340" | "E341" | "E342" | "E343" | "E344" | "E345" | "W320" | "W321" | "W322" | "W323" | "M240" | "M241" | "M242" | "E360" | "E361" | "E362" | "E363" | "E364" | "E365" | "E366" | "E367" | "W330" | "W331" | "W332" | "W333" | "W334" | "M250" | "M251" | "E400" | "E401" | "E402" | "E403" | "W350" | "W351" | "W352" | "W353" | "M270" | "M271" | "E420" | "E421" | "E422" | "E423" | "E424" | "W360" | "W361" | "W362" | "W363" | "W364" | "M180" | "M280" | "M281" | "M282" | "E320" | "E321" | "E322" | "E323" | "E324" | "E325" | "E326" | "E327" | "E328" | "E329" | "E330" | "W310" | "W311" | "W312" | "W313" | "W314" | "M130" | "M131" | "M132" | "M230" | "M231" | "M232" | "M233" | "M234" | "M235" | "M236" | "M237" | "M238" | "E380" | "E381" | "E382" | "E383" | "W340" | "W341" | "W342" | "W343" | "M260" | "I100" | "I101" | "I102" | "I103" | "I104" | "I105" | "I200" | "I201" | "I202" | "I203" | "I204" | "I206" | "R100" | "R101" | "R200" | "R201" | "R202" | "R203" | "R204" | "R205" | "R206" | "R207" | "S100" | "S200" | "S101" | "S102" | "S103" | "S104" | "S201" | "S202" | "S203"yesStable code to branch on; E-codes are errors, W-codes are warnings.
diagnostics[].severity"error" | "warning"yesErrors stop rendering; warnings never do.
diagnostics[].messagestringyesWhat is wrong, in one sentence.
diagnostics[].lineintegeryes1-based line in the submitted source. minimum 1.
diagnostics[].columnintegeryes1-based column in that line. minimum 1.
diagnostics[].lengthintegeryesNumber of characters the problem covers. minimum 1.
diagnostics[].hintstring | nullyesA concrete suggestion for fixing it, or null.
statsobjectyes
stats.itemsintegeryesBoxes, tables, rows, slices, places, entries, or commits written.
stats.linksintegeryesArrows, relations, messages, flows, or merges written.
stats.groupsintegeryesFrames, sections, or folders written.
stats.droppedintegeryesThings in the file left out by a cap or because the picture has no place for them; each is in diagnostics.
coverageobject | nullyesHow much of the file the picture shows; null when nothing was imported. When complete is false, the picture is not the whole file: say so.
validationobject | nullyesThe Plotwork validator run on source; null when nothing was imported.
partsobject[]yesWhen the file is too big for one readable picture, the diagrams it was split into, in order, at most 24 a page; source is the first diagram of all. Show or draw each of them. Empty when the import is one diagram.
parts[].titlestringyesWhat this diagram shows, such as one resource group or one tag of an API.
parts[].kindstringyesThe kind of diagram.
parts[].sourcestringyesThe Plotwork source of this diagram; draw it with draw_diagram.
parts[].itemsintegeryesThe boxes, rows, or entries it draws.
parts[].validbooleanyesTrue when the source has no Plotwork errors.
parts[].warningsDiagnostic[]yesPlotwork quality warnings of this diagram. Lines and columns point into its source.
parts[].warnings[].code"E100" | "E101" | "E110" | "E111" | "E120" | "E121" | "E122" | "E123" | "E124" | "E125" | "E130" | "E131" | "E132" | "E133" | "E134" | "E135" | "E136" | "E137" | "E138" | "E139" | "E140" | "W200" | "W201" | "W202" | "W203" | "W204" | "W205" | "W206" | "W207" | "W500" | "M100" | "M101" | "M102" | "M103" | "M104" | "M110" | "M200" | "M201" | "M202" | "M203" | "M204" | "M205" | "M206" | "M207" | "M208" | "M209" | "M210" | "M211" | "M212" | "M213" | "M214" | "M215" | "M216" | "M217" | "M218" | "E300" | "E301" | "E302" | "E303" | "E304" | "W300" | "W301" | "W302" | "W303" | "M120" | "M220" | "M221" | "M222" | "E340" | "E341" | "E342" | "E343" | "E344" | "E345" | "W320" | "W321" | "W322" | "W323" | "M240" | "M241" | "M242" | "E360" | "E361" | "E362" | "E363" | "E364" | "E365" | "E366" | "E367" | "W330" | "W331" | "W332" | "W333" | "W334" | "M250" | "M251" | "E400" | "E401" | "E402" | "E403" | "W350" | "W351" | "W352" | "W353" | "M270" | "M271" | "E420" | "E421" | "E422" | "E423" | "E424" | "W360" | "W361" | "W362" | "W363" | "W364" | "M180" | "M280" | "M281" | "M282" | "E320" | "E321" | "E322" | "E323" | "E324" | "E325" | "E326" | "E327" | "E328" | "E329" | "E330" | "W310" | "W311" | "W312" | "W313" | "W314" | "M130" | "M131" | "M132" | "M230" | "M231" | "M232" | "M233" | "M234" | "M235" | "M236" | "M237" | "M238" | "E380" | "E381" | "E382" | "E383" | "W340" | "W341" | "W342" | "W343" | "M260" | "I100" | "I101" | "I102" | "I103" | "I104" | "I105" | "I200" | "I201" | "I202" | "I203" | "I204" | "I206" | "R100" | "R101" | "R200" | "R201" | "R202" | "R203" | "R204" | "R205" | "R206" | "R207" | "S100" | "S200" | "S101" | "S102" | "S103" | "S104" | "S201" | "S202" | "S203"yesStable code to branch on; E-codes are errors, W-codes are warnings.
parts[].warnings[].severity"error" | "warning"yesErrors stop rendering; warnings never do.
parts[].warnings[].messagestringyesWhat is wrong, in one sentence.
parts[].warnings[].lineintegeryes1-based line in the submitted source. minimum 1.
parts[].warnings[].columnintegeryes1-based column in that line. minimum 1.
parts[].warnings[].lengthintegeryesNumber of characters the problem covers. minimum 1.
parts[].warnings[].hintstring | nullyesA concrete suggestion for fixing it, or null.
partsTotalintegeryesHow many diagrams the import was split into in all; 0 when it is one diagram.
partsPageintegeryesThe page of parts this answer holds, from 1.
partsPagesintegeryesHow many pages of parts there are; call again with partsPage for the next one.
outlinestring[]yesThe diagram as plain text, to check it says what the file says; empty when nothing was imported.
outlineTruncatedbooleanyesTrue when the outline was cut short at its summary length.
viewUrlstringnoA link that shows a valid diagram in a browser; give it to the person who wants to look. The source is in the part after #, never sent to a server, but anyone with the link can read it. Absent when too long; next says so.
pngUrlstringnoThe viewUrl with &download=png: opening it in a browser saves the diagram as a PNG for Slack, email, or a wiki. The PNG is drawn in the person's browser, not on a server, so it is a link to open, not an image address to embed. Absent when too long.
svgUrlstringnoThe viewUrl with &download=svg: a person opens it to download the SVG. Not a file address for curl; use saveCommand. Absent when too long.
saveCommandstringnoRun in a shell to save the SVG into the repository: the CLI decodes the link locally, fetches nothing, and embeds the source. Set --out to the path; add --theme dark for dark. Absent when too long.
nextstringyesThe next step in one sentence.

Behavior hints

HintValue
readOnlyHinttrue
destructiveHintfalse
idempotentHinttrue
openWorldHintfalse

Bounds

A bound that is reached is reported in the result; nothing is cut silently.

BoundValueWhat it limits
maxImportLength10000000Characters an import reads, not counting white space or lines that are only a comment. A longer text is answered with I102.
maxImportLocalLength100000000Characters of text in one call on the local server, which runs on your own machine. A guard on memory, not a cap a real project meets.
maxImportTextLength10485760Characters of text in one hosted call, comments and white space included, all files together.
maxImportFiles200Files in one hosted call.
maxImportLocalFiles20000Files in one call on the local server.
maxImportParts24Diagrams one import is split into when the file is too big for one picture; each is validated.
maxImportNodes40Boxes in an imported flow; the rest are left out with an I200 diagnostic.
maxImportTables20Tables in an imported schema.
maxImportRows20Rows of an imported matrix: endpoints, or rows of a table.
maxImportColumns8Columns of an imported matrix: roles, scopes, or schemes.
maxImportPoints60Places, slices, flows, or tiles in an imported chart.
maxImportSeries6Series in an imported XY chart.
maxImportEntries60Rows of an imported tree; a folder past it ends with an omitted line.
maxImportCommits40Commits of an imported git graph, the newest kept, and events of an imported timeline.
maxImportMessages30Messages of an imported sequence.

See also

DocWhy
Tool referenceEvery tool, with the workflows first
POST /v1/importThe same operation over HTTP
Language referenceWhat the diagram source may contain
Writing diagrams with an agentThe loop in practice