loading…
Search for a command to run...
loading…
ZKshare stdio MCP: store/prove/share, semantic search, sandbox proxy to HTTPS /api/v1/context.
ZKshare stdio MCP: store/prove/share, semantic search, sandbox proxy to HTTPS /api/v1/context.
Privacy-oriented context API for users, AI agents, and back-office systems. A single HTTP entrypoint
(POST /api/v1/context) handles encrypted fact storage, commitment-based proof envelopes,
semantic search over encrypted data, end-to-end-encrypted (client-sealed) facts, and a
isolated sandbox execution for sensitive computations. The implementation is a Next.js
(App Router) application backed by PostgreSQL with pgvector.
This document is for developers integrating against the API and operators self-hosting the service. It is not a marketing brochure — pricing tiers, dashboards, and billing are optional layers defined separately in the application code.
The platform is designed around three trust boundaries:
| Boundary | What the operator can see | What stays private |
|---|---|---|
| Server-sealed store | Ciphertext, IV, auth tag, commitment, embedding vector. The server holds the AES-256-GCM key (ZKSHARE_ENCRYPTION_SECRET) and decrypts in memory only when the caller invokes prove, share, or search summaries. |
Database operators (without the encryption secret) and direct table readers (RLS denies anon and authenticated) cannot read plaintext. |
| Client-sealed (E2EE) store | Opaque ciphertext blobs, IV, auth tag, commitment, and a caller-supplied embedding vector. The server never receives or derives plaintext, and never calls an embedding model on the fact. | The platform operator. Decryption requires the caller's own key, which never leaves the caller. |
| Proof envelopes | A versioned, HMAC-signed JSON envelope (commitment + query + yes/no answer + nonce). Verifiable by anyone holding ZKSHARE_PROOF_SECRET. |
The fact plaintext used to derive the answer is never included in the envelope. |
verify_proof.share_token
bound to a recipient agent identifier.SECURITY.md is the canonical reference for the threat model, the trust model summary, vulnerability disclosure, the operator checklist, and third-party LLM exposure controls.
| Operation | Behavior |
|---|---|
store |
Server-sealed: caller sends value. Server encrypts with AES-256-GCM, computes a salted commitment, generates an embedding (or accepts a 1536-dim embedding), and persists with client_encrypted = false. Client-sealed: caller sends ciphertext, iv, auth_tag, commitment, and the required embedding. Server stores blobs and the vector, sets client_encrypted = true, and never derives anything from the plaintext or label. |
prove |
Loads a server-sealed fact, decrypts in memory, derives a yes/no answer for the supplied query (LLM with temperature: 0, or a heuristic when external LLMs are disabled), and returns an HMAC-signed proof envelope. Returns 422 / CLIENT_ENCRYPTED if the fact is client-sealed. |
share |
Same as prove, plus inserts a row into share_tokens (recipient_agent_id, expiry, proof) and returns a share_token. The token is a 24-byte base64url string, valid for seven days. |
search |
Embeds the query, calls match_facts (a security definer SQL function with cosine distance over pgvector), and returns ranked summaries for server-sealed rows only. Client-sealed rows are excluded at the SQL level and the application level. |
verify_proof |
Validates an envelope without loading any fact. Malformed envelope returns 400 / VALIDATION_ERROR; well-formed envelope with a bad HMAC returns 200 with data.valid: false. |
sandbox |
Executes a small allow-listed function inside an isolated node:vm sandbox (no host I/O, 50 ms timeout) and returns the result with attestation metadata and a short-lived HS256 JWT (proof_of_execution). Every response advertises provider: "vm-sandbox" — this is software isolation, not hardware attestation. |
Authoritative request and response shapes live in types/index.ts and openapi.json.
The npm package zkshare-mcp (npm, source packages/zkshare-mcp/) is a stdio MCP server exposing tools (zkshare_store, zkshare_prove, …) that call POST https://zkshare.io/api/v1/context (or your ZKSHARE_API_URL) with ZKSHARE_API_KEY.
Official MCP Registry canonical name: io.github.sp0oby/zkshare — registry lookup · About the MCP Registry (discovery metadata; runnable package remains on npm).
End users: Node.js ≥ 18, then npx -y zkshare-mcp — no clone. Configure your host (example below).
Contributors: from the repo root pnpm install, then pnpm mcp to run the local package; source is packages/zkshare-mcp/.
Advanced client-sealed store bodies stay on HTTPS/OpenAPI — not via MCP tools.
// ~/.cursor/mcp.json
{
"mcpServers": {
"zkshare": {
"command": "npx",
"args": ["-y", "zkshare-mcp"],
"env": {
"ZKSHARE_API_KEY": "zk_live_…",
"ZKSHARE_API_URL": "https://zkshare.io"
}
}
}
}
| Code | HTTP | Meaning |
|---|---|---|
INVALID_API_KEY |
401 |
Missing, malformed, or revoked key. |
RATE_LIMITED |
429 |
Per-key sliding-window limit exceeded. Retry-After header included. |
VALIDATION_ERROR |
400 |
Body fails the Zod schema or a malformed proof was passed to verify_proof. |
FACT_NOT_FOUND |
404 |
No row matches (api_key_id, logical_user_id, fact_key). |
PROOF_FAILED |
400 |
Decryption failed or no definite yes/no answer could be derived. |
CLIENT_ENCRYPTED |
422 |
prove or share was called against a client-sealed fact. |
INTERNAL_ERROR |
500 |
Caught exception. The original message is logged via lib/logger.ts; clients see a generic message. |
/api/v1/context is a Node.js route handler (not Edge) so AES-256-GCM, scrypt key
derivation, and the Supabase service-role client behave deterministically.supabase/migrations/. Tables: api_keys, facts, audit_logs, share_tokens. The facts
table stores ciphertext, IV, auth tag, commitment, a vector(1536) embedding, and a
client_encrypted flag.match_facts(api_key_id, logical_user_id, query_embedding, match_count) is a
security definer function with an IVFFlat index. It returns server-sealed rows only.
Updating the function's row type requires DROP FUNCTION ... CASCADE-style replacement (a
PostgreSQL constraint) — the migrations handle this explicitly.middleware.ts redirects unauthenticated
visitors away from /dashboard.x-api-key header. Keys are stored as SHA-256 hashes; only the prefix is shown in
the dashboard. Rotating a key requires generating a new one — plaintext is never persisted.anon and authenticated roles. The
application uses the Supabase service role server-side only.ZKSHARE_ENCRYPTION_SECRET — server-side AES-256-GCM master secret (scrypt-derived; minimum
32 characters).ZKSHARE_PROOF_SECRET — HMAC secret for commitments and proof envelopes (minimum 16
characters).ZKSHARE_ENCLAVE_JWT_SECRET — HS256 secret for sandbox attestations (minimum 32 characters).| Path | Purpose |
|---|---|
app/ |
Next.js App Router routes — public site, dashboard, API endpoints (api/v1/context, api/keys, api/billing, api/webhooks/stripe, api/health, api/health/ready, api/audit/export, auth/callback). |
lib/ |
Server-only modules: encryption.ts, zk.ts, embeddings.ts, search.ts, sandbox.ts, api-key.ts, rate-limit.ts, audit.ts, llm-client.ts, supabase-server.ts, supabase-browser.ts. |
components/ |
UI components built on shadcn/ui primitives. |
types/index.ts |
Zod request schema, operation enum, error codes, and shared row types. |
supabase/migrations/ |
Ordered SQL migrations. |
circuits/ |
Notes and placeholders for future Groth16 wiring. snarkjs is a runtime dependency but is not on the default trust path. |
packages/zkshare-mcp/ |
Publishable zkshare-mcp npm package — MCP stdio server that proxies to /api/v1/context. |
openapi.json |
OpenAPI 3.1 description of the public surface. |
SECURITY.md |
Threat model, operational checklist, and the encryption / LLM matrix. |
pnpm install
cp .env.local.example .env.local
# Fill the Supabase, ZKSHARE_*, and (optionally) LLM, Upstash, and Stripe values.
# Defaults for LLM model slugs live in lib/llm-client.ts.
pnpm dev
Apply migrations against your Supabase database before exercising the API. See supabase/README.md.
Server-sealed store followed by a proof:
curl -sS -X POST http://localhost:3000/api/v1/context \
-H "x-api-key: zk_live_..." \
-H "Content-Type: application/json" \
-d '{"operation":"store","user_id":"user_123","fact_key":"example","value":"hello"}'
curl -sS -X POST http://localhost:3000/api/v1/context \
-H "x-api-key: zk_live_..." \
-H "Content-Type: application/json" \
-d '{"operation":"prove","user_id":"user_123","fact_key":"example","query":"does the fact say hello?"}'
Verifying a proof string:
curl -sS -X POST http://localhost:3000/api/v1/context \
-H "x-api-key: zk_live_..." \
-H "Content-Type: application/json" \
-d '{"operation":"verify_proof","proof":"<base64url envelope from the prove response>"}'
Health probes:
GET /api/healthGET /api/health/readypnpm run verify:crypto
This runs scripts/verify-crypto.ts directly under Node's built-in TypeScript support and
asserts encryption round-trip, tamper detection, deterministic commitments, and all three
verify_proof outcomes (valid, invalid, malformed).
The full operator checklist lives in SECURITY.md → Operator checklist. At a minimum, before exposing the API to the public internet:
ZKSHARE_* secrets are set with high-entropy values; the application throws on startup otherwise.ZKSHARE_CORS_ORIGIN is an explicit comma-separated allow list of origins. * is for unauthenticated demos only.supabase/migrations/ have been applied in timestamp order on the target environment.UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKEN); the in-process rate-limit fallback is for local development only.GET /api/health/ready returns 200 with no missing entries and acknowledged warnings.The proof field returned today is a versioned JSON envelope signed with HMAC-SHA256, binding
the commitment, the query, and the yes/no answer. snarkjs is included as a dependency, and
circuits/ documents the intended Groth16 path for future work. Groth16 verification is not on
the default response path. Treat any external claim of full SNARK-on-every-call as aspirational
unless the verifier and circuit artifacts have been shipped and audited.
See CONTRIBUTING.md for the local-development checklist, the verification commands required before opening a pull request, and how to flag changes that touch the data plane or cryptographic paths.
Please do not open a public issue for security vulnerabilities. The disclosure process and contact channels are documented in SECURITY.md.
Released under the MIT License.
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"zkshare-mcp": {
"command": "npx",
"args": [
"-y",
"zkshare-mcp"
]
}
}
}pro-tip
Поставил Zkshare Mcp? Скажи Claude: «запомни почему я установил Zkshare Mcp и что хочу попробовать» — попадёт в твой Vault.
как это работает →