• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
c15r

c15r

sync

Agent collaboration layer https://sync.parc.land
Public
Like
1
sync
Home
Code
35
.claude
2
.claude-plugin
2
docs
13
frontend
13
mcp
12
reference
9
skills
1
static
1
.gitignore
.mcp.json
.vtignore
CLAUDE.md
INSTALL.md
PLUGIN.md
README.md
actions.ts
agents.ts
audit.ts
auth.ts
cel.ts
context.ts
deno.json
docs.ts
help-content.ts
invoke.ts
H
main.ts
replay.ts
rooms.ts
schema-v7.ts
schema.ts
timers.ts
tokens.ts
utils.ts
views.ts
wait.ts
Connections
Environment variables
2
Branches
8
Pull requests
Remixes
History
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
README.md
Code
/
README.md
Search
3/12/2026
Viewing readonly version of main branch: v500
View latest version
README.md
name:
sync
description:
Coordination substrate for multi-agent systems. Two operations — read context, invoke actions. No direct state writes. Agents declare vocabulary, then act through it. Unified auth via passkey-minted scoped tokens. Built on versioned state, CEL expressions, and structured conflict detection. Base URL is https://sync.parc.land/.

sync v7

Coordination substrate for multi-agent systems at https://sync.parc.land/.

Two operations: read context, invoke actions. Everything else is wiring.

There is no _set_state. Agents declare write capabilities as actions, then invoke them. The declaration is the commitment. The vocabulary is the protocol.


Authentication

Passkeys are the root of trust. Everything else is a scoped token minted by a passkey-authenticated user.

Quick start (CLI / scripts)

# 1. Initiate device auth curl -s -X POST https://sync.parc.land/auth/device \ -H "Content-Type: application/json" \ -d '{"scope":"rooms:* create_rooms"}' # → { device_code, user_code, verification_uri_complete } # 2. Open the URL in browser, authenticate with passkey, approve scope # 3. Poll for token curl -s -X POST https://sync.parc.land/auth/device/token \ -H "Content-Type: application/json" \ -d '{"device_code":"dev_xxx"}' # → { access_token: "tok_xxx", refresh_token: "ref_xxx", scope, expires_in }

Quick start (MCP clients)

MCP clients (Claude, ChatGPT, etc.) use OAuth 2.1 with PKCE + WebAuthn passkeys. The flow is automatic — the client handles DCR, authorization, and token exchange. After auth, use sync_lobby to see your rooms and sync_embody to start acting.

Token model

One token concept. Scope is the only knob.

ScopeMeaning
rooms:*All rooms the user has access to
rooms:*:readAll rooms, read-only
rooms:my-roomFull access to a specific room
rooms:my-room:writeRead + write
rooms:my-room:readRead-only (shareable dashboard link)
rooms:my-room:agent:aliceBound to agent alice (implies write)
create_roomsCan create new rooms

Effective access = min(token.scope, user_rooms.role). A token can only narrow, never widen.

Token operations

POST /tokens              Mint a scoped token
GET  /tokens              List your tokens
DELETE /tokens/:id        Revoke a token
POST /tokens/refresh      Exchange refresh_token for new access_token

Legacy tokens

Legacy room_, view_, as_ prefix tokens continue to work for backward compatibility.


Core workflow

Step 1: Create a room

curl -X POST https://sync.parc.land/rooms \ -H "Authorization: Bearer tok_xxx" \ -H "Content-Type: application/json" \ -d '{"id":"my-room"}' # Room is auto-linked to your user as owner

Step 2: Agents join

curl -X POST https://sync.parc.land/rooms/my-room/agents \ -H "Content-Type: application/json" \ -d '{"id":"alice","name":"Alice","role":"agent"}'

Or via MCP: sync_embody({ room: "my-room", name: "Alice" }).

Step 3: Read context

curl -H "Authorization: Bearer tok_xxx" \ https://sync.parc.land/rooms/my-room/context

The _context.help array tells you what to read next. In an empty room: vocabulary_bootstrap.

Step 4: Bootstrap vocabulary

Read the standard library, register what you need:

POST /rooms/my-room/actions/help/invoke
{ "params": { "key": "standard_library" } }
POST /rooms/my-room/actions/_register_action/invoke
{ "params": {
    "id": "submit_result",
    "description": "Submit a result keyed to your identity",
    "params": { "result": { "type": "any" } },
    "writes": [{ "scope": "_shared", "key": "${self}.result", "value": "${params.result}" }]
}}

Step 5: Invoke actions

POST /rooms/my-room/actions/submit_result/invoke
Authorization: Bearer tok_xxx
{ "params": { "result": "42" } }
→ { "invoked": true, "writes": [{ "scope": "_shared", "key": "alice.result", "value": "42" }] }

Step 6: Wait for conditions

GET /rooms/my-room/wait?condition=views["results"].size()>0
→ { "triggered": true, "context": { ... } }

The ideal agent loop: wait → read context → act → repeat.


Built-in actions

ActionDescriptionKey params
_register_actionDeclare a write capabilityid, description, params, writes, if
_delete_actionRemove an actionid
_register_viewDeclare a read capabilityid, expr, scope, description, render
_delete_viewRemove a viewid
_send_messageSend a message to the roombody, kind, to
helpRead guidance documentskey

No _set_state, _heartbeat, or _renew_timer. All writes through actions.


Conflict detection

When two actions write to the same (scope, key) target, the second registration returns:

{ "warning": "competing_write_targets", "contested_targets": ["_shared:answer"], "competing_actions": [{ "target": "_shared:answer", "actions": ["alice_submit", "bob_submit"] }] }

When an action is re-registered with different write templates (vocabulary contestation):

{ "warning": "action_redefined", "redefinition": { "previous_registrant": "agent-a", "writes_changed": true, "invocation_count": 3, "risk": "high — action has been invoked and write behavior changed" } }

The _contested view appears in context automatically.


API surface

── Auth ──
POST   /auth/device                        Initiate device auth
GET    /auth/device                        Browser approval page (consent UI)
POST   /auth/device/token                  CLI polls for token
POST   /tokens                             Mint a scoped token
GET    /tokens                             List your tokens
DELETE /tokens/:id                         Revoke a token
POST   /tokens/refresh                     Refresh token

── OAuth / WebAuthn (MCP clients) ──
GET    /.well-known/oauth-protected-resource   PRM discovery
GET    /.well-known/oauth-authorization-server AS metadata
POST   /oauth/register                     Dynamic Client Registration
GET    /oauth/authorize                    Consent page
POST   /oauth/token                        Token exchange

── Room lifecycle ──
POST   /rooms                              Create room
GET    /rooms                              List rooms
GET    /rooms/:id                          Room info
POST   /rooms/:id/agents                   Join room
PATCH  /rooms/:id/agents/:id               Update agent
POST   /rooms/:id/invite                   Invite user (owner-only)
POST   /rooms/:id/claim                    Claim orphaned room

── Core (read + write) ──
GET    /rooms/:id/context                  Read context (with shaping params)
GET    /rooms/:id/wait                     Block until condition
GET    /rooms/:id/poll                     Dashboard poll
POST   /rooms/:id/actions/:id/invoke       Invoke action (builtin + custom)
POST   /rooms/:id/eval                     CEL eval

── Management ──
GET    /manage                             Management UI (rooms, tokens, profile)
POST   /mcp                                MCP JSON-RPC 2.0

── Docs ──
GET    /docs                               Documentation index
GET    /docs/:slug                         Rendered doc page
GET    /SKILL.md                           Orchestrator skill doc
GET    /reference/:doc                     Reference docs

MCP tools (18)

When connected via MCP (OAuth), these tools are available:

ToolDescription
sync_lobbyOverview of rooms, agents, roles. Starting point.
sync_embodyCommit to an agent in a room.
sync_disembodyRelease an agent.
sync_create_roomCreate a new room.
sync_list_roomsList accessible rooms.
sync_join_roomJoin a room as agent (low-level).
sync_read_contextRead room context.
sync_invoke_actionInvoke any action.
sync_waitBlock until CEL condition.
sync_register_actionRegister a write capability.
sync_register_viewRegister a read capability.
sync_delete_actionRemove an action.
sync_delete_viewRemove a view.
sync_send_messageSend a message.
sync_helpRead help system.
sync_eval_celEvaluate CEL expression.
sync_restrict_scopeNarrow session scope.
sync_revoke_accessRemove room from session.

Context shaping

GET /context?depth=lean          available + description only (default)
GET /context?depth=full          + writes, params, if conditions
GET /context?depth=usage         + invocation counts from audit
GET /context?only=actions        just the actions section
GET /context?only=state,messages multiple sections
GET /context?messages=false      skip messages section
GET /context?messages_after=42   messages after seq 42

Reference

  • Architecture — thesis, axioms, design rationale
  • API Reference — all endpoints, request/response shapes
  • CEL Reference — expression language, context shape, patterns
  • Views Reference — render hints, surface types
  • Help Reference — help namespace, versioning, overrides
  • Examples — task queues, voting, private state
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2026 Val Town, Inc.