DXF drawings for AI agents: structured facts, PNG renders, and an interactive in-chat viewer.
io.github.frontsail-ai/aspicio β Model Context Protocol (MCP) Server
The io.github.frontsail-ai/aspicio MCP server provides DXF drawing support for AI agents. It exposes DXF content as structured facts, includes PNG renders, and supports an interactive in-chat viewer for examining drawings within the chat context.
π οΈ Key Features
DXF drawings for AI agents
Structured facts derived from drawings
PNG renders of drawings
Interactive in-chat viewer
π Use Cases
Supplying AI agents with structured information from DXF drawing data
Generating or providing image renderings (PNG) for inspection or downstream use
Reviewing DXF drawings via an in-chat interactive viewer
β‘ Developer Benefits
Consistent access to DXF-derived structured facts
Availability of rendered PNG outputs alongside structured data
In-chat visualization to support faster understanding of drawing content
Return a structured JSON summary of a DXF drawing β units, bounding box, layers (with the color actually drawn), per-type entity counts, the drawing's text content (title blocks and dimension values included), and any skipped/unsupported types. Use this to answer structural questions (what layers exist, how many parts, what size, what does it say) without rendering an image.
Parameters1
source
string
required
A publicly reachable http(s) URL to a .dxf file, or the DXF content inline as text. (This is a hosted server β local file paths are not available; use the npx @aspicio/mcp local server for files on disk.)
Raw schema
{
"type": "object",
"properties": {
"source": {
"type": "string",
"description": "A publicly reachable http(s) URL to a .dxf file, or the DXF content inline as text. (This is a hosted server β local file paths are not available; use the npx @aspicio/mcp local server for files on disk.)"
}
},
"required": [
"source"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
render_dxf
Render a DXF drawing to a PNG image you can look at. Use this to answer visual questions (what does it look like, where is a feature) β it returns an image, not text. For structural facts and measurements, prefer describe_dxf; never measure pixels. Some chat UIs do not display the returned image to the user: for URL sources the result also includes a direct image link β show it to the user (e.g. as a markdown image) when they need to see the render. When the user wants to see or explore the drawing themselves, prefer view_dxf (interactive viewer) β if your platform gates it behind user approval, offer it and ask rather than substituting a static render.
Parameters2
source
string
required
A publicly reachable http(s) URL to a .dxf file, or the DXF content inline as text. (This is a hosted server β local file paths are not available; use the npx @aspicio/mcp local server for files on disk.)
width
integer
optional
PNG width in pixels (default 1200)
Raw schema
{
"type": "object",
"properties": {
"source": {
"type": "string",
"description": "A publicly reachable http(s) URL to a .dxf file, or the DXF content inline as text. (This is a hosted server β local file paths are not available; use the npx @aspicio/mcp local server for files on disk.)"
},
"width": {
"description": "PNG width in pixels (default 1200)",
"type": "integer",
"minimum": 64,
"maximum": 4000
}
},
"required": [
"source"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
view_dxf
Open an interactive DXF viewer the user can pan, zoom, and toggle layers in (renders in-chat on MCP Apps-capable hosts). Use this when the user wants to see or explore the drawing themselves; for your own analysis use describe_dxf (facts) or render_dxf (image). The viewer shows only the drawing from this call. Delivery is handled by the widget itself: small drawings are embedded in the result and larger URL-sourced drawings are fetched by the widget through its own tool call β never re-fetch or inline the file for the viewer's sake, and don't blind-retry if the user reports an empty viewer (the viewer posts its actual status back to the conversation context).
Parameters2
source
string
required
A publicly reachable http(s) URL to a .dxf file, or the DXF content inline as text. (This is a hosted server β local file paths are not available; use the npx @aspicio/mcp local server for files on disk.)
allow_file_open
boolean
optional
Show open-file controls in the viewer (default false: viewer is locked to this drawing)
Raw schema
{
"type": "object",
"properties": {
"source": {
"type": "string",
"description": "A publicly reachable http(s) URL to a .dxf file, or the DXF content inline as text. (This is a hosted server β local file paths are not available; use the npx @aspicio/mcp local server for files on disk.)"
},
"allow_file_open": {
"description": "Show open-file controls in the viewer (default false: viewer is locked to this drawing)",
"type": "boolean"
}
},
"required": [
"source"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
load_dxf_for_viewer
Internal: returns DXF bytes (base64) for the in-chat viewer. Called by the widget, not the model.
Parameters3
source
string
required
http(s) URL of the DXF (same guards as the other tools)
offset
integer
optional
Byte offset of the requested range
length
integer
optional
Byte length of the requested range
Raw schema
{
"type": "object",
"properties": {
"source": {
"type": "string",
"description": "http(s) URL of the DXF (same guards as the other tools)"
},
"offset": {
"description": "Byte offset of the requested range",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"length": {
"description": "Byte length of the requested range",
"type": "integer",
"minimum": 1,
"maximum": 4000000
}
},
"required": [
"source"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
Aspicio is an open-source (MIT), TypeScript-first DXF engine: one
framework-free parse β tessellate pipeline that runs in the browser, in
Node, and in serverless runtimes. A person gets an interactive WebGL viewer
of a CAD drawing; an AI agent gets structured JSON facts and a rendered
PNG of the same file. Every surface β the browser viewer, the web
components and their React, Vue, and Svelte bindings, the headless
renderer, the HTTP API, and the MCP server β is a thin adapter over the same engine,
so a drawing is equally readable everywhere.
What you get: WebGL rendering batched to one draw call per layer (large
drawings stay interactive), broad entity coverage (lines, arcs, circles,
ellipses, polylines with bulges, splines, TEXT/MTEXT, DIMENSION,
SOLID/HATCH fills, nested INSERT blocks β anything unsupported is counted
and reported, never fatal), a layer list with the colors that are
actually drawn (per-entity overrides included, not just the layer
table), measure
with object snap, entity picking, paper-space layouts, SVG/PNG export,
and first-class touch. Out of scope: editing and 3D.
Hand it to an agent
The same engine speaks MCP and HTTP, so an agent can read a drawing
instead of guessing at it:
describe_dxf β units, bounds, size, layers with effective colors,
entity counts, and the drawing's text content. An agent reads a title
block or a dimension value directly β no OCR, no vision round-trip.
render_dxf β a PNG of the drawing the model can look at.
view_dxf (hosted server) β an interactive in-chat viewer for the
person in the conversation, via the open MCP Apps
extension:
pan, zoom, layer toggles, fullscreen, host light/dark theming. The
widget is locked to the drawing the tool call delivered and makes no
network requests; hosts without MCP Apps still get the structured
facts.
The in-chat viewer loading a 1.1 MB floor-plan DXF, toggling dimension and text layers, and expanding to fullscreen
Surface
Local files
URLs
Inline DXF
stdio MCP β npx -y @aspicio/mcp
β
β
β
Hosted MCP β aspicio-api.frontsail.app/mcp
β
β
β
HTTP API β /describe, /render
POST body
β
β
Connect:
Claude Code β one step installs the MCP server plus the bundled
skills (aspicio-inspect-dxf, aspicio-embed):
/plugin marketplace add frontsail-ai/aspicio then /plugin install aspicio@aspicio
Codex β the same repo doubles as a Codex marketplace:
codex plugin marketplace add https://github.com/frontsail-ai/aspicio,
codex plugin add aspicio@aspicio, then
codex mcp add aspicio -- npx -y @aspicio/mcp
Any client that launches stdio MCP servers β register
npx -y @aspicio/mcp
Any client that supports remote MCP (Streamable HTTP) β point it
at https://aspicio-api.frontsail.app/mcp (no install;
speaks MCP, not a browser page)
Plain HTTP β GET /describe?src=<dxf-url>,
GET /render?src=<dxf-url>&format=png|svg; the API self-describes at
/openapi.json
URL fetches are guarded (private-network blocking, size caps, redirect
validation, timeouts). The stdio server reads local files in-process and
never uploads the DXF to any Aspicio service β though, as with any tool
result, your MCP client passes the returned summary or image to its
model provider. Full details:
privacy policy Β·
terms.
Available today Β· direction
Everything above is shipped and live: viewer + demo, core, web
components, React, Vue, and Svelte packages, headless describe/render, stdio and hosted MCP, the in-chat
MCP Apps viewer, the HTTP API with OpenAPI, and plugin packaging for
Claude Code and Codex.
Direction (intent, not commitments β see
issues): MCP registry
listings, structured entity queries and focused rendering, and an
upload flow so remote surfaces can handle local files.
Standalone demo app (private) β also the reference integration
How the viewer packages fit together: every framework path funnels into
the same Lit web components β one implementation of the embed UI β which
sit on the framework-free core. React, Vue, and Svelte get thin veneers
with idiomatic props; plain HTML consumes the elements directly.
flowchart TD
REACTAPP["React app"]
HTMLAPP["Plain HTML / vanilla JS app"]
VUEAPP["Vue app"]
SVELTEAPP["Svelte app"]
REACT["<b>@aspicio/react</b><br/><DxfEmbed> Β· <DxfPreview> Β· <DxfLayerPanel><br/><i>thin @lit/react veneer, API-stable</i>"]
VUE["<b>@aspicio/vue</b><br/><DxfEmbed> Β· <DxfPreview> Β· <DxfLayerPanel><br/><i>thin Vue 3 veneer, typed emits</i>"]
SVELTE["<b>@aspicio/svelte</b><br/><DxfEmbed> Β· <DxfPreview> Β· <DxfLayerPanel><br/><i>raw Svelte 5 source, compiled by your bundler</i>"]
ELEMENTS["<b>@aspicio/elements</b><br/><aspicio-embed> Β· <aspicio-preview> Β· <aspicio-layer-panel><br/><i>Lit web components β the one embed-UI implementation</i>"]
CORE["<b>@aspicio/core</b><br/>parse β tessellate β render<br/><i>camera Β· input Β· picking Β· SVG/PNG export Β· headless describe</i>"]
REACTAPP -->|"idiomatic props, ref β DxfViewer"| REACT
REACT -->|"wraps"| ELEMENTS
HTMLAPP -->|"attributes + DOM events"| ELEMENTS
VUEAPP -->|"idiomatic props + emits"| VUE
VUE -->|"wraps"| ELEMENTS
SVELTEAPP -->|"typed callback props"| SVELTE
SVELTE -->|"wraps"| ELEMENTS
ELEMENTS -->|"drives"| CORE
HTMLAPP -.->|"or hand-rolled UI on the DxfViewer API"| CORE
classDef pkg fill:#191c22,stroke:#4c8dff,color:#e7e3da
classDef app fill:#1f232b,stroke:#3a3f4a,color:#9aa0ab
class REACT,VUE,SVELTE,ELEMENTS,CORE pkg
class REACTAPP,HTMLAPP,VUEAPP,SVELTEAPP app