npm @aspicio/mcpstreamable-httpMITupdated 8d ago
Aspicio Drawing understanding for people, applications, and AI agents β DXF and vector PDF. Aspicio (Latin: "I look at")
What can you do with Aspicio?
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/
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:
<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:
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:
<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:
<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:
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):
import {
describeDrawing,
parseWith,
tessellate,
tessellateSpace,
tessellationToSvg,
} from "@aspicio/core";
import { dxfParser } from "@aspicio/core/dxf";
const doc = await parseWith([dxfParser], bytes); // ASCII or binary DXF
const 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.
| 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/aspiciothen/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, thencodex 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
| Package | Description |
|---|---|
@aspicio/core |
The viewer library: parsing, tessellation, rendering, camera, input |
@aspicio/elements |
Web components: <aspicio-embed>, <aspicio-preview>, <aspicio-layer-panel> β plain HTML, Svelte, any framework |
@aspicio/react |
React bindings: <AspicioEmbed>, <AspicioPreview>, <AspicioLayerPanel> |
@aspicio/vue |
Vue 3 bindings: the same three components with typed props and emits |
@aspicio/svelte |
Svelte 5 bindings: the same three components as raw .svelte source |
@aspicio/mcp |
MCP server for AI agents: describe_dxf + render_dxf |
@aspicio/api |
DXF HTTP API server (private): /describe, /render, /mcp |
@aspicio/widget |
MCP Apps in-chat viewer widget (private), served by the api server |
@aspicio/demo |
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/><AspicioEmbed> Β· <AspicioPreview> Β· <AspicioLayerPanel><br/><i>thin @lit/react veneer, API-stable</i>"]
VUE["<b>@aspicio/vue</b><br/><AspicioEmbed> Β· <AspicioPreview> Β· <AspicioLayerPanel><br/><i>thin Vue 3 veneer, typed emits</i>"]
SVELTE["<b>@aspicio/svelte</b><br/><AspicioEmbed> Β· <AspicioPreview> Β· <AspicioLayerPanel><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 β 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.
vp install # install dependencies
vp run dev # start the demo app
vp 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.
Install
Add Aspicio to your client. Pick the one you use.
{
"servers": {
"mcp": {
"type": "http",
"url": "https://aspicio-api.frontsail.app/mcp"
}
}
}Add to `.vscode/mcp.json` in your workspace.
claude mcp add mcp -- npx -y @aspicio/mcpcodex mcp add mcp -- npx -y @aspicio/mcpamp mcp add mcp -- npx -y @aspicio/mcp{
"mcpServers": {
"mcp": {
"command": "npx",
"args": [
"-y",
"@aspicio/mcp"
]
}
}
}Add to `claude_desktop_config.json`, then restart Claude Desktop.
{
"mcpServers": {
"mcp": {
"command": "npx",
"args": [
"-y",
"@aspicio/mcp"
]
}
}
}Add to `~/.cursor/mcp.json`, or `.cursor/mcp.json` for a single project.
{
"mcpServers": {
"mcp": {
"command": "npx",
"args": [
"-y",
"@aspicio/mcp"
]
}
}
}Add to `~/.codeium/windsurf/mcp_config.json`.
{
"mcpServers": {
"mcp": {
"command": "npx",
"args": [
"-y",
"@aspicio/mcp"
]
}
}
}Add to `cline_mcp_settings.json` via the MCP Servers panel.
{
"mcpServers": {
"mcp": {
"command": "npx",
"args": [
"-y",
"@aspicio/mcp"
]
}
}
}Add to `~/.gemini/settings.json`.
{
"mcpServers": {
"mcp": {
"type": "local",
"command": "npx",
"args": [
"-y",
"@aspicio/mcp"
],
"tools": [
"*"
]
}
}
}Add to `~/.copilot/mcp-config.json`, or run `/mcp add` inside the CLI.
{
"context_servers": {
"mcp": {
"command": {
"path": "npx",
"args": [
"-y",
"@aspicio/mcp"
]
}
}
}
}Add to your Zed `settings.json`.
npx -y @aspicio/mcpRun `goose configure`, choose **Add Extension β Command-line Extension**, and paste this command.
Score
39 / 100
Incomplete
- Documentation20/25
- Maintenance25/25
- Trust16/20
- Capability0/15
- Install experience15/15
- Documents what it does and how to connect
- Has a resolvable package or endpoint
- Exposes at least one tool, prompt or resource
- README has substantive content
- Includes a code example
- Documents its configuration
- Mentions credentials or security posture
- Last commit 1 days ago
- Has a release history
- Repository is not archived
- Licensed MIT
- Namespace verified in the official MCP registry
- Claimed by its owner
- Published under an organisation
- 0 tool(s) documented
- Provides prompt templates
- Provides resources
- 18 documented install method(s)
- Published to a package registry
- Offers a hosted endpoint β no local install
Version history
| Versions | Published |
|---|---|
| 0.13.0Latest | Aug 11, 2026 |
| 0.12.0 | Aug 2, 2026 |
| 0.11.1 | Jul 23, 2026 |
| 0.11.0 | Jul 23, 2026 |
| 0.10.0 | Jul 22, 2026 |
| 0.9.0 | Jul 21, 2026 |
| 0.8.0 | Jul 21, 2026 |
| 0.7.0 | Jul 21, 2026 |
| 0.6.1 | Jul 21, 2026 |