Aspicio

io.github.frontsail-aiPublished by GitHub account frontsail-aiv0.13.2Updated Oct 30, 2026

DXF and PDF/X-4 for AI agents: structured facts, PNG renders, an interactive in-chat viewer.

VerifiedStreamable HTTPWeb executableFiles & StorageMedia & Design

Overview

AI-generated overview

Reads DXF and vector PDF drawings for an assistant: structured JSON facts (units, bounds, layers, entity counts, text) plus PNG renders.

What you can do
  • Describe a DXF drawing: units, bounding box, layers with effective colors, entity counts, text content, skipped types
  • Render a DXF drawing to a PNG image the model can look at
  • Describe a PDF drawing: units, bounds, layers, entity counts, contained text, and what was skipped
  • Render a PDF drawing's vector content (line work and text) to a PNG
  • Describe or render a drawing in any supported format, detected from its bytes rather than its file name
  • Scope describe and render to a named space, such as a PDF page or a DXF layout
When to use it
Useful when a conversation involves CAD or technical drawings and the assistant needs to answer structural questions (layers, sizes, part counts, title-block text) or look at the drawing, without OCR or a vision round-trip.
Requirements
Either the hosted remote endpoint over Streamable HTTP, or a local stdio process run with npx from the npm package, which needs Node.js. No accounts, API keys or environment variables are declared. The hosted endpoint accepts URLs and inline DXF but not local files; the stdio server can read local files.
Before you install
The stdio server reads local files in-process and does not upload them to the vendor, but tool results (summaries and images) are passed by the MCP client to its model provider. The hosted endpoint fetches URLs you give it, with private-network blocking and size caps. Rendering is read-only; editing and 3D are out of scope, and PDF renders omit images, shadings and transparency.

Installation

In SourceWeft

  1. Open Aspicio in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/io.github.frontsail-ai%2Faspicio/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "aspicio": {
      "type": "http",
      "url": "https://aspicio-api.frontsail.app/mcp"
    }
  }
}

README

[Aspicio logo]

Aspicio

Drawing understanding for people, applications, and AI agents — DXF and vector PDF.

Aspicio (Latin: "I look at")

[CI] [License: MIT]
[npm: @aspicio/core] [npm: @aspicio/elements] [npm: @aspicio/react] [npm: @aspicio/vue] [npm: @aspicio/svelte] [npm: @aspicio/mcp]
[Aspicio MCP on mcprush]

▶ Live demo

Aspicio is an open-source (MIT), TypeScript-first drawing engine: one framework-free parse → tessellate pipeline that runs in the browser, in Node, and in serverless runtimes. It reads DXF and the vector content of PDF — the kind of PDF that carries artwork and dielines rather than a scan. 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.

DXF / PDF bytes ─parse─▶ DrawingDocument ─tessellate─▶ Tessellation ──┬─▶ WebGL renderer (viewer)                        (normalized model)   (batched geometry)       ├─▶ SVG string (export / API / MCP)                                                                      └─▶ DrawingSummary (describe)

How it's built: docs/architecture.md · behavior specs: docs/product-specs/

[Aspicio viewing a sample floor-plan DXF — layer panel, colored geometry, text, and a dimension]

Embed it

One embed, every flavor — and every path below renders the same web components, so the result is pixel-identical no matter which you pick.

Web components — plain HTML, any framework

One tag gives you the layer panel plus an interactive preview; no bindings needed:

html
<script type="module">  import "@aspicio/elements";  import "@aspicio/elements/formats/dxf";</script>
<aspicio-embed src-url="/drawing.dxf" style="height: 480px"></aspicio-embed>

Formats are opted into by import: the package brings the components, the formats/* entry brings the parser. That is what keeps a DXF app from shipping every other format's code — and every flavor below does the same.

React

The same embed with idiomatic props and a ref exposing the full viewer, via @aspicio/react:

tsx
import { AspicioEmbed } from "@aspicio/react";import "@aspicio/react/formats/dxf";
<AspicioEmbed src={file} style={{ height: 480 }} />;

Vue

Typed props and emits with unwrapped payloads, via @aspicio/vue:

vue
<script setup>import { AspicioEmbed } from "@aspicio/vue";import "@aspicio/vue/formats/dxf";</script>
<template>  <AspicioEmbed src-url="/drawing.dxf" style="height: 480px" /></template>

Svelte

The same components as raw Svelte 5 source with typed callback props, via @aspicio/svelte:

svelte
<script>  import { AspicioEmbed } from "@aspicio/svelte";  import "@aspicio/svelte/formats/dxf";</script>
<AspicioEmbed srcUrl="/drawing.dxf" style="height: 480px" />

Vanilla TypeScript

Skip the ready-made UI and drive the viewer directly from @aspicio/core — bring your own chrome:

ts
import { DrawingViewer } from "@aspicio/core";import { dxfParser } from "@aspicio/core/dxf";
const viewer = new DrawingViewer(document.querySelector("#preview")!, {  parsers: [dxfParser],});await viewer.load(file); // File | Blob | ArrayBuffer | DXF text (ASCII or binary)

Headless — Node and serverless

Parse, describe, and render with no browser at all (server-side previews, thumbnails, pipelines):

ts
import {  describeDrawing,  parseWith,  tessellate,  tessellateSpace,  tessellationToSvg,} from "@aspicio/core";import { dxfParser } from "@aspicio/core/dxf";
const doc = await parseWith([dxfParser], bytes); // ASCII or binary DXFconst summary = describeDrawing(doc); // units, bounds, layers, texts, spaces…const svg = tessellationToSvg(tessellate(doc)); // model space (a PDF's page 1)
// Multi-page PDFs and multi-sheet DXFs: describe covers all of them, and// either verb can be scoped to one.const page3 = describeDrawing(doc, { space: "Page 3" });const sheet = tessellationToSvg(tessellateSpace(doc, "Layout1"));

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]
SurfaceLocal filesURLsInline DXF
stdio MCP — npx -y @aspicio/mcp✅✅✅
Hosted MCP — aspicio-api.frontsail.app/mcp—✅✅
HTTP API — /describe, /renderPOST 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.

Packages

PackageDescription
@aspicio/coreThe viewer library: parsing, tessellation, rendering, camera, input
@aspicio/elementsWeb components: <aspicio-embed>, <aspicio-preview>, <aspicio-layer-panel> — plain HTML, Svelte, any framework
@aspicio/reactReact bindings: <AspicioEmbed>, <AspicioPreview>, <AspicioLayerPanel>
@aspicio/vueVue 3 bindings: the same three components with typed props and emits
@aspicio/svelteSvelte 5 bindings: the same three components as raw .svelte source
@aspicio/mcpMCP server for AI agents: describe_dxf + render_dxf
@aspicio/apiDXF HTTP API server (private): /describe, /render, /mcp
@aspicio/widgetMCP Apps in-chat viewer widget (private), served by the api server
@aspicio/demoStandalone 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.

mermaid
flowchart TD    REACTAPP["React app"]    HTMLAPP["Plain HTML / vanilla JS app"]    VUEAPP["Vue app"]    SVELTEAPP["Svelte app"]
    REACT["<b>@aspicio/react</b><br/>&lt;AspicioEmbed&gt; · &lt;AspicioPreview&gt; · &lt;AspicioLayerPanel&gt;<br/><i>thin @lit/react veneer, API-stable</i>"]    VUE["<b>@aspicio/vue</b><br/>&lt;AspicioEmbed&gt; · &lt;AspicioPreview&gt; · &lt;AspicioLayerPanel&gt;<br/><i>thin Vue 3 veneer, typed emits</i>"]    SVELTE["<b>@aspicio/svelte</b><br/>&lt;AspicioEmbed&gt; · &lt;AspicioPreview&gt; · &lt;AspicioLayerPanel&gt;<br/><i>raw Svelte 5 source, compiled by your bundler</i>"]    ELEMENTS["<b>@aspicio/elements</b><br/>&lt;aspicio-embed&gt; · &lt;aspicio-preview&gt; · &lt;aspicio-layer-panel&gt;<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 → DrawingViewer"| 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 DrawingViewer 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

Development

Toolchain: Vite+ (vp) on top of bun.

bash
vp install       # install dependenciesvp run dev       # start the demo appvp run ready     # check + test + build everything (the repo gate)

Testing, CI/deploy, releasing, and contribution guidance: CONTRIBUTING.md.


Aspicio is developed and maintained by FrontSail AI.

Source: README.md at commit 247008c

Tools

6

describe_dxf

Describe a DXF drawing

Return a structured JSON summary of a DXF drawing — units, bounding box, layers (with the color actually drawn), per-type entity counts, and any skipped/unsupported types. Use this to answer structural questions (what layers exist, how many parts, what size, is it to scale) without rendering an image. For a PDF use describe_pdf; if you do not know the format, use describe_doc. Covers the whole drawing by default, including every page of a multi-page PDF; pass `space` (a name from the reply's `spaces`) to scope it to one page or sheet.

Parametersspacesourcerequired

render_dxf

Render a DXF to an image

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, does it look right) — it returns an image, not text. For structural facts, prefer describe_dxf. For a PDF use render_pdf; if you do not know the format, use render_doc. Renders the first page/sheet by default; pass `space` (a name from a describe reply's `spaces`) to render another one.

Parametersspacewidthsourcerequired

describe_pdf

Describe a PDF drawing

Return a structured JSON summary of a PDF drawing — units (points), bounding box, layers, per-type entity counts, the text it contains, and what was skipped (images, shadings, transparency). Use this for structural questions about a PDF without rendering it. For a DXF use describe_dxf; if you do not know the format, use describe_doc. Covers the whole drawing by default, including every page of a multi-page PDF; pass `space` (a name from the reply's `spaces`) to scope it to one page or sheet.

Parametersspacesourcerequired

render_pdf

Render a PDF to an image

Render a PDF drawing's vector content to a PNG you can look at. Images, shadings, and transparency are not drawn — they are reported by describe_pdf — so this shows line work and text, not a page facsimile. For a DXF use render_dxf; if you do not know the format, use render_doc. Renders the first page/sheet by default; pass `space` (a name from a describe reply's `spaces`) to render another one.

Parametersspacewidthsourcerequired

describe_doc

Describe a drawing of any supported format

Return a structured JSON summary of a drawing in any supported format (DXF or PDF), detected from its bytes rather than its name. Use this when you do not know which format you have; the reply names the format that was read. Covers the whole drawing by default, including every page of a multi-page PDF; pass `space` (a name from the reply's `spaces`) to scope it to one page or sheet.

Parametersspacesourcerequired

render_doc

Render a drawing of any supported format

Render a drawing in any supported format (DXF or PDF) to a PNG you can look at, detected from its bytes rather than its name. Use this when you do not know which format you have. Renders the first page/sheet by default; pass `space` (a name from a describe reply's `spaces`) to render another one.

Parametersspacewidthsourcerequired

Version history

2
  1. v0.13.2LatestOct 23, 2026
  2. v0.13.0Sep 16, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts