{
  "markdown": "<div align=\"center\">\n  <img src=\"apps/demo/public/favicon.svg\" width=\"72\" height=\"72\" alt=\"Aspicio logo\" />\n  <h1>Aspicio</h1>\n  <p><strong>Drawing understanding for people, applications, and AI agents — DXF and vector PDF.</strong></p>\n  <p><em>Aspicio</em> (Latin: \"I look at\")</p>\n  <p>\n    <a href=\"https://github.com/frontsail-ai/aspicio/actions/workflows/ci.yml\"><img src=\"https://github.com/frontsail-ai/aspicio/actions/workflows/ci.yml/badge.svg\" alt=\"CI\" /></a>\n    <a href=\"https://www.npmjs.com/package/@aspicio/core\"><img src=\"https://img.shields.io/npm/v/%40aspicio%2Fcore?label=%40aspicio%2Fcore\" alt=\"npm: @aspicio/core\" /></a>\n    <a href=\"https://www.npmjs.com/package/@aspicio/elements\"><img src=\"https://img.shields.io/npm/v/%40aspicio%2Felements?label=%40aspicio%2Felements\" alt=\"npm: @aspicio/elements\" /></a>\n    <a href=\"https://www.npmjs.com/package/@aspicio/react\"><img src=\"https://img.shields.io/npm/v/%40aspicio%2Freact?label=%40aspicio%2Freact\" alt=\"npm: @aspicio/react\" /></a>\n    <a href=\"https://www.npmjs.com/package/@aspicio/vue\"><img src=\"https://img.shields.io/npm/v/%40aspicio%2Fvue?label=%40aspicio%2Fvue\" alt=\"npm: @aspicio/vue\" /></a>\n    <a href=\"https://www.npmjs.com/package/@aspicio/svelte\"><img src=\"https://img.shields.io/npm/v/%40aspicio%2Fsvelte?label=%40aspicio%2Fsvelte\" alt=\"npm: @aspicio/svelte\" /></a>\n    <a href=\"https://www.npmjs.com/package/@aspicio/mcp\"><img src=\"https://img.shields.io/npm/v/%40aspicio%2Fmcp?label=%40aspicio%2Fmcp\" alt=\"npm: @aspicio/mcp\" /></a>\n    <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-blue.svg\" alt=\"License: MIT\" /></a>\n  </p>\n  <p><a href=\"https://aspicio.frontsail.app\"><strong>▶ Live demo</strong></a></p>\n</div>\n\nAspicio is an open-source (MIT), TypeScript-first drawing engine: one\nframework-free `parse → tessellate` pipeline that runs in the browser, in\nNode, and in serverless runtimes. It reads DXF and the vector content of\nPDF — the kind of PDF that carries artwork and dielines rather than a\nscan. A person gets an interactive WebGL viewer of a CAD drawing; an AI\nagent gets structured JSON facts and a rendered PNG of the same file.\nEvery surface — the browser viewer, the web components and their React,\nVue, and Svelte bindings, the headless renderer, the HTTP API, and the MCP\nserver — is a thin adapter over the same engine, so a drawing is equally\nreadable everywhere.\n\n```\nDXF / PDF bytes ─parse─▶ DrawingDocument ─tessellate─▶ Tessellation ──┬─▶ WebGL renderer (viewer)\n                        (normalized model)   (batched geometry)       ├─▶ SVG string (export / API / MCP)\n                                                                      └─▶ DrawingSummary (describe)\n```\n\nHow it's built: [docs/architecture.md](docs/architecture.md) · behavior\nspecs: [docs/product-specs/](docs/product-specs/README.md)\n\n<img src=\"docs/sample-demo.png\" alt=\"Aspicio viewing a sample floor-plan DXF — layer panel, colored geometry, text, and a dimension\" />\n\n## Embed it\n\nOne embed, every flavor — and every path below renders the same web\ncomponents, so the result is pixel-identical no matter which you pick.\n\n### Web components — plain HTML, any framework\n\nOne tag gives you the layer panel plus an interactive preview; no\nbindings needed:\n\n```html\n<script type=\"module\">\n  import \"@aspicio/elements\";\n  import \"@aspicio/elements/formats/dxf\";\n</script>\n\n<aspicio-embed src-url=\"/drawing.dxf\" style=\"height: 480px\"></aspicio-embed>\n```\n\nFormats are opted into by import: the package brings the components, the\n`formats/*` entry brings the parser. That is what keeps a DXF app from\nshipping every other format's code — and every flavor below does the same.\n\n### React\n\nThe same embed with idiomatic props and a `ref` exposing the full\nviewer, via [`@aspicio/react`](packages/react):\n\n```tsx\nimport { AspicioEmbed } from \"@aspicio/react\";\nimport \"@aspicio/react/formats/dxf\";\n\n<AspicioEmbed src={file} style={{ height: 480 }} />;\n```\n\n### Vue\n\nTyped props and emits with unwrapped payloads, via\n[`@aspicio/vue`](packages/vue):\n\n```vue\n<script setup>\nimport { AspicioEmbed } from \"@aspicio/vue\";\nimport \"@aspicio/vue/formats/dxf\";\n</script>\n\n<template>\n  <AspicioEmbed src-url=\"/drawing.dxf\" style=\"height: 480px\" />\n</template>\n```\n\n### Svelte\n\nThe same components as raw Svelte 5 source with typed callback props,\nvia [`@aspicio/svelte`](packages/svelte):\n\n```svelte\n<script>\n  import { AspicioEmbed } from \"@aspicio/svelte\";\n  import \"@aspicio/svelte/formats/dxf\";\n</script>\n\n<AspicioEmbed srcUrl=\"/drawing.dxf\" style=\"height: 480px\" />\n```\n\n### Vanilla TypeScript\n\nSkip the ready-made UI and drive the viewer directly from\n[`@aspicio/core`](packages/core) — bring your own chrome:\n\n```ts\nimport { DrawingViewer } from \"@aspicio/core\";\nimport { dxfParser } from \"@aspicio/core/dxf\";\n\nconst viewer = new DrawingViewer(document.querySelector(\"#preview\")!, {\n  parsers: [dxfParser],\n});\nawait viewer.load(file); // File | Blob | ArrayBuffer | DXF text (ASCII or binary)\n```\n\n### Headless — Node and serverless\n\nParse, describe, and render with no browser at all (server-side\npreviews, thumbnails, pipelines):\n\n```ts\nimport {\n  describeDrawing,\n  parseWith,\n  tessellate,\n  tessellateSpace,\n  tessellationToSvg,\n} from \"@aspicio/core\";\nimport { dxfParser } from \"@aspicio/core/dxf\";\n\nconst doc = await parseWith([dxfParser], bytes); // ASCII or binary DXF\nconst summary = describeDrawing(doc); // units, bounds, layers, texts, spaces…\nconst svg = tessellationToSvg(tessellate(doc)); // model space (a PDF's page 1)\n\n// Multi-page PDFs and multi-sheet DXFs: describe covers all of them, and\n// either verb can be scoped to one.\nconst page3 = describeDrawing(doc, { space: \"Page 3\" });\nconst sheet = tessellationToSvg(tessellateSpace(doc, \"Layout1\"));\n```\n\nWhat you get: WebGL rendering batched to one draw call per layer (large\ndrawings stay interactive), broad entity coverage (lines, arcs, circles,\nellipses, polylines with bulges, splines, TEXT/MTEXT, DIMENSION,\nSOLID/HATCH fills, nested INSERT blocks — anything unsupported is counted\nand reported, never fatal), a layer list with the colors that are\n_actually drawn_ (per-entity overrides included, not just the layer\ntable), measure\nwith object snap, entity picking, paper-space layouts, SVG/PNG export,\nand first-class touch. Out of scope: editing and 3D.\n\n## Hand it to an agent\n\nThe same engine speaks MCP and HTTP, so an agent can _read_ a drawing\ninstead of guessing at it:\n\n- **`describe_dxf`** — units, bounds, size, layers with effective colors,\n  entity counts, and the drawing's text content. An agent reads a title\n  block or a dimension value directly — no OCR, no vision round-trip.\n- **`render_dxf`** — a PNG of the drawing the model can look at.\n- **`view_dxf`** (hosted server) — an interactive in-chat viewer for the\n  _person_ in the conversation, via the open [MCP Apps\n  extension](https://modelcontextprotocol.io/seps/1865-mcp-apps-interactive-user-interfaces-for-mcp):\n  pan, zoom, layer toggles, fullscreen, host light/dark theming. The\n  widget is locked to the drawing the tool call delivered and makes no\n  network requests; hosts without MCP Apps still get the structured\n  facts.\n\n<img src=\"docs/demo-widget.gif\" alt=\"The in-chat viewer loading a 1.1 MB floor-plan DXF, toggling dimension and text layers, and expanding to fullscreen\" />\n\n| Surface                                      | Local files | URLs | Inline DXF |\n| -------------------------------------------- | ----------- | ---- | ---------- |\n| stdio MCP — `npx -y @aspicio/mcp`            | ✅          | ✅   | ✅         |\n| Hosted MCP — `aspicio-api.frontsail.app/mcp` | —           | ✅   | ✅         |\n| HTTP API — `/describe`, `/render`            | POST body   | ✅   | ✅         |\n\nConnect:\n\n- **Claude Code** — one step installs the MCP server plus the bundled\n  skills (`aspicio-inspect-dxf`, `aspicio-embed`):\n  `/plugin marketplace add frontsail-ai/aspicio` then `/plugin install aspicio@aspicio`\n- **Codex** — the same repo doubles as a Codex marketplace:\n  `codex plugin marketplace add https://github.com/frontsail-ai/aspicio`,\n  `codex plugin add aspicio@aspicio`, then\n  `codex mcp add aspicio -- npx -y @aspicio/mcp`\n- **Any client that launches stdio MCP servers** — register\n  `npx -y @aspicio/mcp`\n- **Any client that supports remote MCP (Streamable HTTP)** — point it\n  at `https://aspicio-api.frontsail.app/mcp` (no install;\n  speaks MCP, not a browser page)\n- **Plain HTTP** — `GET /describe?src=<dxf-url>`,\n  `GET /render?src=<dxf-url>&format=png|svg`; the API self-describes at\n  [`/openapi.json`](https://aspicio-api.frontsail.app/openapi.json)\n\nURL fetches are guarded (private-network blocking, size caps, redirect\nvalidation, timeouts). The stdio server reads local files in-process and\nnever uploads the DXF to any Aspicio service — though, as with any tool\nresult, your MCP client passes the returned summary or image to its\nmodel provider. Full details:\n[privacy policy](https://aspicio.frontsail.app/privacy/) ·\n[terms](https://aspicio.frontsail.app/terms/).\n\n## Available today · direction\n\nEverything above is shipped and live: viewer + demo, core, web\ncomponents, React, Vue, and Svelte packages, headless describe/render, stdio and hosted MCP, the in-chat\nMCP Apps viewer, the HTTP API with OpenAPI, and plugin packaging for\nClaude Code and Codex.\n\nDirection (intent, not commitments — see\n[issues](https://github.com/frontsail-ai/aspicio/issues)): MCP registry\nlistings, structured entity queries and focused rendering, and an\nupload flow so remote surfaces can handle local files.\n\n## Packages\n\n| Package                                  | Description                                                                                                         |\n| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |\n| [`@aspicio/core`](packages/core)         | The viewer library: parsing, tessellation, rendering, camera, input                                                 |\n| [`@aspicio/elements`](packages/elements) | Web components: `<aspicio-embed>`, `<aspicio-preview>`, `<aspicio-layer-panel>` — plain HTML, Svelte, any framework |\n| [`@aspicio/react`](packages/react)       | React bindings: `<AspicioEmbed>`, `<AspicioPreview>`, `<AspicioLayerPanel>`                                         |\n| [`@aspicio/vue`](packages/vue)           | Vue 3 bindings: the same three components with typed props and emits                                                |\n| [`@aspicio/svelte`](packages/svelte)     | Svelte 5 bindings: the same three components as raw .svelte source                                                  |\n| [`@aspicio/mcp`](packages/mcp)           | MCP server for AI agents: `describe_dxf` + `render_dxf`                                                             |\n| [`@aspicio/api`](apps/api)               | DXF HTTP API server (private): `/describe`, `/render`, `/mcp`                                                       |\n| [`@aspicio/widget`](apps/widget)         | MCP Apps in-chat viewer widget (private), served by the api server                                                  |\n| [`@aspicio/demo`](apps/demo)             | Standalone demo app (private) — also the reference integration                                                      |\n\nHow the viewer packages fit together: every framework path funnels into\nthe same Lit web components — one implementation of the embed UI — which\nsit on the framework-free core. React, Vue, and Svelte get thin veneers\nwith idiomatic props; plain HTML consumes the elements directly.\n\n```mermaid\nflowchart TD\n    REACTAPP[\"React app\"]\n    HTMLAPP[\"Plain HTML / vanilla JS app\"]\n    VUEAPP[\"Vue app\"]\n    SVELTEAPP[\"Svelte app\"]\n\n    REACT[\"<b>@aspicio/react</b><br/>&lt;AspicioEmbed&gt; · &lt;AspicioPreview&gt; · &lt;AspicioLayerPanel&gt;<br/><i>thin @lit/react veneer, API-stable</i>\"]\n    VUE[\"<b>@aspicio/vue</b><br/>&lt;AspicioEmbed&gt; · &lt;AspicioPreview&gt; · &lt;AspicioLayerPanel&gt;<br/><i>thin Vue 3 veneer, typed emits</i>\"]\n    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>\"]\n    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>\"]\n    CORE[\"<b>@aspicio/core</b><br/>parse → tessellate → render<br/><i>camera · input · picking · SVG/PNG export · headless describe</i>\"]\n\n    REACTAPP -->|\"idiomatic props, ref → DrawingViewer\"| REACT\n    REACT -->|\"wraps\"| ELEMENTS\n    HTMLAPP -->|\"attributes + DOM events\"| ELEMENTS\n    VUEAPP -->|\"idiomatic props + emits\"| VUE\n    VUE -->|\"wraps\"| ELEMENTS\n    SVELTEAPP -->|\"typed callback props\"| SVELTE\n    SVELTE -->|\"wraps\"| ELEMENTS\n    ELEMENTS -->|\"drives\"| CORE\n    HTMLAPP -.->|\"or hand-rolled UI on the DrawingViewer API\"| CORE\n\n    classDef pkg fill:#191c22,stroke:#4c8dff,color:#e7e3da\n    classDef app fill:#1f232b,stroke:#3a3f4a,color:#9aa0ab\n    class REACT,VUE,SVELTE,ELEMENTS,CORE pkg\n    class REACTAPP,HTMLAPP,VUEAPP,SVELTEAPP app\n```\n\n## Development\n\nToolchain: [Vite+](https://viteplus.dev) (`vp`) on top of bun.\n\n```bash\nvp install       # install dependencies\nvp run dev       # start the demo app\nvp run ready     # check + test + build everything (the repo gate)\n```\n\nTesting, CI/deploy, releasing, and contribution guidance:\n[CONTRIBUTING.md](CONTRIBUTING.md).\n\n---\n\nAspicio is developed and maintained by\n[FrontSail AI](https://frontsail.ai/).\n",
  "bytes": 13666,
  "sha": "2fbfc4934e4d8249a93cbfd0c2e1690c162b37ea00c35a34c7733e6fc62dd599",
  "repo_slug": "frontsail-ai/aspicio",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_frontsail_ai_aspicio_47accebe/readme"
}