Docs
Unsame returns a protocol before each generation. Your model writes the text. These pages cover connecting it, calling it, and writing the playbook it chooses from.
Getting started
- Sign in. The free plan has monthly credits and needs no card.
- Create a goal. In the panel, describe the repeated job in one sentence and the playbook is
drafted for you (it can take up to half a minute). Or ask your assistant to run
playbook_initthrough the author server. - Connect the engine to your assistant or your code (next section).
- Call
advisebefore every generation, give the protocol to your model, thenreportwhat happened.
# The pull pattern: the model asks before it writes
tool advise(goal, scope, input, facts) # MCP, or POST /v1/advise
-> put draws[0].advice into the system prompt or the message tail
-> your model writes the text
tool report(draw_id, outcome) # always free A goal is one repeated job with a fixed strategy. A scope is a free string inside a goal (an account, an agent, a project) under which history and anti-repeat memory are kept.
Connect the MCP
Two remote MCP servers, both behind OAuth 2.1 that clients discover automatically:
http://localhost:2980/mcp/engine: scopeadvise. Tools: advise, report, report_batch, recent, draw_get.http://localhost:2980/mcp/author: scopeauthor. Tools to init, read, edit, dry-run and export a playbook, and to review the learner’s proposals.
Two servers: the engine (scope advise) calls advise before every draft; the author (scope author) edits the playbook.
Add both servers.
claude mcp add --transport http unsame-engine http://localhost:2980/mcp/engine claude mcp add --transport http unsame-author http://localhost:2980/mcp/authorStart Claude Code, run /mcp, pick each server and choose Authenticate. Your browser opens the sign-in; OAuth is discovered automatically.
HTTP API
Base URL http://localhost:2980/v1. JSON in and out; playbooks also accept application/yaml. Every response carries X-Request-Id. For
server-to-server calls create an API client in the panel under API keys and exchange it for a
token with the client_credentials grant. The Connect tab above has the three curl
calls end to end.
Advise
{
"goal": "indie_dev_x",
"scope": "acct:dk",
"input": { "text": "…what you are reacting to…" },
"facts": ["glm-5.3 test run finished the task in 14 min"],
"k": 1
} {
"batch_id": "01J…",
"playbook_version": 7,
"situations": [{ "id": "someone_post", "label": "reacting to someone's post", "p": 0.93 }],
"hooks": ["they claim local models can't do agentic coding"],
"facts": ["glm-5.3 test run finished the task in 14 min"],
"draws": [
{
"draw_id": "01J…",
"way": "build_on",
"axes": { "length": "short", "opener": "statement" },
"advice": "Situation: reacting to someone's post.\nEngage with:\n- …",
"reason": null
}
],
"miss": null
} k asks for up to that many distinct protocols (limited by your plan). Send an Idempotency-Key header and a repeated request returns the stored response without
a new draw or a new charge.
Engine routes (scope advise)
| Method | Route | What |
|---|---|---|
| POST | /v1/advise | Get k protocols for an input. Add ?trace=1 for scores. |
| POST | /v1/report | Report the outcome of one draw. Free. |
| POST | /v1/report/batch | Mark the chosen draw of a batch; the others count as rejected. Free. |
| GET | /v1/goals/{goal}/draws | List recent draws. |
| GET | /v1/draws/{draw_id} | One draw with its outcome and trace. |
| GET | /v1/goals/{goal}/scopes/{scope}/recent | The last n draws of a scope. |
Errors
Errors are {"error":{"code","message","details","request_id"}}.
| HTTP | Code | When |
|---|---|---|
| 400 | invalid_request, invalid_playbook | Schema violation. details[] lists the field errors. |
| 401 | unauthenticated | Missing, expired or invalid token. |
| 403 | insufficient_scope | The token lacks the scope the route needs. |
| 404 | unknown_goal, unknown_node, unknown_draw | The id does not exist in your account. |
| 409 | version_conflict | If-Match differs from the current playbook version. |
| 413 | input_too_long | Input text is over 8000 characters. Nothing is truncated. |
| 429 | rate_limited, quota_exceeded | Retry-After says when. The protocol is never silently degraded. |
| 503 | judge_unavailable | The judgement model failed after retries. No keyword fallback. |
Playbook format
A playbook is a versioned tree for one goal. YAML is the import and export form; the stored JSON document is isomorphic to it. Edit it in the panel, or through the author MCP.
version: 7 # server-assigned, increments on every change
goal: indie_dev_x
goal_text: "grow the account as an indie dev: one post a day, reply to mentions"
language: en
voice: "casual, concrete, no emojis"
always: ["one real example from own work"]
never: ["politics", "competitor names"] Strategy
Copied verbatim into every protocol. Never varied, never learned, never retired.
situations:
- id: world_event
label: "reacting to a news event"
when: "the input is about a news event relevant to dev tools or AI"
- id: someone_post
label: "reacting to someone's post"
when: "the input is another person's post we may react to"
- id: scheduled
label: "a planned post"
when: "no external trigger; a planned post"
default: true Situations
Plain-language conditions tested against each input. Several can be active at once; exactly one is the default.
ways:
- id: hot_take
fits: [trend, world_event]
how: "one contrarian line, backed by one fact from own experience"
- id: build_on
fits: [someone_post]
how: "quote their point, add the missing angle, end with a question back"
- id: behind_scenes
fits: [scheduled, trend]
how:
- "hook: the surprising number first"
- "setup: what we tried"
- "turn: what broke"
- "payoff: the fix, one line" Ways
Your approaches. A way fits the situations you list; steps give scripts and long forms an order.
axes:
length: [one_liner, short, medium]
opener: [statement, question, number]
variety:
recent_window: 10 # draws per scope remembered for anti-repeat
entropy_floor: 0.3 # minimum normalized entropy of the way distribution Axes and variety
Form values chosen independently of the way. The only thing Unsame varies is the choice, never your wording.
learning:
mode: propose # off | propose | auto Learning
off, propose or auto. Proposals come from inputs the playbook missed; your nodes are never touched.
Rules enforced on every write
- Ids are
[a-z0-9_]{1,64}, unique within their kind in the goal. - Exactly one situation is
default: true.fitsmust reference existing situations. - At least one situation and one way. A situation with no fitting way is accepted with a warning.
whenandhowmust be concrete. Ahowlist has 2 to 8 steps.voiceandgoal_textup to 500 characters;alwaysandneverup to 20 entries; at most 6 axes with 8 values each.
Updating a playbook with PUT needs If-Match: <version>. A stale
version returns 409 version_conflict instead of overwriting someone else’s edit.
How a way is chosen
For each candidate way that fits the active situations the engine scores fit × novelty × weight, normalises, keeps a minimum entropy so the choice never
collapses to one way, and samples from the result. It never takes the top score.
Novelty penalises recent uses in the same scope; weight comes from outcomes you report, and is
1.0 until there are any. The panel’s dry run shows this table for any input.
Learning
With learning on, inputs the playbook handled badly (no situation matched, or no way fit) are clustered and turned into proposals. Each proposal carries its evidence: example inputs and cluster size.
off: nothing is learned and no inputs are kept.propose: you accept, edit or reject each proposal. An edited proposal is re-checked before it enters.auto: proposals enter as trials and are promoted or retired by outcome data. Only on plans that allow it.
Nodes move through trial, active and retired. Nodes you
wrote are never touched. You can pin a node, ban it, or restore a retired one at any time.
Strategy (voice, always, never, goal text) is never varied, learned or retired.
Pricing mechanics
- 1 credit = 1 draw.
advisewithk=3is 3 credits. - Always free: report, report_batch, reads, stats, export and validation.
- Free plan: monthly credits, no card, no rollover. Out of credits returns
429 quota_exceededwithRetry-After. - Paid plans: included credits plus overage per credit, held under your spend cap.
- Packs: prepaid credits for API users, used after the monthly included credits and before overage.