Назад към всички

bind-mcp

// Bind Protocol MCP server for credential verification, policy authoring, and zero-knowledge proof generation.

$ git log --oneline --stat
stars:1,933
forks:367
updated:March 4, 2026
SKILL.mdreadonly
SKILL.md Frontmatter
namebind-mcp
descriptionBind Protocol MCP server for credential verification, policy authoring, and zero-knowledge proof generation.
version2.0.0
metadata[object Object]

Bind MCP Server — Agent Skill Guide

You have access to the Bind Protocol MCP server. This document teaches you how to use it.

Prerequisites & Installation

Requirements

  • Node.js >= 18 — Required to run the server (npx handles package installation automatically)
  • Bind account — Required for API-backed tools. Create one at https://dashboard.bindprotocol.xyz
  • Agent key (idbr_agent_...) — Required for API-backed tools. Regular API keys (idbr_) are not supported for MCP.

Credential Setup

Bind uses agent keys for MCP authentication. Agent keys are scoped API keys that let org admins control exactly which tools are available, set daily rate limits, and get audit logs.

Key typeFormatMCP supported
Agent keyidbr_agent_<keyId>_<secret>Yes — required for API-backed tools
Regular API keyidbr_<keyId>_<secret>No — rejected by MCP server

To create an agent key:

  1. Sign in at https://dashboard.bindprotocol.xyz
  2. Navigate to Settings > Agent Keys
  3. Select which tool categories the key can access (e.g., credential verification only, or policy authoring + verification)
  4. Copy the key — it is shown only once

MCP Server Configuration

Add the server to your MCP client configuration. The exact file depends on your tool:

ToolConfig file
Claude Code.mcp.json in your project root, or ~/.claude/claude_desktop_config.json
Claude DesktopSettings > Developer > Edit Config
Cursor.cursor/mcp.json in your project root
WindsurfMCP settings

Configuration JSON:

{
  "mcpServers": {
    "bind": {
      "command": "npx",
      "args": ["@bind-protocol/mcp-server"],
      "env": {
        "BIND_API_KEY": "${BIND_API_KEY}"
      }
    }
  }
}

The BIND_API_KEY environment variable must be set in your shell to your agent key before launching your AI tool. Never hardcode the key directly in config files — always use environment variable references to avoid accidental credential leakage in shared configs or repositories.

Environment variables:

VariableRequiredDefaultDescription
BIND_API_KEYFor API-backed toolsAgent key (idbr_agent_...). Without this, only local tools are available.
BIND_API_URLNohttps://api.bindprotocol.xyzBase URL for API calls
BIND_RECEIPTS_PATHNo~/.bind/receiptsDirectory for receipt chain data
LOG_LEVELNoinfoLogging verbosity (debug, info, warn, error)

Verifying the Setup

If you do not have bind tools available, prompt the user to complete the setup above. You can test connectivity by calling bind_whoami — if it returns org info, the agent key is authenticated. Without a BIND_API_KEY, only local tools (parse, verify, hash) are available.


Architecture & Data Flow

The server runs locally via npx and communicates with your AI tool over stdio. It provides both local tools (always available) and API-backed tools (require an agent key). You just call the tool by name — routing is handled automatically.

Tool typeAuthPurpose
Local toolsNoneParse, verify, and hash VC-JWTs on-device
API-backed toolsAgent key via BIND_API_KEYPolicies, proofs, issuers, revocation, and more

What stays local vs. what calls the API

This is critical for understanding the privacy model:

Local tools (credential data NEVER leaves the machine):

  • bind_parse_credential — Decodes the JWT entirely on your machine
  • bind_verify_credential — Fetches the issuer's public JWKS from the Bind API (public keys only), then verifies the signature locally. The credential itself is never sent.
  • bind_hash_credential — Computes a SHA-256 hash locally. Only the irreversible hash is used for revocation checks.

API-backed tools (send requests to api.bindprotocol.xyz):

  • bind_check_revocation — Sends only the credential hash (not the credential). The hash is not reversible.
  • bind_resolve_issuer — Fetches public keys for an org. No credential data involved.
  • bind_explain_policy, bind_list_policies, bind_list_circuits — Read-only public metadata. No credential data involved.
  • bind_submit_prove_job — Sends circuit inputs to the Bind proving service. These are the raw values being proven (e.g., income amount, mileage count).
  • bind_issue_credential — Requests the Bind API to sign and issue a VC-JWT from a completed proof.
  • bind_create_policy, bind_validate_policy — Sends policy spec JSON to Bind for validation/storage.
  • bind_share_proof — Shares a proof record with a verifier org via the Bind API.

In short: Raw credentials are local-only. Hashes, policy specs, proof inputs, and metadata go to the API.


Tool Inventory

Local Tools (no auth required, credential data stays on-machine)

ToolWhat it does
bind_parse_credentialDecode a VC-JWT into header + payload + signature without verification
bind_verify_credentialFull verification: parse, fetch issuer JWKS, verify ES256 signature, check expiration. Does NOT check revocation.
bind_hash_credentialSHA-256 hash a VC-JWT. Use the hash with bind_check_revocation.

API-Backed Tools (require agent key via BIND_API_KEY)

Discovery & Inspection

ToolWhat it does
bind_resolve_issuerFetch an org's public signing keys (JWKS) by org ID
bind_explain_policyGet the public spec for a policy by policy ID
bind_check_revocationCheck if a credential is revoked by its hash (hash only — not the credential)
bind_list_policiesList available policies (supports limit/offset pagination)
bind_list_circuitsList available ZK circuits

Proof Generation & Credential Issuance

ToolWhat it does
bind_submit_prove_jobSubmit a ZK proof generation job with circuit ID and inputs
bind_get_prove_jobPoll a prove job's status by job ID
bind_list_prove_jobsList prove jobs, optionally filtered by status
bind_issue_credentialIssue a verifiable credential from a completed prove job
bind_share_proofShare a completed proof with a verifier org
bind_list_shared_proofsList proofs shared with/by your org

Policy Authoring

ToolWhat it does
bind_whoamiGet authenticated org info, tier, policy limits, and agent key permissions
bind_validate_policyDry-run validation of a policy spec (catches errors before creation)
bind_create_policyCreate a new verification policy
bind_generate_circuitTrigger ZK circuit compilation for a saved policy
bind_get_circuit_statusPoll circuit compilation job status

Workflow 1: Full Credential Verification

When to use: A user gives you a VC-JWT string (starts with eyJ...) and wants to know if it's valid.

Steps:

  1. bind_parse_credential — Decode the JWT to inspect claims
  2. bind_verify_credential — Verify signature and expiration
  3. bind_hash_credential — Compute SHA-256 hash
  4. bind_check_revocation — Send the hash (not the credential) to check revocation

Steps 1 and 2 can be combined (verify includes parsing), but parsing first lets you show the user what the credential contains before the full check. Steps 1–3 run locally; step 4 sends only the hash to the API.

Important: bind_verify_credential does NOT check revocation. You must always follow up with hash + revocation check for a complete verification.

parse → verify → hash → check_revocation

Workflow 2: Investigate an Issuer

When to use: A user wants to know about an organization's keys or policies.

  1. bind_resolve_issuer(orgId) — Fetch their JWKS
  2. bind_list_policies or bind_explain_policy — Look up their policies

Workflow 3: Create a Policy

When to use: A user wants to define a new verification policy.

Steps:

  1. bind_whoami — Check org name, tier, and limits. You need the org name for the namespace.
  2. Build the policy spec (see Policy Spec Reference below)
  3. bind_validate_policy — Dry-run to catch errors before creation
  4. Fix any validation errors and re-validate
  5. bind_create_policy — Save the policy
  6. bind_generate_circuit — Queue ZK circuit compilation
  7. bind_get_circuit_status — Poll until status is completed or failed

Critical rules:

  • metadata.namespace MUST start with your org's slugified name (from bind_whoami). The namespaces bind and system are reserved.
  • The policy id MUST start with the namespace (e.g., acme.finance.creditCheck for namespace acme).
  • ALWAYS validate before creating. Fix all errors first.
  • String inputs MUST have an encoding block mapping values to numbers (ZK circuits only work with numbers).

Workflow 4: Generate a Proof and Issue a Credential

When to use: A user wants to generate a ZK proof and get a verifiable credential.

  1. bind_list_policies or bind_explain_policy — Find the right policy/circuit
  2. bind_submit_prove_job(circuitId, inputs) — Submit the proof job
  3. bind_get_prove_job(jobId) — Poll until status is completed
  4. bind_issue_credential(proveJobId) — Issue the VC from the completed proof
  5. Optionally: bind_share_proof(proveJobId, verifierOrgId) — Share with a verifier

Policy Spec Reference

A policy is a JSON object with this structure. All fields shown are required unless marked optional.

{
  "id": "<namespace>.<category>.<name>",
  "version": "0.1.0",
  "metadata": {
    "title": "Human-readable title",
    "description": "What this policy verifies",
    "category": "finance|mobility|identity|demo",
    "namespace": "your-org-name"
  },
  "subject": {
    "type": "individual|organization|vehicle|device",
    "identifier": "wallet_address|did|vin|vehicleTokenId"
  },

  "inputs": [
    {
      "id": "input_name",
      "source": { "kind": "static|api", "api": "optional_api_name" },
      "signal": "input_name",
      "valueType": "number|boolean|string",
      "unit": "USD|count|months",
      "time": { "mode": "point|range|relative", "lookback": "30d" },
      "aggregation": { "op": "latest|sum|mean|count" },
      "encoding": {
        "type": "enum",
        "values": { "label1": 1, "label2": 2 }
      }
    }
  ],

  "rules": [
    {
      "id": "rule_name",
      "description": "Human-readable description",
      "assert": { /* expression — see below */ },
      "severity": "fail|warn|info"
    }
  ],

  "evaluation": {
    "kind": "PASS_FAIL|SCORE",
    "scoreRange": { "min": 0, "max": 100 },
    "baseline": 50,
    "contributions": [
      { "ruleId": "rule_name", "points": 30, "whenPasses": true }
    ]
  },

  "outputs": [
    {
      "name": "output_name",
      "type": "boolean|enum|number",
      "derive": {
        "kind": "PASS_FAIL|SCORE|BAND|CONST",
        "from": "SCORE|input_id",
        "bands": [
          { "label": "LOW", "minInclusive": 0, "maxExclusive": 40 },
          { "label": "HIGH", "minInclusive": 40, "maxExclusive": 101 }
        ],
        "value": 42
      },
      "disclosed": true
    }
  ],

  "validity": { "ttl": "P30D" },
  "disclosure": {
    "default": "SELECTIVE",
    "exposeClaims": ["output_name"]
  },

  "proving": {
    "circuitId": "<namespace>.<name>.v<version>",
    "inputTypes": { "input_name": "u32" },
    "outputType": "u8"
  }
}

Expression Types (used in rules[].assert)

TypeShapeExample
ref{ "type": "ref", "inputId": "<input_id>" }Reference an input value
const{ "type": "const", "value": <number|boolean> }Literal number or boolean (never strings)
cmp{ "type": "cmp", "cmp": ">=|<=|>|<|==|!=", "left": <expr>, "right": <expr> }Comparison
op{ "type": "op", "op": "+|-|*|/", "args": [<expr>, ...] }Arithmetic
and{ "type": "and", "args": [<expr>, ...] }Logical AND
or{ "type": "or", "args": [<expr>, ...] }Logical OR
not{ "type": "not", "arg": <expr> }Logical NOT

Field name gotchas:

  • Use "inputId" in ref expressions, NOT "path"
  • Use "cmp" for the comparison operator, NOT "operator"
  • Use "args" for operand lists, NOT "children"
  • Use "arg" (singular) for not, NOT "expr"
  • const values must be numbers or booleans, never strings

Evaluation Kinds

PASS_FAIL: All severity: "fail" rules must pass. No scoring.

SCORE: Starts at baseline, adds/subtracts points from rule contributions.

{
  "kind": "SCORE",
  "scoreRange": { "min": 0, "max": 100 },
  "baseline": 50,
  "contributions": [
    { "ruleId": "has_high_income", "points": 25, "whenPasses": true },
    { "ruleId": "has_delinquencies", "points": -20, "whenPasses": true }
  ]
}

Output Derive Kinds

KindUse forRequired fields
PASS_FAILBoolean pass/fail from evaluationNone
SCORERaw numeric scorefrom: "SCORE"
BANDMap score to labeled bandsfrom: "SCORE", bands array
CONSTFixed valuevalue

Working with String Inputs

ZK circuits only work with numbers. When a policy uses string inputs (employer names, country codes, etc.), you MUST include an encoding block:

{
  "id": "employer",
  "source": { "kind": "static" },
  "signal": "employer",
  "valueType": "string",
  "encoding": {
    "type": "enum",
    "values": {
      "Acme Corp": 1,
      "Globex Inc": 2,
      "Initech": 3
    }
  }
}

Proving Section

The proving section maps inputs to Noir types for the ZK circuit:

{
  "proving": {
    "circuitId": "acme.safe_driver.v0_1_0",
    "inputTypes": {
      "miles_driven": "u32",
      "hard_brake_pct": "u8",
      "is_commercial": "bool"
    },
    "outputType": "u8"
  }
}

Available Noir types: u8, u16, u32, u64, i8, i16, i32, i64, bool, Field


Tier Restrictions

Policy authoring is gated by organization tier. Always call bind_whoami first to check limits.

TierCan Create PoliciesNotes
BasicNoVerification only
PremiumYesLimited inputs/rules/outputs
ScaleYesExpanded limits, can create extractors
EnterpriseYesUnlimited
VerifierNoCannot create proofs or policies

Common Errors and Fixes

ErrorCauseFix
NAMESPACE_MISMATCHPolicy namespace doesn't match your orgUse your org name from bind_whoami as the namespace prefix
TIER_LIMIT_EXCEEDEDYour tier doesn't allow this operationCheck bind_whoami for limits
INVALID_EXPRESSIONMalformed rule assertionCheck expression field names (inputId, cmp, args, arg)
MISSING_ENCODINGString input without encodingAdd encoding.type: "enum" with values map
CIRCUIT_COMPILATION_FAILEDCircuit couldn't compileCheck the error in bind_get_circuit_status, fix the policy, recreate, and regenerate

Example: Complete Policy Creation

Here is a complete example of creating a credit score policy for org acme:

{
  "id": "acme.finance.credit-check",
  "version": "0.1.0",
  "metadata": {
    "title": "Credit Eligibility Check",
    "description": "Evaluates creditworthiness based on income and debt ratio",
    "category": "finance",
    "namespace": "acme"
  },
  "subject": {
    "type": "individual",
    "identifier": "wallet_address"
  },
  "inputs": [
    {
      "id": "annual_income",
      "source": { "kind": "static" },
      "signal": "annual_income",
      "valueType": "number",
      "unit": "USD"
    },
    {
      "id": "debt_ratio",
      "source": { "kind": "static" },
      "signal": "debt_ratio",
      "valueType": "number",
      "unit": "percent"
    }
  ],
  "rules": [
    {
      "id": "min_income",
      "description": "Annual income must be at least $30,000",
      "assert": {
        "type": "cmp",
        "cmp": ">=",
        "left": { "type": "ref", "inputId": "annual_income" },
        "right": { "type": "const", "value": 30000 }
      },
      "severity": "fail"
    },
    {
      "id": "max_debt_ratio",
      "description": "Debt-to-income ratio must be under 40%",
      "assert": {
        "type": "cmp",
        "cmp": "<",
        "left": { "type": "ref", "inputId": "debt_ratio" },
        "right": { "type": "const", "value": 40 }
      },
      "severity": "fail"
    }
  ],
  "evaluation": {
    "kind": "PASS_FAIL"
  },
  "outputs": [
    {
      "name": "eligible",
      "type": "boolean",
      "derive": { "kind": "PASS_FAIL" },
      "disclosed": true
    }
  ],
  "validity": { "ttl": "P30D" },
  "disclosure": {
    "default": "SELECTIVE",
    "exposeClaims": ["eligible"]
  },
  "proving": {
    "circuitId": "acme.credit_check.v0_1_0",
    "inputTypes": {
      "annual_income": "u32",
      "debt_ratio": "u8"
    },
    "outputType": "u8"
  }
}

Agent workflow for this:

  1. bind_whoami — Confirm org is acme and tier allows policy creation
  2. bind_validate_policy(policy) — Dry-run validation
  3. bind_create_policy(policy) — Create the policy
  4. bind_generate_circuit("acme.finance.credit-check") — Compile the circuit
  5. bind_get_circuit_status(jobId) — Poll until complete