Quickstart
Try it in 10 seconds (no clone): npx parley-protocol demo runs a narrated session with two services, a human's policy, consent and undo, over real sockets. Or try it in your browser →
npm install parley-protocol # TypeScript/JavaScript: Node ≥ 20, Bun, Deno (web-standard APIs only)
pip install parley-protocol # Python ≥ 3.10Packages aren't published yet. Until they are:
git clone, thennpm install && npm run build && npm link -w parley-protocolfor theparleyCLI, andpip install ./python.
Build a service
import { service, update, send, clarify } from "parley-protocol";
import { listen } from "parley-protocol/node";
const cal = service({ id: "cal.example.com", name: "Calendar", summary: "Move meetings.", trust: [PRINCIPAL_KEY] })
.ask("calendar.agenda", {
summary: "Upcoming events",
params: { "day?": "date" },
run: ({ params }) => db.events(params.day),
})
.intent("calendar.reschedule", {
summary: "Move a meeting",
params: { event: "string — id or title", to: "datetime" },
plan: ({ params }) => {
const matches = db.find(params.event);
if (matches.length > 1) return clarify("Which one?", matches.map((e) => ({ label: e.title, params: { event: e.id } })));
const e = matches[0], before = e.start;
return {
summary: `Move "${e.title}" to ${params.to}`,
effects: [update(`event/${e.id}`, "start", before, params.to), send(e.owner, "updated invite")],
apply: () => db.move(e.id, params.to), // runs only on COMMIT, at most once
revert: () => db.move(e.id, before), // present, so the proposal is undoable
undoWindow: 86400,
};
},
});
await listen(cal); // parley://127.0.0.1:7447, or serveHttp(cal) / fetchHandler(cal) for Workers, Bun and DenoParams are validated against the compact schema automatically, and typos get fixes like rename `dya` to `day` . Budgets, EXPAND, idempotent commits, replay protection, grant verification, spend accounting and consent are all handled for you.
Act as an agent
import { connect } from "parley-protocol/node";
const cal = await connect("parley://cal.example.com", { key: AGENT_SEED, grants: [GRANT] });
const r = await cal.intent("calendar.reschedule", { event: "Ana", to: "2026-09-24T15:00:00Z" }, { auto: true });
console.log(r.lens); // ← give this to your model
if (r.kind === "PROPOSALS") await cal.commit(r.proposals[0]);Python has the same concepts in snake_case (issue_grant, consent_grant, lens, connect), with decorators and a Plan dataclass instead of chaining. The CLI and MCP bridge are TypeScript-only. See python/README.md.
Delegate like you mean it
parley init # your principal key + an agent key (~/.parley)
parley grant --svc cal.example.com --svc shop.example \
--risk low --per 40USD --spend 100USD --exp 8h # signed policy for your agent
parley inspect <token> # read any grant chain
parley delegate <token> --to <sub-agent key> --verbs ASK,INTENT # narrower authority for a sub-agent
parley approve <pc1.code> # review and sign a one-time consent for one proposal
parley examples # serve the example calendar + shop locally
parley do parley://127.0.0.1:7447 calendar.reschedule event=Ana # interactive: intent → pick → commitNext
- Intents and proposals: the loop every Parley service speaks.
- Build a service: capabilities, plans, errors that teach.
- Python: the same protocol in Python.
- Security model: where the principal key must live.