Bolyra

io.github.bolyraPublished by GitHub account bolyrav0.6.4Updated Oct 24, 2026

MCP auth middleware: gate tool calls so only authorized agents can act.

VerifiedSTDIODesktop onlyDeveloper ToolsSecurity & Monitoring

Overview

AI-generated overview

A library that adds Bolyra zero-knowledge proof authentication to MCP servers, so only authorized agents can call sensitive tools.

What you can do
  • Wrap an MCP server so every tool call must carry a Bolyra proof bundle (stdio via request metadata, HTTP via an Authorization header).
  • Verify human and agent proofs, nonce freshness and a minimum score before a call proceeds.
  • Enforce per-tool permission policies against the agent's effective bitmask, including delegated chains.
  • Expose helpers to attach proofs on the client side, verify bundles offline and check tool policies.
  • Run in dev mode with mock proofs and fixed-seed identities for local testing.
When to use it
Use it when you build or operate an MCP server whose tools touch sensitive data or actions and you want cryptographic proof that a human authorized the calling agent. It is a developer library, not a ready-made tool server, so it is worth adding only if you are writing your own MCP server or client.
Requirements
Installed as an npm package alongside the MCP SDK and the Bolyra SDK; runs as a local process on the user's machine. Production use needs a credential resolver, circuit artifacts on disk, an RPC URL and a registry contract address. Dev mode needs no circuit artifacts.
Before you install
Dev mode uses mock proofs and fixed-seed identities and is explicitly not for production; leaving it on defeats the protection. Production configuration involves a blockchain RPC endpoint and registry contract address, and the library gates tool calls that may read or write data, so a misconfigured policy can block or allow the wrong tools.

Installation

In SourceWeft

  1. Open Bolyra in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

@bolyra/mcp

Gate MCP tool calls so only authorized agents can call sensitive tools.

Quick Start (60 seconds)

bash
npm install @bolyra/mcp @bolyra/sdk @modelcontextprotocol/sdk
typescript
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';import { withBolyraAuthStdio } from '@bolyra/mcp';
const server = new McpServer({ name: 'my-server', version: '1.0.0' });
server.tool('read_file', { path: { type: 'string' } }, async (args) => ({  content: [{ type: 'text', text: `Reading ${args.path}` }],}));
withBolyraAuthStdio(server.server, {  devMode: true,  toolPolicy: {    // 1n = READ_DATA, 2n = WRITE_DATA (BigInt — add 'n' suffix)    read_file: 1n,  },});

That's it. Every tools/call now requires a valid Bolyra proof bundle.

Dev mode (full example)

Dev mode uses mock proofs — no circuit artifacts, no trusted setup, instant startup. Use it to build and test your server before wiring real ZKP verification.

ts
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';import { withBolyraAuthStdio } from '@bolyra/mcp';
// Serverconst server = new McpServer({ name: 'my-server', version: '1.0.0' });
server.tool('read_file', { path: { type: 'string' } }, async (args) => ({  content: [{ type: 'text', text: 'file contents...' }],}));
withBolyraAuthStdio(server.server, {  devMode: true,  toolPolicy: {    // 1n = READ_DATA, 2n = WRITE_DATA (BigInt — add 'n' suffix)    read_file: 1n,    write_file: 2n,  },});
await server.connect(new StdioServerTransport());

Client side:

ts
import { createDevIdentities, attachBolyraProof } from '@bolyra/sdk';
const { human, agent } = await createDevIdentities();const auth = await attachBolyraProof(human, agent, { devMode: true });
// stdioawait client.callTool({ name: 'read_file', arguments: { path: '/tmp/x' }, _meta: auth.meta });// HTTPawait fetch('/mcp', { headers: { ...auth.headers }, ... });

How it works

Every tools/call request must carry a proof bundle: a pair of Groth16 proofs (one from the human's circuit, one from the agent's) bound to a shared session nonce.

The server side:

  1. Extracts the bundle from params._meta.bolyra (stdio) or the Authorization: Bolyra <base64> header (HTTP).
  2. Verifies the handshake — both proofs, nonce freshness, score floor.
  3. Checks the tool's permission policy against the agent's effective bitmask.
  4. Attaches a BolyraAuthContext to the request for downstream handlers.
  5. Rejects with an MCP error if any step fails.

Discovery calls (initialize, tools/list) pass through unauthenticated.

Delegation chains (v=2 bundles) narrow scope from root credential to leaf agent across multiple hops. The effective bitmask seen by tool policies is always the leaf's — the most-restricted scope.

API reference

Server — stdio

ts
withBolyraAuthStdio(server: McpServer, config: BolyraMcpConfig): void

Wraps an McpServer instance. Must be called before server.connect(transport).

Server — HTTP

ts
bolyraAuthMiddleware(config: BolyraMcpHttpConfig): express.RequestHandler

Express middleware. Mount before your MCP HTTP handler. Rejects unauthenticated tools/call requests with HTTP 401.

Client helpers

ts
attachBolyraProof(  human: HumanIdentity,  agent: AgentCredential,  options?: AttachProofOptions,): Promise<BolyraClientAuth>

Runs a handshake and returns { headers, meta, bundle }. Pass options.devMode = true to skip real proving and emit a mock bundle.

ts
attachDelegatedBolyraProof(  human: HumanIdentity,  rootCred: AgentCredential,  hops: DelegationHopSpec[],  options?: AttachProofOptions,): Promise<BolyraClientAuth>

Like attachBolyraProof but walks a delegation chain and returns a v=2 bundle.

Verification

ts
verifyBundle(bundle: BolyraProofBundle, config: BolyraMcpConfig): Promise<BolyraAuthContext>

Verify a bundle directly — useful for custom transports or offline verification.

ts
checkToolPolicy(  toolName: string,  ctx: BolyraAuthContext,  policy: ToolPermissionPolicy,): { allowed: boolean; reason?: string }

Check a BolyraAuthContext against a tool's required bitmask.

Dev identities (re-exported from SDK)

ts
createDevIdentities(options?: DevIdentityOptions): Promise<DevIdentities>

Returns fixed-seed { human, agent, operatorKey } — deterministic, no circuit artifacts required. Logs a warning on first call. Never use in production.

Production configuration

Swap devMode: true for a real resolveCredential resolver and point the SDK at your circuit artifacts:

ts
withBolyraAuthStdio(server, {  resolveCredential: async (commitment) => myRegistry.get(commitment),  toolPolicy: {    // 1n = READ_DATA, 2n = WRITE_DATA (BigInt — add 'n' suffix)    read_file: 1n,    write_file: 2n,  },  sdkConfig: {    circuitDir: '/path/to/circuits/build',    rpcUrl: 'https://sepolia.base.org',    registryAddress: '0x2781dF8b6381462d881C833Fb703d68c661c9577',  },});

Full config interface:

ts
interface BolyraMcpConfig {  network?: string;          // DID network label (default: 'base-sepolia')  minScore?: number;         // Minimum score floor 0–100 (default: 70)  maxProofAge?: number;      // Nonce freshness window in seconds (default: 300)  toolPolicy?: ToolPermissionPolicy;  devMode?: boolean;         // Mock verification — dev/test only  resolveCredential?: (commitment: string) => Promise<AgentCredential | null>;  sdkConfig?: BolyraConfig;}

The HTTP variant adds authScheme?: string (default "Bolyra").

Transport guide

TransportBundle locationNotes
stdio (Claude Desktop, Cursor, Cline)params._meta.bolyraMCP spec defines no stdio auth surface; _meta is the only protocol-level field
HTTP / SSE / Streamable-HTTPAuthorization: Bolyra <base64-bundle>Custom auth scheme per RFC 7235; aligns with OAuth 2.1 resource-server pattern

Both produce the same BolyraAuthContext on the server side. Tool handlers don't need to know which transport was used.

Example

See examples/protected-file-server/ for a complete stdio server + client pair using dev mode. Run it with:

bash
cd integrations/mcpnpm run example:protected-file-server

Source: integrations/mcp/README.md at commit 5e9de85

Tools

0
SourceWeft has not started this package in its sandbox yet, so its tools are not known.

Version history

1
  1. v0.6.4LatestSep 16, 2026

Score

50% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts

    Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.

  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listed15 pts

    Answer tools/list without a credential, or ship a package that starts in a sandbox without one.

  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts