Warning
This repository is archived.
Archived on 2026-09-08 by the AI Catalyst Platform Team. It is read-only and no longer maintained.
---
A negative-constraint memory layer for AI agents.
Teach agents what to avoid repeating — without dumping memory into every prompt.
Juice is a small MCP server for durable avoidance constraints: things an AI agent should not do again.
It is not a general memory store. It deliberately stores only negative guidance: what to avoid, stop doing, prohibit, or not repeat. Positive preferences and "always do this" instructions are rejected unless they can be converted into a clear avoided alternative.
Juice keeps constraints scoped, categorized, and out of context until they are actually relevant to a task.
AI agents repeat mistakes. Full memory files are noisy. Project rules get too large. Juice sits between those extremes:
- Save small corrections like "Avoid generic copy when direct writing is appropriate."
- Scope constraints to
global,project,repo, oragent. - Expose a tiny manifest so agents can decide whether Juice is relevant.
- Fetch only the few matching constraints for the current task.
- Keep old positive notes inert instead of silently treating them as constraints.
- Work with OpenCode, Claude Code, Cursor, Codex, and other MCP clients.
User correction
-> agent suggests a negative constraint
-> user approves, edits, or ignores it
-> Juice stores the constraint
-> future agents recall only matching constraints
Example:
Feedback:
"This copy feels too generic. Make it more direct."
Saved Juice constraint:
"Avoid generic copy when direct writing is appropriate."
Later:
An agent drafting landing page copy can recall that constraint before writing.
Each saved constraint includes:
statement— the avoidance constraint itself.scope— where it applies:global,project,repo, oragent.category— a stable category such asgeneral,design, orwriting.triggers— short terms used to decide when the constraint is relevant.confidenceandstrength— lightweight ranking signals.status—activeorretired.
New constraints are stored in juice_constraints. Legacy juice_records rows
are left inert so old positive data is not reinterpreted as negative guidance.
Juice uses a stable category registry. New databases start with:
generaldesignwriting
The manifest lists registered categories even when they are empty. Use the defaults unless a custom reusable category is clearly needed. Custom categories must be registered before constraints can use them.
HTTP clients can use:
GET /api/categories
POST /api/categoriesExample body:
{ "name": "security", "trigger_hints": ["auth", "tokens"] }Juice exposes one MCP resource and a small tool set.
| URI | What it does |
|---|---|
juice://manifest |
Returns categories, trigger hints, and scopes. It omits constraint statements. |
| Tool | What it does |
|---|---|
juice_get_manifest |
Returns the same small manifest as juice://manifest. |
juice_prepare |
Returns relevant avoidance constraints for a task. |
juice_suggest |
Suggests an avoidance constraint without saving it. |
juice_add_category |
Registers a reusable category for avoidance constraints. |
juice_save |
Saves a confirmed avoidance constraint. |
juice_update |
Updates an existing avoidance constraint. |
juice_retire |
Retires an avoidance constraint without deleting it from storage. |
juice_list |
Lists saved avoidance constraints with optional filters. |
| Scope | Use it for |
|---|---|
global |
Personal constraints that should carry across projects. |
project |
Constraints for a specific product, brand, or project. |
repo |
Constraints tied to one codebase. |
agent |
Constraints about one client, model, or agent behavior. |
Juice can run as a small HTTP app with:
- A mobile-friendly web UI.
- PWA/iOS home-screen assets.
- No auth for the GUI and REST API by default.
- Token protection for
/mcpwhen a token is configured.
Common endpoints:
GET /
GET /api/manifest
GET /api/categories
POST /api/categories
GET /api/juices
POST /api/juices
POST /api/suggestRequires Node.js 20 or newer.
npm install
npm run buildRun as a local stdio MCP server:
node dist/cli.js stdioRun as an HTTP MCP server:
JUICE_HOST=127.0.0.1 JUICE_PORT=3055 node dist/cli.js httpIf you bind outside loopback, set a token:
JUICE_HOST=100.x.y.z \
JUICE_PORT=3055 \
JUICE_TOKEN='your-secure-token' \
node dist/cli.js httpBy default, Juice stores data here:
~/.local/share/juice/juice.sqlite
Override it with:
JUICE_DB=/path/to/juice.sqliteThe bundled skill lives here:
skills/juice/SKILL.md
Install it with skills.sh:
npx skills add . --global --copy --agent opencode --agent claude-code --agent codex --agent cursorOr copy it manually:
| Client | Global path | Project path |
|---|---|---|
| OpenCode | ~/.config/opencode/skills/juice/SKILL.md |
.opencode/skills/juice/SKILL.md |
| Claude Code | ~/.claude/skills/juice/SKILL.md |
.claude/skills/juice/SKILL.md |
| Codex | N/A | .agents/skills/juice/SKILL.md |
| Cursor | N/A | .agents/skills/juice/SKILL.md |
Restart your agent after installing or updating the skill.
Local stdio:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"juice": {
"type": "local",
"command": ["node", "/absolute/path/to/juice/dist/cli.js", "stdio"],
"enabled": true,
"timeout": 30000
}
}
}Remote HTTP:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"juice": {
"type": "remote",
"url": "http://100.x.y.z:3055/mcp",
"enabled": true,
"oauth": false,
"headers": {
"Authorization": "Bearer your-secure-token"
},
"timeout": 30000
}
}
}OpenCode also supports file substitution for tokens:
"Authorization": "Bearer {file:juice-token}"To point OpenCode at the bundled skill without copying it:
{
"skills": {
"paths": ["/absolute/path/to/juice/skills"]
}
}For local stdio clients:
{
"command": "node",
"args": ["/absolute/path/to/juice/dist/cli.js", "stdio"]
}For remote HTTP clients:
URL: http://host-or-tailscale-ip:3055/mcp
Headers:
Authorization: Bearer <your-secure-token>
Clients with MCP resource support can read juice://manifest. Other clients can
call juice_get_manifest instead.
npm test
npm run build
npm run typecheck
npm run format:check
npm run formatRemember what to avoid. Repeat fewer mistakes.