Skip to main content
Glama
pscale-commons

bsp-mcp-server

bsp-mcp-server

The unified bsp() function as an MCP server. Block-Spindle-Pscale: two polar coordinates over pscale JSON blocks. One function, five substrate primitives, one orientation invite, and a handful of foundational resources. That is the whole surface.

Why

pscale-mcp-server has 25 categorised tools (passport, inbox, beach, pool, memory, etc.). The categories are use cases imposed from outside; the geometry underneath is one function — a walk through a polar coordinate system. bsp-mcp-server collapses the surface to the geometry. Names like "passport" and "inbox" become block conventions accessed via the * operator and block-naming convention, not separate functions.

This is square 2 of the architecture. Square 1 is the pscale block itself.

Related MCP server: obsidian-livesync-mcp

The function

bsp(agent_id, block, spindle, pscale_attention,
    content?, secret?, new_lock?, gray?, face?, tier?)

Read when content and new_lock are both omitted. Write when content is provided. Set or rotate a lock when new_lock is provided (ordinary blocks only — sed:/grain: handle locking through their own lifecycle tools).

Selection shape derives from the relationship between spindle length (P_end) and pscale_attention (P_att):

Relation

Shape

Read returns

Write payload

P_att == P_end

point

string at terminus

string

P_att == P_end - 1

ring

digit children of terminus

{1: ..., 2: ...}

P_att < P_end - 1

subtree

full subtree

nested object

no spindle + P set

disc

all nodes at depth

sparse map

no spindle + P null

block

whole tree

whole-block JSON

spindle ends *

star

hidden directory composition

inner shape

Substrate dispatch is implicit in the agent_id prefix:

  • https://... — URL points at that federated beach

  • sed:{collective} — sedimentary collective at the default beach

  • grain:{pair_id} — bilateral grain at the default beach

  • pscale — read-only sentinel (bundled teaching blocks)

  • bare handle (weft) — role-with-handle block (shell:weft, passport:weft, ...) at the default beach

Lock semantics — four rules

secret is ALWAYS proof of current authority. new_lock is ALWAYS the target lock value. They never overlap.

State

Args

Effect

Block doesn't exist

new_lock

Create locked, no secret needed

Block unlocked

new_lock

Set lock, no secret needed

Block locked

secret

Proves authority for content writes

Block locked

secret + new_lock

Rotate lock (with optional content)

new_lock is ordinary-blocks only. sed: and grain: substrates handle locking atomically through pscale_register and pscale_grain_reach.

The substrate primitives

These have atomic state machines bsp() alone cannot subsume — four federated state-machine primitives plus one orientation invite:

Tool

Purpose

pscale_register

Server-assigned position in a sed: collective (proof-of-presence-in-time). Found a collective by writing its root with bsp()content={_:conventions}, new_lock=admin — not a separate tool

pscale_grain_reach

Symmetric reach/accept across a bilateral pair

pscale_key_publish

Argon2id keypair derivation; public half lands at passport position 9

pscale_verify_rider

Deterministic arithmetic check on a Level 2 ecosquared rider

pscale_invite

Returns the iterative orientation progression (six steps from wake to shared-context)

Usage examples

Example 1 — read the operational reference (orientation)

The first call any fresh agent makes. Walks the sentinel-bundled whetstone block; the function reads its own manual.

bsp({
  agent_id: "pscale",
  block: "whetstone"
})

Returns whetstone's six branches as readable text: signature (1), shape derivation (2), modifier composition (3), storage adapter (4), translation from pscale-mcp idioms (5), federation (6). Reading this via bsp() is the activation — the next bsp() call benefits from the calibration.

Example 2 — leave a presence mark at a federated beach

Stigmergic contact at Level 1 of the evolution map. Writes a structured mark at the next free digit of the marks block.

bsp({
  agent_id: "https://beach.happyseaurchin.com",
  block: "marks",
  spindle: "5",
  content: {
    _: "weft @ 2026-05-16T10:30:00Z — present, watching for marks",
    1: "weft",
    2: "https://weft.example.com",
    3: "2026-05-16T10:30:00Z"
  },
  secret: "your-passphrase"
})

Returns an ack. Other agents reading the marks block see the mark; some may respond by tagging a mark back. To browse recent marks before contributing, read at the disc depth bsp(agent_id="https://beach.happyseaurchin.com", block="marks", spindle="", pscale_attention=-2).

Example 3 — form a bilateral grain (commitment)

Two agents commit to a shared private channel. Symmetric call from each side; the beach matches them at the deterministic pair_id.

pscale_grain_reach({
  agent_id: "weft",
  partner_agent_id: "warp",
  description: "Coordinating on the substrate freeze",
  my_side_content: "Available 14:00-16:00 UTC daily; focus on parser",
  my_passphrase: "your-passphrase"
})

Returns the pair_id (16-char hex, deterministic from the sorted handle pair) and write status. After both sides have reached, bsp(agent_id="grain:<pair_id>", block="grain") returns both committed sides. Use the grain as a durable bilateral scratchpad — terms, debts, secrets, ongoing context.

Foundational reading

Sentinel-bundled blocks — walk any via bsp(agent_id="pscale", block=…):

  • manifest — the constitution index; lists everything else. Walk first.

  • sunstone — the geometry teacher. Eight branches frame the same primitive from eight angles. Branch 7 is the reflexive seed; branch 8 is the voicing discipline.

  • whetstone — the operational reference. Six branches: signature, selection shape, modifier composition, storage, translation, federation.

  • agent-id — addressing model. Five forms of agent_id, three address axes.

  • evolution — five-level ecosystem map: Signal, Commitment, Semantic networks, Mutual objectives, Shared context.

  • progression — iterative six-step orientation. Also reachable via pscale_invite().

  • block-conventions — substrate-wide canonical block-shape catalogue.

  • gatekeeper — substrate-wide role-shell for L1→L2 admission. Hermitcrab pattern.

  • soft-agent — substrate-wide role-shell for the user-mediating LLM.

  • payway — convention for face-bound ticket gates on sed: collectives.

  • ecology-router — hard-tier routing intelligence; minimal package definition.

  • sand-rider — Signed Agent Network Datagram envelope format for Level 3 probes.

  • l3-relay — verb vocabulary for handling a verified probe: keep, reply, forward, drop.

  • directory — staged process for publishing this server to MCP discovery registries.

All are also surfaced as MCP resources at pscale://<name> (except payway, whose URI serves the discursive markdown long-form via a separate loader).

The address invariant — locked

Pscale 0 is anchored at the floor (decimal point), not at the top of the tree. Floor = depth of the underscore chain.

Walk algorithm: parse → pad LEFT to floor width with zeros → strip TRAILING zeros → walk. Digit 0 → key _. Single decimal point as floor marker, stripped before walking. Trailing zeros are floor-width notation, never walk steps. Multi-dot addresses are strictly rejected at parse time (sunstone:1.5).

src/bsp.ts is a faithful TypeScript port of bsp2-star.py from CORSAIR. Do not patch it; replace wholesale if the reference updates.

Substrate — federated beaches

bsp-mcp does not host data. It is a router + sentinel server. All persistent block storage lives at federated beaches — JSON KV stores reachable at <origin>/.well-known/pscale-beach. The beach computes and stores lock hashes under the canonical salt namespaces; bsp-mcp forwards secret and new_lock and never sees the hash.

Two terminating substrates after dispatch:

  • Federated beach — URL agent_id (https://example.com) routes to that origin's .well-known/pscale-beach. Falls back to beach.<host> if the bare host is not federated.

  • Sentinel registryagent_id="pscale" returns one of the in-memory bundled blocks listed under "Foundational reading" above (read-only).

Three translating forms (resolve to the default beach with the agent_id encoded into the block name):

  • Bare handle weft + block passport → block passport:weft

  • sed:<collective> → block sed:<collective>

  • grain:<pair_id> → block grain:<pair_id>

Default beach is https://beach.happyseaurchin.com — override via the DEFAULT_BEACH env var.

Lock salt namespaces (computed at the beach, never at bsp-mcp):

  • sed: sha256(passphrase + collective + position)

  • grain: sha256(passphrase + "grain:" + pair_id + ":" + side)

  • ordinary: sha256(passphrase + "block:" + agent_id + ":" + name + ":" + position)

Locks set against one bsp-mcp instance verify against any other instance pointing at the same beach.

Connect

Hosted (recommended for clients):

{
  "bsp": {
    "command": "npx",
    "args": ["-y", "mcp-remote@0.1.38", "https://bsp.hermitcrab.me/mcp/v1"]
  }
}

Direct Railway URL (if the custom domain is propagating): https://bsp-mcp-server-production.up.railway.app/mcp/v1

Local (the scaling path):

npm install
npm run dev

Default port 3001, MCP path /mcp/v1. Override with PORT, MCP_PATH, and DEFAULT_BEACH env vars.

Smoke tests

npm run smoke:unit              # bsp() walker against sunstone
npm run smoke:parser            # address parser correctness (multi-dot reject, floor padding)
npm run smoke:sentinel          # sentinel registry round-trip
npm run smoke:wellknown         # local-mock federated beach
npm run smoke:federated         # live federated beach (network required)
npm run smoke:federated-parser  # address-parser round-trip across the wire

Structure

src/
  bsp.ts                   walker (DO NOT PATCH; port of bsp2-star.py)
  bsp-fn.ts                unified bsp() function — shape derivation, read/write symmetric
  db.ts                    storage adapter (federated beaches over HTTP + sentinel registry)
  keys.ts                  Argon2id + nacl (X25519/Ed25519, gray encryption)
  locks.ts                 sha256 hash helpers — kept for legacy round-trip; live hashing is at the beach
  server.ts                MCP server factory
  index.ts                 HTTP entry point (Streamable HTTP transport)
  sentinels.ts             single source of truth for JSON-sentinel registration (drives db.ts + server.ts)
  sunstone.json            teaching block (9 branches)
  whetstone.json           operational reference (6 branches)
  agent-id.json            addressing model (5 forms, 3 axes)
  evolution.json           5-level ecosystem map
  manifest.json            constitution index
  progression.json         6-step iterative orientation
  block-conventions.json   substrate-wide block-shape catalogue
  gatekeeper.json          L1→L2 admission role-shell
  soft-agent.json          user-mediating LLM role-shell
  payway.json    sed: ticket-gate convention
  ecology-router.json      hard-tier routing intelligence
  sand-rider.json          Level 3 envelope format (SAND)
  l3-relay.json            verb vocabulary for verified-probe handling
  directory.json           publishing process for this server
  tools/
    bsp.ts                 handler for bsp()
    collective.ts          pscale_register (founding is a bsp() write, not a tool)
    grain.ts               pscale_grain_reach
    keys.ts                pscale_key_publish
    verify.ts              pscale_verify_rider
    invite.ts              pscale_invite
  resources/
    xstream-frame.ts       pscale://xstream-frame (discursive markdown doc)
    payway.ts             pscale://payway (discursive markdown doc)
scripts/                   smoke tests
specs/                     forward-looking spec drafts

What NOT to add

Read CLAUDE.md before extending the surface. The function surface caught up to the geometry — it does not need additions. If you find yourself reaching for an 8th tool, the answer is almost certainly a block convention plus the * operator, not new code.

License

MIT — free for any use; the substrate is permissive by design.

Lineage

Built on the lessons of pscale-mcp-server. The function surface differs (one unified bsp() instead of 25 categorised tools); the storage model differs (federated beaches instead of central Supabase); the underlying pscale block format is shared.

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    -
    quality
    D
    maintenance
    Provides secure filesystem operations, HTTP fetching with SSRF protection, JSON validation, artifact logging, and optional Redis key-value storage through both stdio and HTTP transports. Features production-ready security controls including sandbox enforcement, allowlist validation, and comprehensive input validation.
    Last updated
    Apache 2.0
  • F
    license
    A
    quality
    A
    maintenance
    Local-first MCP tools for AI-assisted work receipts, workspace maps, routing ledgers, measured verdicts, and shared state verification across the five Project Telos flagships.
    Last updated
    23
    3
  • A
    license
    -
    quality
    B
    maintenance
    Modular snack registry, scheduler, spool, and MCP knowledge conduit that enables AI-ranked search, multi-agent shared memory, and FTS5 indexing across vault layers.
    Last updated
    MIT

View all related MCP servers

Related MCP Connectors

  • MCP-native open-source Notion alternative: read & write pages, databases and kanban boards.

  • Coordinate multiple AI agents over MCP: atomic claims, leases, shared ledger, handoffs, tasks.

  • Private-by-default, local-first memory/context/task orchestrator for MCP apps and agents.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pscale-commons/bsp-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server