@withfudge/design
v0.8.2
Published
Local Fudge design CLI and MCP server for querying saved pins with Prolog.
Maintainers
Readme
Fudge CLI
Local developer CLI and stdio MCP server for querying the Fudge Prolog runtime.
Setup
npx -y @withfudge/design@latest setupsetup checks local auth, starts browser login when needed, installs the local MCP server plus the fudge-search routing skill, and prints a paste-ready first prompt.
You can provide the first task up front:
npx -y @withfudge/design@latest setup "find inspiration for a credit based pricing page"Always run setup through the explicit @latest package selector. A bare globally installed fudge command can be version-pinned and is not used for onboarding or repair.
During development from this repository, install dependencies locally and run commands with tsx:
npm install --prefix fudge/cli
npx --prefix fudge/cli tsx fudge/cli/src/cli.ts --helpLocal MCP Development Loop
Use the local loop when testing MCP/server changes before publishing to npm.
node fudge/cli/scripts/local-mcp-dev.mjsThen restart or reload the MCP client. The client config starts this repo's built server directly:
node /absolute/path/to/fudge/cli/dist/cli.js mcpThat means every MCP test cycle is:
node fudge/cli/scripts/local-mcp-dev.mjsReload the client after killing the old process so it starts the new build.
To test multiple installed clients against the local build:
node fudge/cli/scripts/local-mcp-dev.mjs --all --include-undetectedTo restore the same client config back to the published npm package:
node fudge/cli/scripts/local-mcp-dev.mjs --restoreTo write a project-local config instead of the global/client config:
node fudge/cli/scripts/local-mcp-dev.mjs --project-config --cwd .Use --all --include-undetected instead of --client codex when you intentionally want to rewrite every supported client config. Config backups are written by default before existing files are changed.
Install MCP And Skill Routing
fudge install writes only the fudge MCP server entry, installs the bundled fudge-search routing skill by default, and preserves unrelated client config. The generated launcher explicitly selects @withfudge/design@latest through npm package mode, so a stale global fudge binary cannot shadow it. npm checks for the latest release whenever the client starts a new MCP process. The running server stays on one coherent version for the life of that process; the next client restart is the safe update boundary.
When a target config already exists, the CLI writes a timestamped sibling backup such as config.json.fudge-backup-... before calling the installer library. Use --no-backup to skip that backup.
fudge install --client codex
fudge install --client opencode
fudge install --client codex --local
fudge install --client codex --local --local-build
fudge install --all
fudge install --all --include-undetected
fudge install --dry-run --json
fudge install --list-clients
fudge install --client codex --no-backup
fudge install --client codex --no-skillThe first supported matrix is Codex, OpenCode, Claude Desktop, Claude Code, Cursor, Windsurf, VS Code, Gemini CLI, and Zed. Codex and OpenCode are the reference clients covered by config-level tests.
Config upsert is library-backed for the full matrix. Doctor verification is strongest for Codex and OpenCode today: those paths are covered by local config tests plus packed-package stdio handshake tests. Other clients are installable through the shared installer library, but should be manually opened once after install to verify the client loaded the fudge MCP entry.
Use --skill-only to install just the Fudge routing instructions into the local agents skill directory:
fudge install --skill-onlyThe default skill target is ~/.agents/skills/fudge-search. Override it with --skills-dir DIR or $FUDGE_SKILLS_DIR.
The bundled fudge-search skill is intentionally a small, stable router. It tells agents to read fudge://agent/guide.md from the running MCP package, which then points to the current release and presentation contracts. This keeps tool names, visual behavior, and query policy synchronized with the automatically selected package instead of freezing them into a copied skill file.
Routing support by client:
- Native skills: install
fudge-searchwithfudge install --skillfor agents that read~/.agents/skills. - AGENTS.md or instruction-file clients: copy the rules from
skills/fudge-search/SKILL.mdinto the project or client instruction file. - MCP-only clients: install the MCP server and use
fudge://agent/guide.mdplus thequery_fudge_releaseprompt for current query and presentation guidance.
To uninstall manually, remove only the fudge MCP server entry from the target client config and remove ~/.agents/skills/fudge-search if you installed the routing skill. Do not delete unrelated MCP entries or provider settings.
MCP
Start the stdio MCP server:
npx --yes --prefer-online --package=@withfudge/design@latest -- fudge mcpExample MCP client command config:
{
"command": "npx",
"args": [
"--yes",
"--prefer-online",
"--package=@withfudge/design@latest",
"--",
"fudge",
"mcp"
]
}The MCP server exposes these primary tools:
query_fudgefor raw Prolog queries.inspect_fudge_pin_screenshotsfor loading actual saved-pin screenshot pixels into the current model before visual reasoning.display_fudge_pin_cardfor embedded pin screenshot cards after pins/colors/fonts have been queried.display_fudge_color_palettefor embedded color palettes after color facts have been queried.display_fudge_font_usagefor embedded font usage previews after font facts have been queried.render_fudge_pin_cards,render_fudge_color_palette, andrender_fudge_font_usagefor non-visual fallback text.
display_fudge_pin_card is user-facing presentation, not model perception. Agents should call inspect_fudge_pin_screenshots before making visual claims or implementing UI from pin references.
query_fudge runs raw Prolog through a yield-aware SWI query loop. It returns raw bindings, answer count, truncation metadata, and timing. It does not summarize results, infer Prolog semantics, build answer programs, or render markdown.
It also exposes MCP-native release context resources:
fudge://release/info
fudge://agent/guide.md
fudge://release/skill.md
fudge://release/predicates.json
fudge://release/skill-metadata.json
fudge://presentation/guide.mdAgents should read fudge://agent/guide.md first, then follow its references to the release predicate and presentation contracts. The server also exposes the query_fudge_release prompt, which guides clients through that flow.
Generate a paste-ready first prompt without installing anything:
fudge first-prompt "find inspiration for a credit based pricing page"Auth
fudge status reads the local session from macOS Keychain during normal local use. If Keychain is unavailable, or when $FUDGE_HOME is set for development/tests, it falls back to ~/.fudge/session.json or $FUDGE_HOME/session.json with restrictive file permissions.
fudge login starts a browser-loopback OAuth flow. The CLI opens the hosted Fudge auth URL, listens on 127.0.0.1, accepts a one-time code from the browser redirect, exchanges it for a local session, and stores that session locally.
fudge loginDoctor
fudge doctor --json
fudge doctor --client codex --json
fudge doctor --client opencode --local --cwd .doctor checks package and Node versions, auth status, release availability, local runtime warmup, stdio MCP handshake, release MCP resources, routing skill status, and installed MCP config status for the requested clients.
Query
fudge query 'pin_title(Pin, Title).' --limit 1Temporary helper source can be consulted for one query. Source is passed to SWI-Prolog as opaque Prolog text:
fudge query 'helper_result(X).' \
--source 'helper_result(X) :- member(X, [one,two]).' \
--limit 2Use --source-file for local helper files. Repeat --source or
--source-file to consult multiple sources in order:
fudge query 'tailwind_theme_css("linear.app", Css).' \
--source-file ./helpers/tailwind-theme.pl \
--limit 1fudge query 'final_helper(Result).' \
--source-file ./helpers/base.pl \
--source-file ./helpers/final.pl \
--limit 1The same Tailwind helper is also available as the bundled tailwind recipe:
fudge recipe run tailwind \
--query 'tailwind_theme_css("linear.app", Css).' \
--limit 1For MCP callers, query_fudge accepts source for one helper body and
sources for ordered helper bodies. If both are provided, source is
consulted before the entries in sources.
Useful development flags:
FUDGE_LOAD_RELEASE=0
FUDGE_REFRESH_USER_MEMORY=0Or disable user-memory refresh for one command:
fudge query 'member(X, [a,b]).' --limit 2 --no-refresh-user-memorylimit caps returned bindings and closes finite enumeration after the first extra answer proves truncation. Execution timeout remains the runaway protection.
text_vector/2 uses a persistent local cache for deterministic text embeddings. Cache entries are keyed by release id, embedding vector-space id, dimensions, and normalized text, and are stored under ~/.fudge/cache/text-vectors or $FUDGE_HOME/cache/text-vectors.
Error Contract
CLI JSON failures and MCP structuredContent errors use the same shape:
{
"error": {
"code": "login_required",
"message": "Login required",
"recoverable": true,
"actor": "user",
"action": {
"type": "run_command",
"command": "fudge login",
"label": "Log in to Fudge"
}
}
}actor tells the caller who can recover:
agent: retry once or adjust the local call.user: stop retrying and ask the user to act.system: local setup, environment, or service state must change.none: no recovery path is available.
Auth gates point to fudge login. Billing and plan gates try to create an authenticated checkout session and return that URL. If checkout creation is unavailable, logged-in users fall back to https://design.withfudge.com/checkout; when login state is unavailable, they fall back to https://design.withfudge.com/.
Recipes
Recipe files are named reusable .pl files read as opaque Prolog source.
Use recipes for helpers you expect to run more than once; use fudge query
--source-file for one-off local helper files.
Project recipes:
.fudge/recipes/*.plGlobal recipes:
~/.fudge/recipes/*.plWhen $FUDGE_HOME is set, global recipes live under:
$FUDGE_HOME/recipes/*.plRecipe lookup is project first, then global, then bundled. Project recipes shadow global and bundled recipes with the same filename. Global recipes shadow bundled recipes with the same filename.
fudge recipe list
fudge recipe run colors --query 'recipe_color(X).' --limit 2Bundled recipes:
fudge recipe run tailwind --query 'tailwind_theme_css("linear.app", Css).' --limit 1
fudge recipe run contrast-ratio --query 'contrast_ratio("#111827", "#ffffff", Ratio).' --limit 1Follow-Ups
The current user-memory refresh builds saved/1, collection/1, and collection_item/2 facts client-side from authenticated JSON endpoints. A cleaner hosted endpoint, /personal/prolog-context, should eventually return opaque Prolog user-memory source directly.
