Homotope

app.homotope由 homotope.app 發布官方發布者v1.0.0更新於 Oct 31, 2026

Vectorize images to SVG, PDF, EPS or DXF, and check a DXF before cutting.

已驗證Streamable HTTP可網頁執行開發者工具媒體與設計

概覽

AI 產生的概覽

Homotope 是託管型 MCP 伺服器,讓助理把點陣圖向量化成 SVG、PDF、EPS 或 DXF,並對 DXF 做切割前檢查。

可以做什麼
  • 把 PNG 或 JPEG 影像向量化成乾淨的 SVG,可用標誌、插畫、像素畫、線稿、黑白、照片或中心線等預設
  • 把產生的 SVG 轉成 DXF、PDF 或 EPS,包含依顏色分層與分色
  • 對向量結果做切割就緒檢查,提示過小的孤島、過近的邊與節點數量
  • 回傳調色盤顏色以及路徑、節點等統計資訊
適用情境
適合讓助理把點陣標誌、手繪圖或照片轉成可編輯的向量圖,或為繪圖機、雷射切割、雕刻、刺繡準備向量檔並確認可安全切割。
執行需求
需要連線到 homotope.app 的遠端 MCP 端點(streamable HTTP),並以 OAuth 登入授權。未宣告任何環境變數或請求標頭。
安裝前請注意
託管服務需要以 OAuth 授權你的帳號;README 提到可選的伺服器端處理,因此經託管連接器送出的影像可能離開本機,儘管底層引擎本身在本機執行。產生的檔案在切割或加工前應人工檢查。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Homotope,將其新增到工作區。
  2. 連接 所需的 憑證。它們會被私密儲存,絕不會在公開頁面上展示。
  3. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

交給代理程式安裝

把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。

閱讀 https://sourceweft.com/mcp/app.homotope%2Fhomotope/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。

檢視代理程式所依據的安裝指南

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。 客戶端會在首次連接時完成 OAuth 登入。

{
  "mcpServers": {
    "homotope": {
      "type": "http",
      "url": "https://homotope.app/mcp"
    }
  }
}

README

@homotope/engine

This is the engine of Homotope, an image vectorizer that runs in the browser: nothing is uploaded. Try it in the workshop (free, no account needed for SVG and PNG).

Raster-to-vector engine in pure TypeScript: turns a PNG or JPEG (any RGBA pixel buffer) into a clean SVG, and from that SVG into DXF, PDF or EPS. Released under the MIT license.

What this package is not: it has no editor, no server, no REST API, no MCP server and no printer checks; those live in the hosted service. The npm package is frozen at 0.2.0: what it contains is complete and usable on its own.

  • No DOM, no runtime dependencies. The core runs unchanged in a Web Worker, in the main thread and in Node. Pixel data stays on the machine: nothing is uploaded anywhere.
  • Topology first. The image is quantized in OKLab, segmented into regions, and every shared boundary is fitted once: two neighbouring shapes never overlap and never leave a gap. Holes are kept (an "O" stays an "O").
  • Presets for logos, illustrations, pixel art, line art, black & white, photos, and a centerline mode that traces strokes as single open paths (plotters, engraving, embroidery).
  • Fabrication exports: DXF (layers per colour, shared edges cut once), PDF, EPS, colour separations, and a cut-readiness check (tiny islands, too-close edges, node counts).
  • An alternative to Potrace: no GPL code, full colour, exact shared borders.

Install

bash
npm install @homotope/engine# Node only, to decode PNG/JPEG files (optional peer dependencies):npm install pngjs jpeg-js

Requires an ES2022 runtime (Node ≥ 22, any current browser). ESM only.

Entry points

ImportWhatDependencies
@homotope/enginevectorize, presetOptions, PRESET_NAMES, all typesnone
@homotope/engine/exportconvertSvg (SVG → PDF, DXF, EPS), exportLayers, sceneFromSvgnone
@homotope/engine/cutcheckcheckSvg, simplifySvg: cut-readiness report for cuttersnone
@homotope/engine/nodedecodePng, decodeJpeg, encodePng, encodeJpegpngjs, jpeg-js

Browser bundles only receive what they import: the core never imports pngjs or jpeg-js.

Node example

ts
import { readFileSync, writeFileSync } from 'node:fs';import { vectorize, presetOptions } from '@homotope/engine';import { convertSvg } from '@homotope/engine/export';import { decodePng } from '@homotope/engine/node';
const image = decodePng(new Uint8Array(readFileSync('logo.png')));const result = vectorize(image, presetOptions('logo'), {  onProgress: (e) => process.stdout.write(`\r${e.stage} ${Math.round(e.progress * 100)}%`),});
writeFileSync('logo.svg', result.svg);writeFileSync('logo.dxf', convertSvg(result.svg, 'dxf'));console.log(`\n${result.palette.colors.length} colours, ${result.stats.paths} paths`);

Browser example (Web Worker)

vectorize is synchronous on purpose: run it in a worker so the page stays responsive. Its input is any ImageData-like object { width, height, data: Uint8ClampedArray } (RGBA, not premultiplied).

ts
// main.tsconst bitmap = await createImageBitmap(file);const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);const ctx = canvas.getContext('2d')!;ctx.drawImage(bitmap, 0, 0);const { width, height, data } = ctx.getImageData(0, 0, bitmap.width, bitmap.height);
const worker = new Worker(new URL('./vectorize.worker.ts', import.meta.url), { type: 'module' });worker.onmessage = (e: MessageEvent<{ svg: string }>) => {  const url = URL.createObjectURL(new Blob([e.data.svg], { type: 'image/svg+xml' }));  document.querySelector<HTMLImageElement>('#preview')!.src = url; // or offer it as a download};worker.postMessage({ width, height, data }, [data.buffer]);
ts
// vectorize.worker.tsimport { vectorize, presetOptions, type RasterImage } from '@homotope/engine';
self.onmessage = (e: MessageEvent<RasterImage>) => {  const { svg } = vectorize(e.data, presetOptions('illustration'));  self.postMessage({ svg });};

Cancellation is cooperative: pass { cancel: { cancelled: boolean } } as the third argument (for example backed by a SharedArrayBuffer); vectorize then throws a CancelledError between and inside stages.

Presets

presetOptions(name) returns a full, independent options object that you can tweak.

PresetFor
logoFlat colours, crisp corners, straight lines kept straight
illustrationUp to 32 colours, smoother curves, light gradients, stacked shapes
pixel-artExact pixel grid, no curves, zero error
line-artInk drawings and text: two colours, filled shapes
centerlineStrokes traced as single open paths (plotter, laser engraving)
black-whiteTwo colours from an automatic (Otsu) threshold
photoUp to 64 colours, denoising, small regions absorbed, stacked shapes
ts
import { presetOptions, vectorize } from '@homotope/engine';
const options = presetOptions('logo');options.quantize.colors = 4; // fixed number of colours instead of 'auto'options.export.precision = 1; // decimals in path dataoptions.export.mode = 'stacked'; // fewer nodes: shapes stacked instead of cut outconst { svg } = vectorize(image, options);

Every option is typed and documented in VectorizeOptions (preprocess, quantize, segment, fit, export, centerline).

SVG output

  • viewBox in the pixel coordinates of the original image, cubic Béziers, one <path> per colour by default (export.mergeByColor).
  • export.mode: 'cut' (default): every region is an exact path with its holes (fill-rule="evenodd"), no overlap; 'stacked': shapes stacked by depth, fewer nodes.
  • Transparent pixels (preprocess.alphaMode: 'keep') produce no path.
  • result.palette lists the colours (sRGB and OKLab, pixel counts); result.stats the number of paths and nodes; result.timings the time spent per stage.

Hosted version and API

homotope.app runs this engine in the browser with a visual editor (palette, presets, before/after), plus optional server processing, a REST API and an MCP server for AI assistants: see the API documentation.

Development

bash
npm installnpm test           # Vitest, no DOMnpm run typechecknpm run lintnpm run eval       # renders every fixture and measures the error (Resvg)npm run build      # dist/ (ESM + .d.ts)

See CONTRIBUTING.md.

License

MIT.

來源:README.md,提交 4a43cb4

工具

0
該伺服器需要登入,因此 SourceWeft 無法在沒有帳號的情況下讀取其工具,也未收錄。已連接帳號所能看到的內容可能因帳號及其權限而異。

版本歷史

1
  1. v1.0.0最新Oct 31, 2026

評分

已滿足適用檢查項的 85%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通必需25 分
  • 已宣告認證方式必需10 分
  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分