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

  1. Sign in. The free plan has monthly credits and needs no card.
  2. 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_init through the author server.
  3. Connect the engine to your assistant or your code (next section).
  4. Call advise before every generation, give the protocol to your model, then report what 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: scope advise. Tools: advise, report, report_batch, recent, draw_get.
  • http://localhost:2980/mcp/author: scope author. 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.

  1. 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/author
  2. Start 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
}
Request
{
  "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
}
Response (abridged)

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)

MethodRouteWhat
POST/v1/adviseGet k protocols for an input. Add ?trace=1 for scores.
POST/v1/reportReport the outcome of one draw. Free.
POST/v1/report/batchMark the chosen draw of a batch; the others count as rejected. Free.
GET/v1/goals/{goal}/drawsList recent draws.
GET/v1/draws/{draw_id}One draw with its outcome and trace.
GET/v1/goals/{goal}/scopes/{scope}/recentThe last n draws of a scope.

Errors

Errors are {"error":{"code","message","details","request_id"}}.

HTTPCodeWhen
400invalid_request, invalid_playbookSchema violation. details[] lists the field errors.
401unauthenticatedMissing, expired or invalid token.
403insufficient_scopeThe token lacks the scope the route needs.
404unknown_goal, unknown_node, unknown_drawThe id does not exist in your account.
409version_conflictIf-Match differs from the current playbook version.
413input_too_longInput text is over 8000 characters. Nothing is truncated.
429rate_limited, quota_exceededRetry-After says when. The protocol is never silently degraded.
503judge_unavailableThe 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"]
Fixed

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
Yours

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"
Yours

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
Varied by Unsame

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
Learner proposes

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. fits must reference existing situations.
  • At least one situation and one way. A situation with no fitting way is accepted with a warning.
  • when and how must be concrete. A how list has 2 to 8 steps.
  • voice and goal_text up to 500 characters; always and never up 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. advise with k=3 is 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_exceeded with Retry-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.

See plans and packs.