npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

open-design-mcp

v0.16.1

Published

MCP stdio server bridging coding agents to Open Design daemon (BYOK flow with full systemPrompt fidelity).

Readme

open-design-mcp

A stdio Model Context Protocol server that bridges coding agents (OpenCode, Claude Code, Cursor, Zed) to a running Open Design daemon — so you can list projects, fetch artifacts, and (in upcoming releases) generate full design artifacts via BYOK from inside your editor.

Status

v0.15.0 — 10 MCP tools live. The server activates the full Open Design feature surface: list/inspect projects, save and lint artifacts, persist files inside projects, format Turn 3 prompts, and generate designs via BYOK with the full upstream system-prompt fidelity. See open OpenSpec changes for in-flight work and closed changes for historical decisions.

Tools

| Tool | Verb | Env vars required | Description | |---|---|---|---| | od_list_projects | read | OD_DAEMON_URL | List all projects from the OD daemon. Returns {projects: [{id, name, kind?, status?}, …]}. | | od_get_project | read | OD_DAEMON_URL | Fetch a project + its artifact files. Merges GET /api/projects/:id and GET /api/projects/:id/files. Now also surfaces customInstructions, fidelity, skillId, designSystemId, createdAt, updatedAt when set on the project (#56). | | od_create_project | write | OD_DAEMON_URL | Create a new project. Requires a client-supplied id matching /^[A-Za-z0-9._-]{1,128}$/ plus name; optional kind, fidelity, customInstructions, skillId, designSystemId, pendingPrompt. Returns the project details and an auto-seeded conversation ID. customInstructions is also mirrored to metadata.customInstructions for daemon compat (#43). | | od_update_project | write | OD_DAEMON_URL | Update a project's name, custom instructions, or metadata. At least one mutable field is required. customInstructions is also mirrored to metadata.customInstructions for daemon compat (#43). | | od_delete_project | write | OD_DAEMON_URL | PERMANENTLY delete a project (database row + on-disk directory). Cannot be undone. | | od_save_artifact | write | OD_DAEMON_URL | Persist an HTML artifact to the daemon's global artifact store at /app/.od/artifacts/<timestamp>-<identifier>/index.html. Args: identifier (URL-safe slug, /^[a-z0-9-]+$/, 3–64 chars), title (human-readable, 1–200 chars), html (full document). NOT project-scoped — saved artifacts do not appear in od_get_project.files. Returns the saved path + URL. | | od_save_project_file | write | OD_DAEMON_URL | Persist a file inside a project so it appears in od_get_project.files[] and renders in the daemon UI. Wraps POST /api/projects/:id/files. Args: projectId (1–128 chars), name (file name, no path separators, 1–255 chars), content (string, max ~5 MB). Unlike od_save_artifact (global store), this is project-scoped — use it when you want the file to show up under the project's viewer. | | od_lint_artifact | validate | OD_DAEMON_URL | Lint a raw HTML document. Takes { html } only — inline content, not a project/slug reference. Returns findings + agent message. | | od_compose_brief | format | none | Format a Turn 3 prompt for od_generate_design. Combines form answers, brand spec, and page brief into a string upstream Open Design recognizes. Pure function — no network, no env vars. | | od_generate_design | generate (streaming) | OD_DAEMON_URL + BYOK_BASE_URL + BYOK_API_KEY + BYOK_MODEL (BYOK_PROVIDER optional, defaults to openai) | Generate a design via the BYOK pipeline. Composes the upstream Open Design system prompt and proxies through the OD daemon's /api/proxy/<provider>/stream. Returns the accumulated text. Reads customInstructions from metadata.customInstructions first, then top-level field (#43). Accepts maxTokens (default 64000) to control completion length — see #36. |

Only od_generate_design requires the BYOK vars. The other 9 tools work with just OD_DAEMON_URL (or no env vars in the case of od_compose_brief).

od_save_project_file vs od_save_artifact: These two write tools serve different storage scopes. od_save_artifact writes to the daemon's global artifact store — useful for shareable URLs that aren't tied to a project. od_save_project_file writes inside a project's directory so the file appears in od_get_project.files[] and renders in the daemon's project UI. Use od_save_project_file when you want the generated design to live inside the project; use od_save_artifact for standalone, project-unaware artifacts.

How it works

When you invoke od_generate_design with a PRD-style prompt, the MCP server composes a ~20–50 KB system prompt locally (vendored composeSystemPrompt injects designer charter + kind-specific rules), then POSTs to the OD daemon's /api/proxy/<provider>/stream endpoint. The daemon is a thin pass-through proxy — it forwards to your BYOK provider, transcodes the upstream stream into its own SSE format, and streams tokens back. The MCP server accumulates deltas and emits notifications/progress every 25 tokens (only when the client supplied a progressToken, per MCP spec).

Typical timing: ~10 seconds for small sections (single hero, paragraph rewrite); 1–5 minutes for full pages; up to 10 minutes for complex multi-section designs. Set maxTokens (default 64000) to control completion length — full pages typically need 30000+ tokens; the daemon's silent default was 8192 (#36). Server timeout defaults to 10 minutes (OD_GENERATE_TIMEOUT_MS, configurable). On abort or timeout mid-stream, accumulated tokens are returned as partial HTML with a trailing <!-- Generation timed out... --> comment marker and isError: true — pair with od_save_artifact to checkpoint partial progress.

Full reference with file:line citations: docs/architecture/generate-design-flow.md.

sequenceDiagram
    autonumber
    participant E as Editor
    participant M as open-design-mcp
    participant D as OD daemon
    participant P as BYOK proxy
    E->>M: tools/call od_generate_design
    M->>M: composeSystemPrompt + lazy BYOK load
    M->>D: POST /api/proxy/openai/stream
    D->>P: POST /chat/completions stream true
    loop SSE tokens
        P-->>D: delta
        D-->>M: event delta
    end
    M-->>E: tool result HTML

Installation

Add the following entry to your MCP client config (OpenCode / Claude Code / Cursor / Zed):

{
  "mcp": {
    "open-design": {
      "command": "npx",
      "args": ["-y", "open-design-mcp"],
      "env": {
        // Pick the line that matches your deployment (see "Choosing OD_DAEMON_URL" below)
        "OD_DAEMON_URL": "http://ai-open-design:7456",
        "OD_API_TOKEN": "",                            // optional; bearer token if your daemon requires it
        // BYOK vars — only needed if you call od_generate_design
        "BYOK_BASE_URL": "https://your-ai-proxy.example.com/v1",
        "BYOK_API_KEY": "<provider-api-key>",
        "BYOK_MODEL": "open-design",
        "BYOK_PROVIDER": "openai"                      // optional; one of openai/anthropic/azure/google/ollama
      }
    }
  }
}

The server boots successfully with only OD_DAEMON_URL set — the BYOK vars are validated lazily when od_generate_design is invoked. This lets users explore via od_list_projects / od_get_project before wiring an AI provider.

Choosing OD_DAEMON_URL

The right value depends on where the Open Design daemon is running relative to the MCP server (which itself runs wherever your coding agent spawns it):

| Your setup | OD_DAEMON_URL | |---|---| | MCP server + OD daemon both run as containers on a shared Docker network (e.g. via ai-sandbox-wrapper with --network ai-sandbox) — most common | http://ai-open-design:7456 | | MCP server runs inside a Docker container, OD daemon runs natively on the host (exposed on host port 7456) | http://host.docker.internal:7456 (macOS / Windows Docker Desktop)http://172.17.0.1:7456 (Linux bridge gateway) | | MCP server and OD daemon both run natively on the host (no Docker) | http://localhost:7456 | | OD container started via ai-run open-design start --expose --port N to host port N | http://host.docker.internal:N (from inside another container)http://localhost:N (from host) |

Quick diagnostic (run from the environment where the MCP server will spawn):

curl -fsS http://ai-open-design:7456/ && echo " OK"          # shared docker network
curl -fsS http://host.docker.internal:7456/ && echo " OK"    # host gateway
curl -fsS http://localhost:7456/ && echo " OK"               # native

Whichever one returns 200 is your correct OD_DAEMON_URL.

Environment Variables

| Variable | Purpose | Required by | Default | |---|---|---|---| | OD_DAEMON_URL | Open Design daemon base URL — see Choosing OD_DAEMON_URL above | all tools (validated eagerly at startup) | — | | OD_API_TOKEN | Bearer token the OD daemon enforces when bound to non-loopback | optional | "" (no auth header sent) | | OD_AUTH_MODE | Auth mode: none, bearer, or basic. Auto-derived if unset (token set → bearer; basic creds set → basic; neither → none) | optional | inferred | | OD_BASIC_USER | HTTP Basic Auth username | OD_AUTH_MODE=basic | — | | OD_BASIC_PASS | HTTP Basic Auth password | OD_AUTH_MODE=basic | — | | OD_GENERATE_TIMEOUT_MS | Server-side timeout for od_generate_design, in milliseconds. Raised from the previous 120s after #33 confirmed full-page generations legitimately exceed it. | optional | 600000 (10 min) | | BYOK_BASE_URL | OpenAI-compatible AI provider base URL | od_generate_design only (validated lazily) | — | | BYOK_API_KEY | Provider API key forwarded via OD's /api/proxy/*/stream | od_generate_design only | — | | BYOK_MODEL | Model id (e.g. open-design, claude-sonnet-4-6) | od_generate_design only | — | | BYOK_PROVIDER | One of openai / anthropic / azure / google / ollama | optional | openai |

The server fails fast with a clear stderr message if OD_DAEMON_URL is missing or invalid. BYOK vars are checked only when od_generate_design is called — a missing var yields a friendly tool-level error (isError: true, text "BYOK not configured: missing ..."), never a crash.

Hosted Open Design deployment (HTTP Basic Auth)

If the OD daemon is behind a reverse proxy with HTTP Basic Auth (e.g. the publicly-hosted instance at https://od.thnkandgrow.com/), set OD_AUTH_MODE=basic with the matching credentials:

{
  "mcp": {
    "open-design": {
      "command": "npx",
      "args": ["-y", "open-design-mcp"],
      "env": {
        "OD_DAEMON_URL": "https://od.thnkandgrow.com/",
        "OD_AUTH_MODE": "basic",
        "OD_BASIC_USER": "<your-username>",
        "OD_BASIC_PASS": "<your-password>"
      }
    }
  }
}

The server emits Authorization: Basic <base64(user:pass)> on every request to the OD daemon. Embedded credentials in the URL (https://user:pass@host/) are rejected at startup — use the env vars instead.

Development

nvm use            # picks Node 20 per .nvmrc
npm install
npm run lint
npm run typecheck
npm test
npm run build
npm run test:integration   # spawns dist/src/server.js, mocks the OD daemon, exercises all 8 tools

The engineering harness (docs/HARNESS.md) requires every feature, fix, or refactor to go through an OpenSpec proposal → deep-design → specs → implement → validate → review → PR → archive cycle. See docs/stories/ for in-flight stories.

Vendored Dependencies

This project vendors a subset of source from nexu-io/open-design (Apache License 2.0) so we can compose the same systemPrompt the Open Design web UI builds for its BYOK chat turns — without depending on the upstream's private @open-design/contracts package.

| Path | Upstream | License | Notes | |---|---|---|---| | vendor/od-contracts/ | nexu-io/open-design packages/contracts/src/ | Apache-2.0 | 13 files (7 runtime + 6 type-only). Pinned commit + re-sync instructions in vendor/od-contracts/VENDORED_FROM.md. Sync script at scripts/vendor-sync.sh. |

License compliance:

All vendored code is redistributed under the same Apache License 2.0.

License

Apache License 2.0. See LICENSE for the full text and NOTICE for attribution.

Copyright (c) 2026 kokorolx [email protected].