AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Mcp Open Design

skill-michelkerkmeester-opencode-skilled-agent-loops-with-spec-kit-memory-mcp-open-design · by MichelKerkmeester

Drive the installed Open Design desktop app from the terminal through its `od` CLI and stdio MCP server. Read local design projects and design-systems, reuse them, answer the app's prompts, and commission headless generation runs without using the in-app chat. Wires Open Design's MCP server into opencode or Claude Code. MANDATORY: any UI/design work through Open Design also requires sk-interface-…

— No reviews yet
0 installs
32 views
0.0% view→install

Install

$ agentstack add skill-michelkerkmeester-opencode-skilled-agent-loops-with-spec-kit-memory-mcp-open-design

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ✓ Network access No
  • ● Filesystem access Used
  • ✓ Shell / process execution No
  • ✓ Environment & secrets No
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-michelkerkmeester-opencode-skilled-agent-loops-with-spec-kit-memory-mcp-open-design)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
● 2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Mcp Open Design? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Open Design (mcp-open-design)

Drive the installed Open Design desktop app (nexu-io/open-design, "the official open-source, local-first Claude Design alternative") from the terminal, so a coding agent (opencode / Claude Code) can read your local design projects and design-systems, reuse them, answer the app's prompts, and commission generation runs without typing into the in-app chat. The interface is the od CLI plus a stdio MCP server that Open Design exposes; deep operational detail lives in [references/od_cli_reference.md](references/odclireference.md).

> ## ⛔ MANDATORY PAIRING — sk-interface-design > > This skill is the transport, never the taste. For ANY UI/design work through Open Design — every generation/start_run, and every read that feeds a design decision (grounding in a system, reusing its tokens/components) — you MUST load [sk-interface-design](../sk-interface-design/SKILL.md) and run its ground → token-system → critique FIRST, then shape the brief and every discovery-form answer with that judgment. You may never produce or shape an interface from Open Design without it. Open Design generates; sk-interface-design decides. This is a hard precondition, not a recommendation. (Pure transport — wiring the MCP server, bare project listing that feeds no design decision — is exempt because it makes no design decision.)

> Terminology. Open Design calls a workspace a project, a brand/style a design system (DESIGN.md + tokens.css + components.html), a build a run, and an output file an artifact. The CLI brands itself od but is app/prebundled/daemon/daemon-cli.mjs run under Node - it is NOT the bundled vela binary (vela is the cloud auth client).


1. WHEN TO USE

Activation Triggers

Use when the user:

  • Wants a terminal agent to use Open Design's local projects, design-systems, or artifacts.
  • Wants to wire Open Design's MCP server into opencode or Claude Code ("connect open design", "od mcp install").
  • Wants to ground a design in one of Open Design's ~150 design-systems, or reuse its tokens/components.
  • Wants to commission an Open Design generation run headlessly, or answer a run's prompt from the terminal.

Keyword Triggers: "open design", "open-design", "od mcp", "od cli", "design system from open design", "drive open design from the terminal".

Use Cases

Wire direction (connect the app to your agent). Register Open Design's stdio MCP server into opencode/Claude Code so its tools appear to the agent.

Read direction (use local content). List projects, read the active context, read a design system's DESIGN.md/tokens.css/components.html, search files, fetch artifacts - all read-only.

Run direction (commission work headlessly). Generation is multi-turn. start_run (or od run start) fires turn 1, which returns a discovery question-form and zero files. Answer the form with od ui respond (or a follow-up message) to fire the build that writes the design and gives the project a previewUrl. Gated. Mandatory before any of this: load sk-interface-design and shape the brief and form answers with its judgment (see the MANDATORY PAIRING banner above).

When NOT to Use

Skip this skill when:

  • The user wants to work in Open Design's in-app chat UI directly (that is the thing this skill replaces, not automates).
  • The work is generic app coding with no Open Design content (use sk-code).
  • The work is the design judgment itself (the look, the anti-default critique) - that is sk-interface-design; this skill is the transport.
  • Open Design is not installed, or its desktop app is not running (the local daemon, and therefore every tool call, is unavailable).

2. SMART ROUTING

Primary Detection Signal

Detect the workflow direction, since it selects both the commands and the references to load:

# Direction detection (pseudo)
echo "$REQUEST" | grep -qiE 'install|wire|connect|hook .* up|mcp add' && DIR="WIRE"
echo "$REQUEST" | grep -qiE 'run|generate|commission|build .* in open ?design|start_run' && DIR="RUN"
echo "$REQUEST" | grep -qiE 'read|list|search|design system|tokens|reuse|ground' && DIR="READ"
# default when only inspecting/listing: READ

Phase Detection

TASK CONTEXT
    |
    +- STEP 0: locate the od CLI + confirm the daemon is reachable
    +- STEP 1: Score intent -> WIRE | READ | RUN
    +- STEP 2 [HARD GATE]: if RUN, or READ that feeds a design decision -> LOAD sk-interface-design and run ground -> token-system -> critique FIRST. No design output without it. (WIRE / bare inventory: exempt.)
    +- Phase 1: Wire (od mcp install , or manual config) [WIRE]
    +- Phase 2: Read (list_projects / get_active_context / get_file / design-systems read) [READ]
    +- Phase 3: Run (turn 1 start_run -> answer discovery form -> build -> get_run / get_artifact, gated) [RUN]
    +- Phase 4: Verify (tools/list reflects what you used, the build wrote files and the project has a previewUrl)

Resource Loading Levels

| Level | When to Load | Resources | | ----- | ------------ | --------- | | ALWAYS | Every invocation | references/od_cli_reference.md (locate the CLI, daemon model, verb surface) | | CONDITIONAL | WIRE intent | references/mcp_wiring.md (opencode + Claude Code config, manual fallback) | | CONDITIONAL | READ / RUN intent | references/tool_surface.md (the MCP tools, the surface/gate/omit policy) | | ⛔ MANDATORY (any design step) | ANY generation/RUN, or any READ feeding a design decision (grounding, reusing tokens/components) | sk-interface-design — load it and run ground → token-system → critique BEFORE deciding. Hard precondition: a design step without it is blocked. | | ⛔ MANDATORY (any design step) | Reuse-before-generate / fidelity / handoff | references/design_parity_transport.md (Open Design transport for the real-UI loop), applied with sk-interface-design's judgment |

Smart Router Pseudocode

> Resilience pattern: see [sk-doc smart-router template](../sk-doc/assets/skill/skillsmartrouter.md). Guard paths, discover at runtime, derive a routing key, score intents, fall back when unsure.

from pathlib import Path

SKILL_ROOT = Path(__file__).resolve().parent
RESOURCE_BASES = (SKILL_ROOT / "references",)
DEFAULT_RESOURCE = "references/od_cli_reference.md"

INTENT_MODEL = {
    "WIRE": {"keywords": [("install", 4), ("wire", 4), ("connect", 3), ("mcp add", 4)]},
    "READ": {"keywords": [("read", 3), ("list", 3), ("search", 3), ("design system", 4), ("tokens", 3), ("reuse", 3), ("ground", 3)]},
    "RUN":  {"keywords": [("run", 3), ("generate", 4), ("commission", 4), ("start_run", 4), ("artifact", 3)]},
}

RESOURCE_MAP = {
    "WIRE": ["references/mcp_wiring.md", "references/od_cli_reference.md"],
    "READ": ["references/tool_surface.md", "references/od_cli_reference.md"],
    "RUN":  ["references/tool_surface.md", "references/od_cli_reference.md"],
}

# ⛔ HARD COUPLING: any RUN, or any READ that feeds a design decision, is design
# work and MUST load sk-interface-design and run its ground -> token-system ->
# critique BEFORE any design output. mcp-open-design owns the transport; the
# judgment is sk-interface-design's and is non-negotiable. A design step composed
# without it is blocked (see design_gate below). Pure WIRE / bare inventory is exempt.
DESIGN_INTENTS = {"READ", "RUN"}

UNKNOWN_FALLBACK_CHECKLIST = [
    "Confirm the direction: wire the MCP server, read local content, or commission a run",
    "Confirm the Open Design desktop app is running (the daemon hosts every tool call)",
    "Confirm the od CLI path: node \"/Contents/Resources/app/prebundled/daemon/daemon-cli.mjs\"",
    "For RUN or any mutating verb, confirm the user wants a write and name the target project",
]

AMBIGUITY_DELTA = 1

def _guard_in_skill(relative_path: str) -> str:
    resolved = (SKILL_ROOT / relative_path).resolve()
    resolved.relative_to(SKILL_ROOT)            # raises if path escapes the skill
    if resolved.suffix.lower() != ".md":
        raise ValueError(f"Only markdown resources are routable: {relative_path}")
    return resolved.relative_to(SKILL_ROOT).as_posix()

def discover_markdown_resources() -> set[str]:
    docs = []
    for base in RESOURCE_BASES:
        if base.exists():
            docs.extend(p for p in base.rglob("*.md") if p.is_file())
    return {d.relative_to(SKILL_ROOT).as_posix() for d in docs}

def classify_intents(request: str):
    text = (request or "").lower()
    scores = {i: 0 for i in INTENT_MODEL}
    for intent, cfg in INTENT_MODEL.items():
        for kw, w in cfg["keywords"]:
            if kw in text:
                scores[intent] += w
    ranked = sorted(scores.items(), key=lambda kv: kv[1], reverse=True)
    primary, top = ranked[0]
    if top == 0:
        return ("READ", None, scores)
    secondary, second = ranked[1]
    if second > 0 and (top - second)  token-system -> critique;
                                        # RAISE/BLOCK if skipped. Never produce UI without it.

def route_open_design_resources(request: str, feeds_design_decision: bool = False):
    inventory = discover_markdown_resources()
    primary, secondary, scores = classify_intents(request)
    intents = [primary] + ([secondary] if secondary else [])
    design_gate(intents, feeds_design_decision)   # ⛔ blocks any design step missing sk-interface-design
    loaded, seen = [], set()

    def load_if_available(rel: str):
        guarded = _guard_in_skill(rel)
        if guarded in inventory and guarded not in seen:
            load(guarded); loaded.append(guarded); seen.add(guarded)

    load_if_available(DEFAULT_RESOURCE)
    if max(scores.values() or [0]) /api/*`), and the in-app Skills. The HTTP port is **ephemeral and rotates on every daemon restart**, so never hardcode it. Rediscover it from `GET /api/mcp/install-info` (the canonical config source) or the socket. The socket-based `od` CLI is stable across restarts, only the HTTP port moves. Full HTTP detail: [`references/od_cli_reference.md`](references/od_cli_reference.md).

### Wire Direction (od mcp install)

```bash
node "$OD_BIN" mcp install opencode --print --json    # PREVIEW only, writes nothing
node "$OD_BIN" mcp install opencode                    # deep-merges ~/.config/opencode/opencode.json (mcp.open-design)
node "$OD_BIN" mcp install claude --print --json       # PREVIEW
node "$OD_BIN" mcp install claude                       # runs: claude mcp add --scope user open-design ...

The installed entry is {"type":"local","command":["","","mcp"],"enabled":true,"environment":{"OD_DATA_DIR":"...","OD_SIDECAR_IPC_PATH":".../daemon.sock","ELECTRON_RUN_AS_NODE":"1"}}. The canonical source for this entry is GET /api/mcp/install-info, where command[0] is the "Open Design Helper" Electron binary, args is [, "mcp"], and daemonUrl is the live HTTP base. The MCP server re-discovers the live ephemeral daemon URL from the socket on each spawn, so the config stays valid across daemon restarts. Run --print --json first and read the exact command/env it will write. Full detail + manual config: [references/mcp_wiring.md](references/mcp_wiring.md).

Read Direction (the safe default)

After wiring, the agent calls Open Design's MCP tools. The read-only tools are always safe: list_projects, get_active_context (what the user has open now), get_project, get_file, search_files, list_files, get_artifact, list_skills, list_plugins, list_agents, get_run. From the terminal directly: node "$OD_BIN" tools design-systems read --path reads a registered design system's pull-layer files. A design system is a DESIGN.md (9-section prose) + a paste-ready tokens.css (:root block) + an optional components.html.

Run Direction (gated, multi-turn)

Generation is multi-turn, not one-shot. A single start_run (MCP) or od run start (CLI) fires turn 1 only, which returns a GenUI discovery question-form (the inner agent asking about fidelity, data, and behaviour, with recommended defaults) and ends awaiting_input with zero files. A run that stops here produces no design.

> ⛔ MANDATORY before turn 1. Load sk-interface-design and run its ground → token-system → critique on the subject. The brief you pass to start_run (--message) and every od ui respond answer MUST be shaped by that judgment — Open Design generates, it does not decide the design. A run composed without sk-interface-design is not permitted.

# Turn 1: commission the run. Returns a discovery question-form, 0 files, awaiting_input.
node "$OD_BIN" run start --project  --message "" \
  --plugin od-new-generation --agent claude --json
# Answer the form to fire the BUILD that writes the design:
node "$OD_BIN" ui list --run  --json                 # find the surfaceId
node "$OD_BIN" ui respond --run   --value "use the recommended defaults"
#   --value-json  for structured answers, or --skip to accept the defaults.
#   A follow-up message ("use the recommended defaults") works too.

The inner agent is claude / codex / gemini (per od run start --help). opencode also works (verified live) and needs an explicit --model , or the run uses opencode's default (shown as "model":null in the run's events.jsonl start event).

Answering the form fires a build run that writes the design files (index.html and friends). Only then does the project gain an entryFile and a previewUrl and actually render. Poll get_run(runId) and fetch with get_artifact. CLI run verbs: od run start|watch|cancel|list|info. Other headless write verbs: od automation (schedule or fire routines) and od media generate. Every one is mutating and a STOP-and-confirm point (see Rules + [references/tool_surface.md](references/tool_surface.md)).

> Adding a file is not creating a design. od artifacts create --name --input only adds one file to a project. It does NOT create a rendered design and does NOT update the project preview. To create a design that renders, use the multi-turn flow above, never artifacts create.

Verify the live tool set

The od mcp --help text lists only a documentation subset (8 tools); the running server registers ~18 (including write_file, create_project, start_run, and destructive delete_file/delete_project). Always verify the live tools/list before promising a tool exists or is read-only, and gate every mutating/destructive one.


4. RULES

ALWAYS

  1. ALWAYS locate the CLI as node "/Contents/Resources/app/prebundled/daemon/daemon-cli.mjs" (or the ELECTRON_RUN_AS_NODE=1 form). Never assume a global od on PATH, and never hardcode 127.0.0.1:7456 or any HTTP port - the desktop daemon is socket-discovered, and its HTTP port is ephemeral and rotates on every daemon restart. Rediscover it from GET /api/mcp/install-info (daemonUrl) or the socket.
  2. ALWAYS confirm the Open Design desktop app is running first. The daemon it hosts answers every tool call. If it is closed, the socket is gone and calls fail.
  3. ALWAYS verify the live tools/list before relying on a tool's name or read-only status. The help text undercounts; the real surface is ~18 tools and includes mutating and destructive ones.
  4. ALWAYS gate every mutating or destructive verb behind explicit user confirmation, an explicit target project/name, and a one-line rollback note. This covers create_artifact, write_file, create_project, start_run, cancel_run, delete_file, delete_project, and the od artifacts/media/automation/ui/memory/plugin write verbs.
  5. ALWAYS run sk-interface-design BEFORE and THROUGHOUT any design step — a hard precondition. For any generation/RUN, and any READ that feeds a design decision, load sk-interface-design, run ground -> token-system -> critique, and shape the brief and discovery-form answers with it. Thi

…

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.