Model Context Protocol
MCP Server
@digital-metal/mcp-dfm wraps the DFM API as a stdio-transport MCP server. MCP-capable clients (Claude Desktop, Cursor, Continue, Zed, …) can hand a STEP file to the analysis pipeline, browse recognized features, run shipped rule modules, and — the headline use case — author and test custom rule packs in-conversation.
Why MCP, not just curl
The DFM rule grammar is dense. Without machine-readable schema + canonical examples in the LLM’s context, every “write me a rule that flags walls thinner than 2 mm near a hole” turns into a back-and-forth of mis-typed selectors. MCP solves this two ways:
- Resources:
dfm://rule-schemaanddfm://modulesare exposed as read-only MCP resources so the model can read the canonical grammar without burning a tool call. - Tools:
dfm_eval_moduleruns a freshly-authored rule pack against a job in milliseconds — the model gets immediate feedback on its draft and can iterate without redeploying anything.
Install
npx (no global install)
npx -y @digital-metal/mcp-dfm
Or globally:
npm install -g @digital-metal/mcp-dfmConfigure
Claude Desktop
Drop this into ~/Library/Application Support/Claude/claude_desktop_config.json on macOS, or %APPDATA%\Claude\claude_desktop_config.json on Windows:
{
"mcpServers": {
"dfm": {
"command": "npx",
"args": ["-y", "@digital-metal/mcp-dfm"],
"env": {
"DM_API_KEY": "dm_live_..."
}
}
}
}Cursor / Continue
Cursor reads ~/.cursor/mcp.json; Continue uses config.yaml. Both accept the same command / args / env shape as Claude Desktop. After editing, restart the client.
Environment variables
DM_API_KEY— required.dm_live_*token from /dashboard/api.DM_API_BASE— defaulthttps://digitalmetal.io. Override for staging.DFM_API_BASE— defaulthttps://dfm-api.digitalmetal.io(Railway). Override for self-hosted backends.
Tools
| Tool | Signature |
|---|---|
| dfm_quick_info | (file_path) → { volume, surface_area, bbox, n_features, preview_glb_url } Sub-second geometry-only path. Use this first on any unknown part. Metered. |
| dfm_upload | (file_path, max_edge?, curvature?, pull?, alpha_min?, alpha_warn?) → { job_id } Submit a STEP/glTF for full feature recognition + rule modules. Async; poll dfm_status until "done". |
| dfm_status | (job_id) → { status, log } Job state and tail of the analysis log. Returns "queued" / "running" / "done" / "error". |
| dfm_features | (job_id) → features.json Recognized features panel data: roles_by_fid, primary feature list, manufacturability summary. |
| dfm_vertex_data | (job_id) → per-feature per-vertex arrays thickness / clearance / draft / role for every vertex on every face. Use to map a 3D hit point to its measured values. |
| dfm_modules | (job_id) → modules.json All shipped DFM rule-module results (CNC, casting, injection molding, additive, sheet metal). Each module has multiple configurations. |
| dfm_eval_module | (job_id, module, configuration_key, overrides?) → ModuleResult The headline tool. Run a CALLER-supplied rule pack against a completed job. See dfm://rule-schema for the grammar. |
| dfm_recompute | (job_id, pull) → { job_id, status } Re-run draft + recognition + modules with a new pull direction. Mesh is cached. |
| dfm_artifact | (job_id, kind: "thickness"|"clearance"|"features"|"draft") → { url } URL of a generated GLB. Hand to a 3D renderer; do not stream binary through the LLM. |
| dfm_rule_schema | () → schema Selectors / metrics / comparison ops / RHS forms accepted by declarative rules. |
| dfm_list_modules | () → [ModuleSpec] All shipped module specs, suitable for cloning + editing into a custom module. |
Resources
dfm://rule-schema— declarative DFM rule grammar.dfm://modules— every shipped rule-module spec, suitable for cloning + editing.
Sample sessions
Triage a part
User: "Run quick triage on /Users/me/parts/bracket.step."
Claude: dfm_quick_info(file_path="/Users/me/parts/bracket.step")
→ { volume_mm3: 124503, bbox_mm: {x:48.3, y:32.1, z:21.6},
n_features: 320, preview_glb_url: "https://..." }
"Bracket is 48 × 32 × 22 mm, 124 cm³, 320 recognized features. Within
the 150 mm build-volume cap. Want a full DFM analysis?"Run all shipped DFM modules
User: "Yes, full analysis. Show me the CNC verdict."
Claude: dfm_upload(file_path="/Users/me/parts/bracket.step")
→ { job_id: "ae91d057fa33" }
// (polls dfm_status a few times until "done")
dfm_modules(job_id="ae91d057fa33")
→ cnc:5-axis → "warning"
• min_internal_radius: 1 fail (face_0042: r=0.4 mm < tool r=0.5 mm)
• setup_count: pass (1 setup covers every face)
• undercut_access: 2 warningsAuthor + test a custom rule pack
User: "Add a house rule: bosses with diameter < 4 mm are a hard fail."
Claude: (reads dfm://rule-schema in-context)
dfm_eval_module(
job_id="ae91d057fa33",
module={
key: "house",
name: "House DFM rules",
configurations: { default: { name: "Default", parameters: { min_boss_d_mm: 4 } } },
rules: [{
key: "min_boss_diameter",
name: "Minimum boss diameter",
scope: "per_feature",
selector: { set: "bosses" },
metric: "boss.diameter",
tiers: [
{ level: "fail", op: "lt", rhs: { param: "min_boss_d_mm" } },
{ level: "pass" }
],
messages: { fail: "{fid}: Ø{metric:.2f} mm < Ø{threshold:.2f} mm",
pass: "all {n_inspected} bosses ≥ Ø{threshold:.2f} mm" }
}]
},
configuration_key="default")
→ { overall_severity: "fail", findings: [...] }Troubleshooting
- “DM_API_KEY is not set” — the env block in your MCP client config didn’t propagate. Restart the client after editing the config; some clients only read the file at launch.
- Tools don’t appear in the model’s tool picker — the client launched the server but failed to handshake. Check the client’s MCP log (Claude Desktop:
~/Library/Logs/Claude/mcp*.log) for stderr frommcp-dfm. - HTTP 401 on tool calls — key was revoked or pasted with whitespace. Verify at /dashboard/api.
- HTTP 402 on tool calls — metered quota exhausted on the free tier. The dashboard shows live usage; upgrade the plan to enable overage.
- Job stuck in “running” — very large parts can mesh for minutes. The DFM API auto-resolves
max_edgefrom bbox, but you can passmax_edge=3.0todfm_uploadas a coarser override.
Source
Open-source on GitHub at digitalmetal/dfm/mcp. Issues / contributions welcome.