Summary
Give the import surface full Protocol §14 MCP + CLI parity and a single
content-sniffing entry point. Backlogged from the native Sparx XMI work
(ADR-219, shipped in v6.32.0, website-only).
Full plan: docs/plans/adr-220-unified-import-mcp-cli.md (also on branch sparxea-xml-file-format until that PR merges).
The gap
- The Iris MCP has no import tool (56 tools, none for importing model files) and the CLI has no import command. The MCP is a remote Streamable-HTTP server (
iris-mcp.onrender.com, ADR-134) that cannot see the user's local files, so AI agents/scripts can't import models the way the website can.
- Format dispatch is duplicated (frontend extension/content sniff + five per-format endpoints) — no single source of truth.
Locked decisions (made during ADR-219 planning)
- File delivery = URL fetch.
import_model(source_url, set_id?) — the backend downloads and imports. Only mechanism that works for the remote MCP across all formats incl. multi-MB binaries (.qea/.eap/.pptx); inline base64 can't carry those.
- Unified endpoint + CLI. Add a content-sniffing
POST /api/import dispatcher used by the frontend, the MCP tool, and a new iris import command.
Scope / deliverables
Security note
The server-side URL download is an SSRF vector. The plan enforces: https-only scheme allowlist; resolve+block private/loopback/link-local/metadata IPs; pin the vetted IP (DNS-rebinding TOCTOU); no redirects; streaming size cap; timeout; post-download format sniff (reject arbitrary bytes). Requires a /security-review pass on download.py.
Notes
- No DB migration (writes via existing
create_* services; SQLite+Supabase parity).
scripts/check_surface_parity.py stays green (it scans only the five known entity routers); MCP + CLI added voluntarily for §14 spirit.
Summary
Give the import surface full Protocol §14 MCP + CLI parity and a single
content-sniffing entry point. Backlogged from the native Sparx XMI work
(ADR-219, shipped in v6.32.0, website-only).
Full plan:
docs/plans/adr-220-unified-import-mcp-cli.md(also on branchsparxea-xml-file-formatuntil that PR merges).The gap
iris-mcp.onrender.com, ADR-134) that cannot see the user's local files, so AI agents/scripts can't import models the way the website can.Locked decisions (made during ADR-219 planning)
import_model(source_url, set_id?)— the backend downloads and imports. Only mechanism that works for the remote MCP across all formats incl. multi-MB binaries (.qea/.eap/.pptx); inline base64 can't carry those.POST /api/importdispatcher used by the frontend, the MCP tool, and a newiris importcommand.Scope / deliverables
backend/app/imports/:detect.py(5-format sniff),download.py(SSRF-hardened URL fetch),router.py(POST /api/import, file XOR source_url) — per-format routers delegate to a shared dispatch core (DRY)iris-client.import_model+ MCPimport_modeltool +server_instructionsnoteiris import <file|--url>CLI command/api/import(drop the v6.32.0 client-side sniff)Security note
The server-side URL download is an SSRF vector. The plan enforces: https-only scheme allowlist; resolve+block private/loopback/link-local/metadata IPs; pin the vetted IP (DNS-rebinding TOCTOU); no redirects; streaming size cap; timeout; post-download format sniff (reject arbitrary bytes). Requires a
/security-reviewpass ondownload.py.Notes
create_*services; SQLite+Supabase parity).scripts/check_surface_parity.pystays green (it scans only the five known entity routers); MCP + CLI added voluntarily for §14 spirit.