cascrow-mcp 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -0
- package/REMOTE_HTTP_SERVER.md +97 -0
- package/index.js +160 -12
- package/package.json +1 -1
- package/smithery.yaml +8 -6
- package/DEMO_PROMPT.md +0 -78
package/README.md
CHANGED
|
@@ -6,6 +6,13 @@ AI agents use Cascrow to create milestone-based contracts, submit proof of compl
|
|
|
6
6
|
|
|
7
7
|
## Quick Start
|
|
8
8
|
|
|
9
|
+
**No API key yet?** Every setup below works without `CASCROW_API_KEY` too — the server starts either
|
|
10
|
+
way, but only `cascrow_verify_work` (verify AI-generated work, no escrow) is available until you set
|
|
11
|
+
one, at the same 3-free-per-IP-per-day tier as [cascrow.com/verify](https://cascrow.com/verify). Set
|
|
12
|
+
`CASCROW_API_KEY` (see Agent Registration below) once you want the other 17 tools.
|
|
13
|
+
|
|
14
|
+
### Claude Desktop
|
|
15
|
+
|
|
9
16
|
Add to your `claude_desktop_config.json`:
|
|
10
17
|
|
|
11
18
|
```json
|
|
@@ -22,6 +29,65 @@ Add to your `claude_desktop_config.json`:
|
|
|
22
29
|
}
|
|
23
30
|
```
|
|
24
31
|
|
|
32
|
+
Omit the `env` block entirely to run in anonymous mode (`cascrow_verify_work` only, see above).
|
|
33
|
+
|
|
34
|
+
### Claude.ai Web / Smithery
|
|
35
|
+
|
|
36
|
+
Remote HTTP transport — no local install needed. See `smithery.yaml`, or connect
|
|
37
|
+
directly to `https://cascrow.com/api/mcp` with your API key as a Bearer token.
|
|
38
|
+
No Bearer token at all also works — same anonymous `cascrow_verify_work`-only mode as above.
|
|
39
|
+
|
|
40
|
+
### Cursor
|
|
41
|
+
|
|
42
|
+
Add to `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project-local):
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"mcpServers": {
|
|
47
|
+
"cascrow": {
|
|
48
|
+
"command": "npx",
|
|
49
|
+
"args": ["cascrow-mcp"],
|
|
50
|
+
"env": {
|
|
51
|
+
"CASCROW_API_KEY": "csk_..."
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Cursor also supports the remote server directly via `url` + `headers` instead
|
|
59
|
+
of a local process — see [Cursor's MCP docs](https://docs.cursor.com/context/mcp)
|
|
60
|
+
for the current recommended way to avoid hardcoding the API key in a static header.
|
|
61
|
+
|
|
62
|
+
### OpenAI Codex CLI
|
|
63
|
+
|
|
64
|
+
Add to `~/.codex/config.toml`:
|
|
65
|
+
|
|
66
|
+
```toml
|
|
67
|
+
[mcp_servers.cascrow]
|
|
68
|
+
url = "https://cascrow.com/api/mcp"
|
|
69
|
+
bearer_token_env_var = "CASCROW_API_KEY"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Set `CASCROW_API_KEY` in your shell environment (not in the file) — Codex reads
|
|
73
|
+
the token from the named environment variable at connect time. A stdio variant
|
|
74
|
+
via `npx` also works if you prefer:
|
|
75
|
+
|
|
76
|
+
```toml
|
|
77
|
+
[mcp_servers.cascrow]
|
|
78
|
+
command = "npx"
|
|
79
|
+
args = ["-y", "cascrow-mcp"]
|
|
80
|
+
env_vars = ["CASCROW_API_KEY"]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### ChatGPT
|
|
84
|
+
|
|
85
|
+
ChatGPT web does not currently accept direct custom remote MCP server
|
|
86
|
+
connections (confirmed against OpenAI's own docs, 2026-08) — only
|
|
87
|
+
plugin-supplied tools are available there. A ChatGPT integration for Cascrow
|
|
88
|
+
would need to ship as a Custom GPT Action (OpenAPI-based) rather than a plain
|
|
89
|
+
MCP config snippet; that does not exist yet.
|
|
90
|
+
|
|
25
91
|
Get an API key at [cascrow.com](https://cascrow.com) — or register programmatically (see below).
|
|
26
92
|
|
|
27
93
|
## Agent Registration (no human required)
|
|
@@ -57,13 +123,21 @@ Rate limit: 3 registrations per IP per hour.
|
|
|
57
123
|
| `cascrow_create_contract` | Create a milestone contract. Returns `contractId` + `inviteCode`. |
|
|
58
124
|
| `cascrow_submit_proof` | Submit proof text — auto-triggers AI verification. Returns `proofId`. |
|
|
59
125
|
| `cascrow_verify` | Stream live 5-model AI verification results. |
|
|
126
|
+
| `cascrow_get_proof_status` | Poll a submitted proof's verification result. |
|
|
127
|
+
| `cascrow_watch_verification` | Submit proof and block until verification completes (combines submit + poll). |
|
|
128
|
+
| `cascrow_mcp_submit` | Submit proof and get an immediate verdict in one call — auto-releases funds and mints the NFT on approval. |
|
|
129
|
+
| `cascrow_verify_work` | Verify AI work with no escrow contract, from a GitHub PR or pasted code. Returns a public report URL. |
|
|
60
130
|
| `cascrow_escrow_fund` | Fund a milestone with an EVM private key (fully autonomous). |
|
|
61
131
|
| `cascrow_fund_milestone` | Fund via MetaMask (browser flow). |
|
|
62
132
|
| `cascrow_get_contract` | Get contract status and all milestone states. |
|
|
133
|
+
| `cascrow_list_my_contracts` | List all contracts for this agent, as Requester and/or Builder. |
|
|
63
134
|
| `cascrow_join_contract` | Join a contract as Builder agent via invite code. |
|
|
64
135
|
| `cascrow_handoff` | Send a contract to another agent by Agent ID. |
|
|
65
136
|
| `cascrow_get_agent_id` | Get this agent's own Agent ID. |
|
|
66
137
|
| `cascrow_check_invites` | Check pending contract invites. |
|
|
138
|
+
| `cascrow_get_reputation` | Look up any agent's on-chain reputation by wallet address. No auth required. |
|
|
139
|
+
| `cascrow_discover_agents` | Search discoverable Builder agents by skill tag and minimum success rate. |
|
|
140
|
+
| `cascrow_set_discoverable` | Opt into the agent marketplace, set skill tags, register a callback URL. |
|
|
67
141
|
|
|
68
142
|
## How Verification Works
|
|
69
143
|
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Remote HTTP MCP Server — Smithery Listing
|
|
2
|
+
|
|
3
|
+
**Status: Done.** The HTTP transport described below is live at
|
|
4
|
+
`src/app/api/mcp/route.ts` (Streamable HTTP, `@modelcontextprotocol/sdk`,
|
|
5
|
+
`WebStandardStreamableHTTPServerTransport`), serving the same 18 tools as this
|
|
6
|
+
package's stdio server. `smithery.yaml` already lists both the remote URL
|
|
7
|
+
(`https://cascrow.com/api/mcp`) and the local `npx cascrow-mcp` stdio fallback.
|
|
8
|
+
The plan below is kept as a historical record of what was built and why —
|
|
9
|
+
nothing in it is still pending.
|
|
10
|
+
|
|
11
|
+
**Update (2026-08-03):** both this HTTP transport and the stdio server now also work
|
|
12
|
+
without an API key — an unauthenticated caller gets a restricted server exposing only
|
|
13
|
+
`cascrow_verify_work` (anonymous, 3/day per IP, same tier as `POST /api/verify/standalone`),
|
|
14
|
+
instead of the transport-level 401 described below. Full 18-tool access still requires
|
|
15
|
+
`Authorization: Bearer csk_...` exactly as documented.
|
|
16
|
+
|
|
17
|
+
## Why
|
|
18
|
+
|
|
19
|
+
The current `cascrow-mcp` package runs locally via `npx` (stdio transport).
|
|
20
|
+
That works for **Claude Desktop** only.
|
|
21
|
+
|
|
22
|
+
A remote HTTP MCP server at `https://cascrow.com/mcp` would enable:
|
|
23
|
+
- **Claude.ai Web** (browser) — which only supports remote HTTP, not stdio
|
|
24
|
+
- **Smithery listing** under `cascrow/cascrow` with one-click install for 10k+ users
|
|
25
|
+
- **Any MCP client** without Node.js installed
|
|
26
|
+
|
|
27
|
+
## The Use Case (no escrow needed)
|
|
28
|
+
|
|
29
|
+
The primary value right now is **AI work verification**, independent of payments:
|
|
30
|
+
|
|
31
|
+
- Agent does work → calls `cascrow_mcp_submit` with `amountUSD: 0`
|
|
32
|
+
- 5 independent AI models vote on whether the work is complete
|
|
33
|
+
- User sees: "4/5 models approved, 89% confidence"
|
|
34
|
+
- Public certificate at `cascrow.com/proof/[hash]`
|
|
35
|
+
|
|
36
|
+
This works today on testnet. No MetaMask, no wallet, no escrow required.
|
|
37
|
+
Positions cascrow as the **trust/verification layer for AI work** before the agent economy matures.
|
|
38
|
+
|
|
39
|
+
## What Needs to Be Built
|
|
40
|
+
|
|
41
|
+
### 1. HTTP MCP Endpoint — `src/app/api/mcp/route.ts`
|
|
42
|
+
|
|
43
|
+
Replace stdio transport with HTTP transport using `@modelcontextprotocol/sdk`:
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
47
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
48
|
+
|
|
49
|
+
// Same 16 tools as cascrow-mcp/index.js but served over HTTP
|
|
50
|
+
// Auth: API key from Authorization header or ?api_key= query param
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The 16 tools already exist in `cascrow-mcp/index.js` — they just need to be
|
|
54
|
+
ported from stdio to HTTP transport. All business logic (`/api/mcp/submit`,
|
|
55
|
+
`/api/contracts`, etc.) stays unchanged.
|
|
56
|
+
|
|
57
|
+
### 2. Smithery Registration
|
|
58
|
+
|
|
59
|
+
- Create Smithery account under `cascrow` org (not personal `moeller` namespace)
|
|
60
|
+
- Go to smithery.ai/new
|
|
61
|
+
- Namespace: `cascrow` / Server ID: `cascrow`
|
|
62
|
+
- MCP Server URL: `https://cascrow.com/mcp`
|
|
63
|
+
- Result: `smithery.ai/server/cascrow/cascrow` with one-click install
|
|
64
|
+
|
|
65
|
+
### 3. Auth for Remote Connections
|
|
66
|
+
|
|
67
|
+
Remote users authenticate with their cascrow API key (`csk_...`).
|
|
68
|
+
Two options (both fine):
|
|
69
|
+
- `Authorization: Bearer csk_...` header
|
|
70
|
+
- `?api_key=csk_...` query param (easier for Smithery config UI)
|
|
71
|
+
|
|
72
|
+
### 4. Smithery Config Schema (update smithery.yaml)
|
|
73
|
+
|
|
74
|
+
```yaml
|
|
75
|
+
startCommand:
|
|
76
|
+
type: http
|
|
77
|
+
configSchema:
|
|
78
|
+
type: object
|
|
79
|
+
properties:
|
|
80
|
+
CASCROW_API_KEY:
|
|
81
|
+
type: string
|
|
82
|
+
description: "Your cascrow API key (csk_...)"
|
|
83
|
+
required:
|
|
84
|
+
- CASCROW_API_KEY
|
|
85
|
+
url: https://cascrow.com/mcp
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Effort Estimate
|
|
89
|
+
|
|
90
|
+
~4–6 hours. The hard parts (tools, auth, business logic) are already done.
|
|
91
|
+
Only the transport layer needs to change.
|
|
92
|
+
|
|
93
|
+
## When to Do This
|
|
94
|
+
|
|
95
|
+
**Now** — the verification use case (amountUSD: 0) works on testnet today.
|
|
96
|
+
Getting listed on Smithery/Claude.ai Web establishes cascrow as the
|
|
97
|
+
verification standard before competitors enter the space.
|
package/index.js
CHANGED
|
@@ -14,19 +14,31 @@ import {
|
|
|
14
14
|
|
|
15
15
|
const BASE_URL = process.env.CASCROW_BASE_URL ?? "https://cascrow.com";
|
|
16
16
|
const API_KEY = process.env.CASCROW_API_KEY ?? "";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
// No CASCROW_API_KEY: the server still starts, but only cascrow_verify_work is
|
|
18
|
+
// usable (it works anonymously against /api/verify/standalone, same 3-free-per-
|
|
19
|
+
// IP-per-day tier as the web page). Every other tool needs a real account.
|
|
20
|
+
const ANONYMOUS_MODE = !API_KEY;
|
|
21
|
+
|
|
22
|
+
if (ANONYMOUS_MODE) {
|
|
23
|
+
process.stderr.write(
|
|
24
|
+
"NOTE: CASCROW_API_KEY is not set — running in anonymous mode. " +
|
|
25
|
+
"Only cascrow_verify_work is available (3 free verifications/day). " +
|
|
26
|
+
"Register at https://cascrow.com/register or POST /api/agent/register for full access.\n"
|
|
27
|
+
);
|
|
21
28
|
}
|
|
22
29
|
|
|
23
30
|
// ─── HTTP helpers ─────────────────────────────────────────────────────────────
|
|
31
|
+
// Authorization header is omitted entirely when no API key is set, rather than
|
|
32
|
+
// sending a garbage "Bearer " token — matches how the web page calls the
|
|
33
|
+
// standalone endpoint anonymously.
|
|
34
|
+
|
|
35
|
+
const authHeader = API_KEY ? { "Authorization": `Bearer ${API_KEY}` } : {};
|
|
24
36
|
|
|
25
37
|
async function apiPost(path, body) {
|
|
26
38
|
const res = await fetch(`${BASE_URL}${path}`, {
|
|
27
39
|
method: "POST",
|
|
28
40
|
headers: {
|
|
29
|
-
|
|
41
|
+
...authHeader,
|
|
30
42
|
"Content-Type": "application/json",
|
|
31
43
|
},
|
|
32
44
|
body: JSON.stringify(body),
|
|
@@ -40,7 +52,7 @@ async function apiPost(path, body) {
|
|
|
40
52
|
|
|
41
53
|
async function apiGet(path) {
|
|
42
54
|
const res = await fetch(`${BASE_URL}${path}`, {
|
|
43
|
-
headers: {
|
|
55
|
+
headers: { ...authHeader },
|
|
44
56
|
});
|
|
45
57
|
const data = await res.json();
|
|
46
58
|
if (!res.ok) {
|
|
@@ -53,7 +65,7 @@ async function apiPatch(path, body) {
|
|
|
53
65
|
const res = await fetch(`${BASE_URL}${path}`, {
|
|
54
66
|
method: "PATCH",
|
|
55
67
|
headers: {
|
|
56
|
-
|
|
68
|
+
...authHeader,
|
|
57
69
|
"Content-Type": "application/json",
|
|
58
70
|
},
|
|
59
71
|
body: JSON.stringify(body),
|
|
@@ -73,7 +85,7 @@ async function uploadProof(milestoneId, filename, content) {
|
|
|
73
85
|
|
|
74
86
|
const res = await fetch(`${BASE_URL}/api/proof/upload`, {
|
|
75
87
|
method: "POST",
|
|
76
|
-
headers: {
|
|
88
|
+
headers: { ...authHeader },
|
|
77
89
|
body: form,
|
|
78
90
|
});
|
|
79
91
|
const data = await res.json();
|
|
@@ -93,7 +105,7 @@ async function streamVerify(proofId) {
|
|
|
93
105
|
res = await fetch(`${BASE_URL}/api/verify`, {
|
|
94
106
|
method: "POST",
|
|
95
107
|
headers: {
|
|
96
|
-
|
|
108
|
+
...authHeader,
|
|
97
109
|
"Content-Type": "application/json",
|
|
98
110
|
"Accept": "text/event-stream",
|
|
99
111
|
},
|
|
@@ -439,6 +451,7 @@ const TOOLS = [
|
|
|
439
451
|
"Runs the full 5-model AI verification pipeline and, on approval, automatically releases funds on-chain and mints an NFT certificate. " +
|
|
440
452
|
"Use this instead of cascrow_submit_proof + cascrow_verify when your proof is text/code (no file upload needed). " +
|
|
441
453
|
"Returns verdict ('approved' | 'rejected' | 'pending_review'), confidence score, and on-chain proof URL.",
|
|
454
|
+
|
|
442
455
|
inputSchema: {
|
|
443
456
|
type: "object",
|
|
444
457
|
required: ["contract_id", "evidence"],
|
|
@@ -476,6 +489,71 @@ const TOOLS = [
|
|
|
476
489
|
},
|
|
477
490
|
},
|
|
478
491
|
},
|
|
492
|
+
{
|
|
493
|
+
name: "cascrow_verify_work",
|
|
494
|
+
description:
|
|
495
|
+
"Verify AI-generated work without any escrow contract. " +
|
|
496
|
+
"Provide a task description and either a GitHub PR URL or paste code/text. " +
|
|
497
|
+
"Returns a public shareable report URL with a YES/NO decision, confidence score, " +
|
|
498
|
+
"and per-model reasoning from 5 AI models. Use this to prove that AI work was actually done correctly.",
|
|
499
|
+
inputSchema: {
|
|
500
|
+
type: "object",
|
|
501
|
+
required: ["taskDescription"],
|
|
502
|
+
properties: {
|
|
503
|
+
taskDescription: {
|
|
504
|
+
type: "string",
|
|
505
|
+
description: "What was the task? E.g. 'Fix the 3 security vulnerabilities listed in the audit report'",
|
|
506
|
+
},
|
|
507
|
+
prUrl: {
|
|
508
|
+
type: "string",
|
|
509
|
+
description: "GitHub PR URL (e.g. github.com/owner/repo/pull/42). Takes precedence over codeText.",
|
|
510
|
+
},
|
|
511
|
+
codeText: {
|
|
512
|
+
type: "string",
|
|
513
|
+
description: "Paste code, diff, or work description (max 50,000 chars). Used if no prUrl.",
|
|
514
|
+
},
|
|
515
|
+
checklistItems: {
|
|
516
|
+
type: "array",
|
|
517
|
+
description: "Optional list of specific items to verify individually",
|
|
518
|
+
items: {
|
|
519
|
+
type: "object",
|
|
520
|
+
required: ["id", "title"],
|
|
521
|
+
properties: {
|
|
522
|
+
id: { type: "number" },
|
|
523
|
+
title: { type: "string" },
|
|
524
|
+
severity: { type: "string", enum: ["CRITICAL", "HIGH", "MEDIUM", "LOW"] },
|
|
525
|
+
},
|
|
526
|
+
},
|
|
527
|
+
},
|
|
528
|
+
},
|
|
529
|
+
},
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
name: "cascrow_watch_verification",
|
|
533
|
+
description:
|
|
534
|
+
"Submit a proof and wait for AI verification to complete — all in one call. " +
|
|
535
|
+
"Combines cascrow_submit_proof + polling into a single blocking tool. " +
|
|
536
|
+
"Returns the final YES/NO decision, confidence score, and per-model votes once verification is done. " +
|
|
537
|
+
"Times out after ~100 seconds and returns the proofId so you can poll manually with cascrow_get_proof_status.",
|
|
538
|
+
inputSchema: {
|
|
539
|
+
type: "object",
|
|
540
|
+
required: ["milestoneId", "content"],
|
|
541
|
+
properties: {
|
|
542
|
+
milestoneId: {
|
|
543
|
+
type: "string",
|
|
544
|
+
description: "The milestone ID to submit proof for",
|
|
545
|
+
},
|
|
546
|
+
content: {
|
|
547
|
+
type: "string",
|
|
548
|
+
description: "Full proof report — what was built, how criteria are met, URLs, metrics",
|
|
549
|
+
},
|
|
550
|
+
filename: {
|
|
551
|
+
type: "string",
|
|
552
|
+
description: "Optional filename for the proof (default: proof-report.txt)",
|
|
553
|
+
},
|
|
554
|
+
},
|
|
555
|
+
},
|
|
556
|
+
},
|
|
479
557
|
];
|
|
480
558
|
|
|
481
559
|
// ─── Tool handlers ────────────────────────────────────────────────────────────
|
|
@@ -597,7 +675,7 @@ async function handleVerify({ proofId }) {
|
|
|
597
675
|
}
|
|
598
676
|
|
|
599
677
|
async function handleGetContract({ contractId }) {
|
|
600
|
-
const data = await apiGet(`/api/contracts/${contractId}`);
|
|
678
|
+
const data = await apiGet(`/api/contracts/${encodeURIComponent(contractId)}`);
|
|
601
679
|
return data;
|
|
602
680
|
}
|
|
603
681
|
|
|
@@ -804,20 +882,88 @@ async function handleMcpSubmit({ contract_id, milestone_id, evidence }) {
|
|
|
804
882
|
};
|
|
805
883
|
}
|
|
806
884
|
|
|
885
|
+
async function handleVerifyWork({ taskDescription, prUrl, codeText, checklistItems }) {
|
|
886
|
+
if (!prUrl && !codeText) {
|
|
887
|
+
throw new Error("Provide either prUrl (GitHub PR URL) or codeText.");
|
|
888
|
+
}
|
|
889
|
+
const data = await apiPost("/api/verify/standalone", { taskDescription, prUrl, codeText, checklistItems });
|
|
890
|
+
const decision = data.decision === "YES" ? "✅ VERIFIED" : "❌ NOT VERIFIED";
|
|
891
|
+
const conf = data.confidence != null ? ` (${data.confidence}% confidence)` : "";
|
|
892
|
+
const checklistNote = data.checklistResults
|
|
893
|
+
? ` — ${data.checklistResults.fixedCount}/${data.checklistResults.totalCount} checklist items addressed`
|
|
894
|
+
: "";
|
|
895
|
+
return {
|
|
896
|
+
...data,
|
|
897
|
+
message: `${decision}${conf}${checklistNote}\n\nFull report: ${data.reportUrl ?? ""}${data.reasoning ? `\n\n${data.reasoning.slice(0, 400)}` : ""}`,
|
|
898
|
+
};
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
async function handleWatchVerification({ milestoneId, content, filename }) {
|
|
902
|
+
// Submit proof using existing multipart upload helper
|
|
903
|
+
const submitData = await uploadProof(milestoneId, filename ?? "proof-report.txt", content);
|
|
904
|
+
const proofId = submitData.proofId;
|
|
905
|
+
if (!proofId) {
|
|
906
|
+
throw new Error(submitData.error ?? "Proof submission failed — no proofId returned");
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// Poll until verification completes (max 100s, every 5s)
|
|
910
|
+
const MAX_WAIT_MS = 100_000;
|
|
911
|
+
const POLL_MS = 5_000;
|
|
912
|
+
const started = Date.now();
|
|
913
|
+
|
|
914
|
+
while (Date.now() - started < MAX_WAIT_MS) {
|
|
915
|
+
await new Promise((r) => setTimeout(r, POLL_MS));
|
|
916
|
+
let status;
|
|
917
|
+
try {
|
|
918
|
+
status = await apiGet(`/api/agent/proof-status/${encodeURIComponent(proofId)}`);
|
|
919
|
+
} catch {
|
|
920
|
+
continue; // transient error — keep polling
|
|
921
|
+
}
|
|
922
|
+
if (!status.pending) {
|
|
923
|
+
const decision = status.decision === "YES" ? "✅ APPROVED" : "❌ REJECTED";
|
|
924
|
+
const conf = status.confidence != null ? ` (${status.confidence}% confidence)` : "";
|
|
925
|
+
return {
|
|
926
|
+
...status,
|
|
927
|
+
proofId,
|
|
928
|
+
message: `${decision}${conf}\n${status.reasoning ? status.reasoning.slice(0, 400) : ""}`,
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
// Timed out — return proofId so agent can poll manually
|
|
934
|
+
return {
|
|
935
|
+
pending: true,
|
|
936
|
+
proofId,
|
|
937
|
+
message: `Verification still in progress after ~100s. Poll the result with cascrow_get_proof_status using proofId: ${proofId}`,
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
|
|
807
941
|
// ─── MCP Server ───────────────────────────────────────────────────────────────
|
|
808
942
|
|
|
809
943
|
const server = new Server(
|
|
810
|
-
{ name: "cascrow", version: "1.
|
|
944
|
+
{ name: "cascrow", version: "1.5.0" },
|
|
811
945
|
{ capabilities: { tools: {} } }
|
|
812
946
|
);
|
|
813
947
|
|
|
814
948
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
815
|
-
tools: TOOLS,
|
|
949
|
+
tools: ANONYMOUS_MODE ? TOOLS.filter((t) => t.name === "cascrow_verify_work") : TOOLS,
|
|
816
950
|
}));
|
|
817
951
|
|
|
818
952
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
819
953
|
const { name, arguments: args } = request.params;
|
|
820
954
|
|
|
955
|
+
if (ANONYMOUS_MODE && name !== "cascrow_verify_work") {
|
|
956
|
+
return {
|
|
957
|
+
content: [{
|
|
958
|
+
type: "text",
|
|
959
|
+
text: `Error: "${name}" requires a Cascrow account. Register free at https://cascrow.com/register ` +
|
|
960
|
+
`(or POST /api/agent/register), then set CASCROW_API_KEY to unlock all 18 tools. ` +
|
|
961
|
+
`Only cascrow_verify_work works anonymously (3 free verifications/day).`,
|
|
962
|
+
}],
|
|
963
|
+
isError: true,
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
|
|
821
967
|
try {
|
|
822
968
|
let result;
|
|
823
969
|
switch (name) {
|
|
@@ -837,6 +983,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
837
983
|
case "cascrow_list_my_contracts": result = await handleListMyContracts(args); break;
|
|
838
984
|
case "cascrow_get_proof_status": result = await handleGetProofStatus(args); break;
|
|
839
985
|
case "cascrow_mcp_submit": result = await handleMcpSubmit(args); break;
|
|
986
|
+
case "cascrow_verify_work": result = await handleVerifyWork(args); break;
|
|
987
|
+
case "cascrow_watch_verification": result = await handleWatchVerification(args); break;
|
|
840
988
|
default:
|
|
841
989
|
throw new Error(`Unknown tool: ${name}`);
|
|
842
990
|
}
|
package/package.json
CHANGED
package/smithery.yaml
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml
|
|
2
2
|
|
|
3
|
+
# Remote HTTP transport (Claude.ai web, Claude.ai API)
|
|
4
|
+
url: https://cascrow.com/api/mcp
|
|
5
|
+
|
|
3
6
|
startCommand:
|
|
4
7
|
type: stdio
|
|
5
8
|
configSchema:
|
|
@@ -7,20 +10,19 @@ startCommand:
|
|
|
7
10
|
properties:
|
|
8
11
|
CASCROW_API_KEY:
|
|
9
12
|
type: string
|
|
10
|
-
description: "Your cascrow API key (starts with csk_)
|
|
13
|
+
description: "Optional. Your cascrow API key (starts with csk_) — get one at cascrow.com/register or POST /api/agent/register. Without it, the server still starts but only cascrow_verify_work is available (3 free AI-verified checks per IP per day, no account needed). Set this to unlock all 18 tools."
|
|
11
14
|
pattern: "^csk_"
|
|
12
|
-
|
|
15
|
+
CASCROW_BASE_URL:
|
|
13
16
|
type: string
|
|
14
17
|
description: "Cascrow API base URL. Leave blank to use the default (https://cascrow.com)."
|
|
15
18
|
default: "https://cascrow.com"
|
|
16
|
-
required:
|
|
17
|
-
- CASCROW_API_KEY
|
|
19
|
+
required: []
|
|
18
20
|
commandFunction: |-
|
|
19
21
|
(config) => ({
|
|
20
22
|
command: 'npx',
|
|
21
23
|
args: ['-y', 'cascrow-mcp'],
|
|
22
24
|
env: {
|
|
23
|
-
CASCROW_API_KEY: config.CASCROW_API_KEY,
|
|
24
|
-
|
|
25
|
+
CASCROW_API_KEY: config.CASCROW_API_KEY || '',
|
|
26
|
+
CASCROW_BASE_URL: config.CASCROW_BASE_URL || 'https://cascrow.com'
|
|
25
27
|
}
|
|
26
28
|
})
|
package/DEMO_PROMPT.md
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
# Cascrow MCP Demo Prompt
|
|
2
|
-
|
|
3
|
-
Paste this into Claude Desktop to run the demo.
|
|
4
|
-
|
|
5
|
-
**Prerequisite:** Your `claude_desktop_config.json` must have a valid `CASCROW_API_KEY` (get one from your Requester dashboard → Deploy Agent).
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Short demo (90 sec YC video)
|
|
10
|
-
|
|
11
|
-
**PROMPT:**
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
I need a landing page for my SaaS "TaskFlow". It needs:
|
|
15
|
-
1. Hero section: headline + CTA
|
|
16
|
-
2. Features section: 3 features
|
|
17
|
-
|
|
18
|
-
Use Cascrow to verify each milestone as I build it — create the contract first, then for each section: build it, submit proof, trigger AI verification.
|
|
19
|
-
|
|
20
|
-
Show me the contract link and confidence scores at the end.
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
**Claude will:**
|
|
24
|
-
1. `cascrow_create_contract` — 2 milestones, `amountUSD: 0` (verification-only, no MetaMask)
|
|
25
|
-
2. Build HTML for milestone 1 → `cascrow_submit_proof` → `cascrow_verify` (4/5 YES)
|
|
26
|
-
3. Build HTML for milestone 2 → `cascrow_submit_proof` → `cascrow_verify` (5/5 YES)
|
|
27
|
-
4. Return contract URL + per-milestone confidence scores
|
|
28
|
-
|
|
29
|
-
**What you see in the browser:**
|
|
30
|
-
- `cascrow.com/contract/<id>` — milestones going PROOF_SUBMITTED → VERIFIED
|
|
31
|
-
- NFT certificate minted on XRP Ledger after final milestone
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## Full demo (longer walkthrough)
|
|
36
|
-
|
|
37
|
-
**PROMPT:**
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
I need a landing page for my SaaS product "TaskFlow" — a project management tool for remote teams.
|
|
41
|
-
|
|
42
|
-
The page needs:
|
|
43
|
-
1. Hero section: headline "Get more done, together" + subheadline + CTA button "Start free trial"
|
|
44
|
-
2. Features section: 3 features (Real-time collaboration, Smart deadlines, Team analytics)
|
|
45
|
-
3. Pricing section: 3 tiers (Free $0, Pro $12/mo, Enterprise custom)
|
|
46
|
-
|
|
47
|
-
Use Cascrow to create a verification contract for these 3 milestones BEFORE you start building (amountUSD: 0 — verification only, no payment needed), then build the page (write the full HTML/CSS), submit proof for each milestone, and get Cascrow verification that everything was actually delivered.
|
|
48
|
-
|
|
49
|
-
At the end, show me:
|
|
50
|
-
- The complete HTML of the landing page
|
|
51
|
-
- The Cascrow contract link proving all milestones were verified
|
|
52
|
-
- The AI confidence score for each milestone
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
**Claude will:**
|
|
56
|
-
1. `cascrow_create_contract` — 3 milestones, `amountUSD: 0` (no escrow, no MetaMask)
|
|
57
|
-
2. For each milestone:
|
|
58
|
-
- `cascrow_fund_milestone` — activate it (instant, no blockchain tx needed for $0)
|
|
59
|
-
- Build the actual HTML section
|
|
60
|
-
- `cascrow_submit_proof` — detailed proof of what was built
|
|
61
|
-
- `cascrow_verify` — 5 AI models vote, returns confidence score
|
|
62
|
-
3. Deliver final HTML + Cascrow contract link
|
|
63
|
-
|
|
64
|
-
**What you see in the browser (`cascrow.com/contract/...`):**
|
|
65
|
-
- Contract created with 3 milestones
|
|
66
|
-
- Each milestone: FUNDED → PROOF_SUBMITTED → VERIFIED
|
|
67
|
-
- NFT certificate minted on XRP Ledger at the end
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
## Why `amountUSD: 0`?
|
|
72
|
-
|
|
73
|
-
Cascrow supports **verification-only mode** — agents can use the full 5-model AI verification pipeline without locking any funds. This is useful for:
|
|
74
|
-
- Autonomous agents that need trustless proof of work (no human holds funds)
|
|
75
|
-
- Demo recordings (no MetaMask popup interrupts the flow)
|
|
76
|
-
- Charging per-verification ($0.10/check) without requiring escrow setup
|
|
77
|
-
|
|
78
|
-
To use real escrow, just set `amountUSD` to the payment amount and the Requester funds via MetaMask.
|