@reclaimprotocol/agent 0.1.0 → 0.1.1
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 +1 -1
- package/lib/cdp/capture-engine.d.ts +66 -0
- package/lib/cdp/capture-engine.js +153 -0
- package/lib/cdp/capture.d.ts +9 -20
- package/lib/cdp/capture.js +14 -138
- package/lib/cdp/index.d.ts +3 -0
- package/lib/cdp/index.js +6 -0
- package/lib/config/store.d.ts +7 -6
- package/lib/config/store.js +2 -2
- package/lib/index.d.ts +2 -2
- package/lib/index.js +1 -1
- package/lib/mcp/api/operations.gen.d.ts +101 -45
- package/lib/mcp/api/operations.gen.js +996 -126
- package/lib/mcp/api/to-zod.d.ts +24 -0
- package/lib/mcp/api/to-zod.js +94 -0
- package/lib/mcp/api/tools.js +1 -1
- package/lib/mcp/credentials/authenticate.d.ts +3 -0
- package/lib/mcp/{tools/credentials → credentials}/authenticate.js +3 -3
- package/lib/mcp/credentials/build.d.ts +5 -0
- package/lib/mcp/credentials/build.js +18 -0
- package/lib/mcp/{tools/credentials → credentials}/cache.d.ts +9 -9
- package/lib/mcp/{tools/credentials → credentials}/cache.js +36 -19
- package/lib/mcp/credentials/import.d.ts +2 -0
- package/lib/mcp/{tools/credentials → credentials}/import.js +2 -2
- package/lib/mcp/credentials/issue.d.ts +2 -0
- package/lib/mcp/{tools/credentials → credentials}/issue.js +4 -4
- package/lib/mcp/credentials/keypair.d.ts +17 -0
- package/lib/mcp/credentials/keypair.js +48 -0
- package/lib/mcp/credentials/link.d.ts +3 -0
- package/lib/mcp/credentials/link.js +107 -0
- package/lib/mcp/{tools/credentials → credentials}/list-cached.d.ts +1 -1
- package/lib/mcp/{tools/credentials → credentials}/list-cached.js +5 -5
- package/lib/mcp/credentials/owner-key.d.ts +23 -0
- package/lib/mcp/credentials/owner-key.js +58 -0
- package/lib/mcp/credentials/paths.d.ts +12 -0
- package/lib/mcp/credentials/paths.js +35 -0
- package/lib/mcp/credentials/poll.d.ts +27 -0
- package/lib/mcp/credentials/poll.js +61 -0
- package/lib/mcp/{tools/credentials → credentials}/resolve-owner-key.d.ts +1 -1
- package/lib/mcp/{tools/credentials → credentials}/resolve-owner-key.js +2 -2
- package/lib/mcp/credentials/session-cache.d.ts +14 -0
- package/lib/mcp/credentials/session-cache.js +42 -0
- package/lib/mcp/{tools/credentials → credentials}/status.d.ts +1 -1
- package/lib/mcp/credentials/status.js +76 -0
- package/lib/mcp/instructions.d.ts +1 -0
- package/lib/mcp/instructions.js +11 -0
- package/lib/mcp/register.d.ts +38 -0
- package/lib/mcp/register.js +80 -0
- package/lib/mcp/server.d.ts +2 -2
- package/lib/mcp/server.js +3 -3
- package/lib/mcp/start.js +10 -4
- package/lib/mcp/tools/agent/build.js +2 -15
- package/lib/mcp/tools/agent/index.d.ts +2 -0
- package/lib/mcp/tools/agent/index.js +3 -0
- package/lib/mcp/tools/agent/proof.js +1 -6
- package/lib/mcp/tools/agent/propose.js +13 -2
- package/lib/mcp/tools/agent/publish.js +10 -2
- package/lib/mcp/tools/agent/replay.js +0 -5
- package/lib/mcp/tools/analyze.d.ts +3 -0
- package/lib/mcp/tools/analyze.js +26 -0
- package/lib/mcp/tools/attach.d.ts +11 -0
- package/lib/mcp/tools/attach.js +72 -0
- package/lib/mcp/tools/authenticate/authenticate.js +107 -0
- package/lib/mcp/tools/authenticate/build.d.ts +15 -0
- package/lib/mcp/tools/authenticate/build.js +28 -0
- package/lib/mcp/tools/authenticate/decrypt-key.d.ts +32 -0
- package/lib/mcp/tools/authenticate/decrypt-key.js +49 -0
- package/lib/mcp/tools/authenticate/eth-key.d.ts +38 -0
- package/lib/mcp/tools/authenticate/eth-key.js +130 -0
- package/lib/mcp/tools/authenticate/import.js +57 -0
- package/lib/mcp/tools/authenticate/index.d.ts +2 -0
- package/lib/mcp/tools/authenticate/index.js +4 -0
- package/lib/mcp/tools/authenticate/issue.js +42 -0
- package/lib/mcp/tools/authenticate/resolve-owner-key.d.ts +13 -0
- package/lib/mcp/tools/authenticate/resolve-owner-key.js +53 -0
- package/lib/mcp/tools/capture.d.ts +10 -0
- package/lib/mcp/tools/capture.js +142 -0
- package/lib/mcp/tools/eval.d.ts +5 -0
- package/lib/mcp/tools/eval.js +127 -0
- package/lib/mcp/tools/find.d.ts +3 -0
- package/lib/mcp/tools/find.js +60 -0
- package/lib/mcp/tools/index.d.ts +3 -0
- package/lib/mcp/tools/index.js +6 -0
- package/lib/mcp/tools/owner-key.d.ts +2 -0
- package/lib/mcp/tools/owner-key.js +63 -0
- package/lib/mcp/tools/proof.d.ts +3 -0
- package/lib/mcp/tools/proof.js +214 -0
- package/lib/mcp/tools/propose.d.ts +9 -0
- package/lib/mcp/tools/propose.js +75 -0
- package/lib/mcp/tools/publish.d.ts +3 -0
- package/lib/mcp/tools/publish.js +59 -0
- package/lib/mcp/tools/replay.d.ts +3 -0
- package/lib/mcp/tools/replay.js +46 -0
- package/lib/mcp/tools/session.d.ts +10 -0
- package/lib/mcp/tools/session.js +29 -0
- package/lib/mcp/tools/verification/build.d.ts +12 -0
- package/lib/mcp/tools/verification/build.js +14 -0
- package/lib/mcp/tools/verification/diagnose.d.ts +11 -0
- package/lib/mcp/tools/verification/diagnose.js +132 -0
- package/lib/mcp/tools/verification/index.d.ts +1 -0
- package/lib/mcp/tools/verification/index.js +2 -0
- package/lib/mcp/tools/verification/result.d.ts +12 -0
- package/lib/mcp/tools/verification/result.js +126 -0
- package/lib/mcp/verifications/build.d.ts +5 -0
- package/lib/mcp/verifications/build.js +14 -0
- package/lib/mcp/verifications/create.d.ts +3 -0
- package/lib/mcp/verifications/create.js +57 -0
- package/lib/mcp/verifications/find.d.ts +3 -0
- package/lib/mcp/verifications/find.js +37 -0
- package/lib/mcp/verifications/get.d.ts +3 -0
- package/lib/mcp/verifications/get.js +26 -0
- package/lib/mcp/verifications/update.d.ts +3 -0
- package/lib/mcp/verifications/update.js +78 -0
- package/lib/old/client.d.ts +3 -0
- package/lib/old/instructions.d.ts +0 -6
- package/lib/old/instructions.js +6 -24
- package/lib/old/to-register.d.ts +3 -0
- package/lib/old/to-register.js +35 -7
- package/lib/old/tools/publish.js +13 -1
- package/lib/proof/attestor.d.ts +33 -1
- package/lib/proof/attestor.js +67 -61
- package/lib/proof/index.d.ts +5 -0
- package/lib/proof/index.js +6 -0
- package/lib/proof/proof-core.d.ts +35 -0
- package/lib/proof/proof-core.js +73 -0
- package/lib/proof/zk-files.d.ts +14 -0
- package/lib/proof/zk-files.js +73 -0
- package/lib/provider/index.d.ts +5 -0
- package/lib/provider/index.js +9 -0
- package/lib/provider/to-version.d.ts +9 -12
- package/lib/provider/to-version.js +38 -4
- package/lib/provider/verification-checks.d.ts +12 -0
- package/lib/provider/verification-checks.js +30 -0
- package/lib/routes.gen.d.ts +271 -0
- package/lib/routes.gen.js +73 -0
- package/lib/types/openapi.gen.d.ts +3967 -0
- package/lib/types/openapi.gen.js +5 -0
- package/package.json +18 -10
- package/skill/SKILL.md +35 -14
- package/skill/builder-mode.md +9 -0
- package/skill/old-mode.md +13 -0
- package/src/cdp/capture-engine.ts +256 -0
- package/src/cdp/capture.ts +25 -185
- package/src/cdp/index.ts +6 -0
- package/src/config/store.ts +7 -6
- package/src/index.ts +2 -4
- package/src/mcp/api/operations.gen.ts +1023 -121
- package/src/mcp/api/to-zod.ts +115 -0
- package/src/mcp/api/tools.ts +9 -3
- package/src/mcp/instructions.ts +15 -0
- package/src/mcp/server.ts +5 -4
- package/src/mcp/start.ts +14 -4
- package/src/mcp/tools/agent/build.ts +2 -18
- package/src/mcp/tools/agent/index.ts +4 -0
- package/src/mcp/tools/agent/proof.ts +1 -7
- package/src/mcp/tools/agent/propose.ts +13 -2
- package/src/mcp/tools/agent/publish.ts +10 -2
- package/src/mcp/tools/agent/replay.ts +0 -5
- package/src/mcp/tools/{credentials → authenticate}/authenticate.ts +9 -8
- package/src/mcp/tools/authenticate/build.ts +32 -0
- package/src/mcp/tools/authenticate/decrypt-key.ts +64 -0
- package/src/mcp/tools/authenticate/eth-key.ts +182 -0
- package/src/mcp/tools/authenticate/import.ts +73 -0
- package/src/mcp/tools/authenticate/index.ts +4 -0
- package/src/mcp/tools/authenticate/issue.ts +50 -0
- package/src/mcp/tools/authenticate/resolve-owner-key.ts +60 -0
- package/src/mcp/tools/index.ts +6 -0
- package/src/mcp/tools/verification/build.ts +16 -0
- package/src/mcp/tools/verification/index.ts +2 -0
- package/src/mcp/tools/verification/result.ts +155 -0
- package/src/old/client.ts +3 -0
- package/src/old/instructions.ts +10 -25
- package/src/old/to-register.ts +62 -27
- package/src/old/tools/publish.ts +17 -1
- package/src/proof/attestor.ts +115 -69
- package/src/proof/index.ts +21 -0
- package/src/proof/proof-core.ts +109 -0
- package/src/proof/zk-files.ts +83 -0
- package/src/provider/index.ts +20 -0
- package/src/provider/to-version.ts +52 -11
- package/src/provider/verification-checks.ts +36 -0
- package/lib/mcp/tools/credentials/build.d.ts +0 -16
- package/lib/mcp/tools/credentials/build.js +0 -33
- package/lib/mcp/tools/credentials/status.js +0 -62
- package/src/mcp/tools/credentials/build.ts +0 -37
- package/src/mcp/tools/credentials/cache.ts +0 -161
- package/src/mcp/tools/credentials/env-file.ts +0 -101
- package/src/mcp/tools/credentials/import.ts +0 -72
- package/src/mcp/tools/credentials/issue.ts +0 -107
- package/src/mcp/tools/credentials/list-cached.ts +0 -66
- package/src/mcp/tools/credentials/register.ts +0 -49
- package/src/mcp/tools/credentials/resolve-owner-key.ts +0 -78
- package/src/mcp/tools/credentials/status.ts +0 -82
- package/src/types/openapi.ts +0 -7
- /package/lib/mcp/{tools/credentials → credentials}/env-file.d.ts +0 -0
- /package/lib/mcp/{tools/credentials → credentials}/env-file.js +0 -0
- /package/lib/mcp/{tools/credentials → credentials}/register.d.ts +0 -0
- /package/lib/mcp/{tools/credentials → credentials}/register.js +0 -0
- /package/lib/mcp/tools/{credentials → authenticate}/authenticate.d.ts +0 -0
- /package/lib/mcp/tools/{credentials → authenticate}/import.d.ts +0 -0
- /package/lib/mcp/tools/{credentials → authenticate}/issue.d.ts +0 -0
- /package/lib/mcp/tools/{credentials → authenticate}/session-cache.d.ts +0 -0
- /package/lib/mcp/tools/{credentials → authenticate}/session-cache.js +0 -0
- /package/src/mcp/tools/{credentials → authenticate}/session-cache.ts +0 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import type { JSONSchema } from 'zod/v4/core'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* JSON Schema → zod for the generated MCP tool inputs.
|
|
6
|
+
*
|
|
7
|
+
* The generator (`packages/app/scripts/mcp-tools-gen.ts`) inlines `$ref`s it
|
|
8
|
+
* walks through `properties`/`items`, but it does NOT recurse into `allOf` /
|
|
9
|
+
* `anyOf` / `oneOf`. So a schema composed with `allOf` (e.g.
|
|
10
|
+
* `RequestSelectionTemplate =
|
|
11
|
+
* allOf[ RequestSelection, { multiple, required } ]`,
|
|
12
|
+
* surfaced by the proof tools' `allowedJsRequests`) can carry a dangling
|
|
13
|
+
* `#/components/schemas/…` `$ref` that points outside the standalone schema
|
|
14
|
+
* object handed to `z.fromJSONSchema`. zod then throws `Reference not found`
|
|
15
|
+
* at module-load time, taking down every tool.
|
|
16
|
+
*
|
|
17
|
+
* We pre-process here (rather than hand-editing the generated file, which
|
|
18
|
+
* regen would clobber): flatten `allOf` compositions into a single object
|
|
19
|
+
* schema and neutralize any remaining unresolvable `#/components/schemas/…`
|
|
20
|
+
* `$ref` to a permissive `{}`. The schemas affected are deep proof-tool inputs
|
|
21
|
+
* the model rarely hand-builds, so loosening leaf validation there is
|
|
22
|
+
* acceptable; the common tool inputs (uuids, version patterns, contexts) keep
|
|
23
|
+
* their full constraints.
|
|
24
|
+
*/
|
|
25
|
+
export function toZod(schema: JSONSchema.Schema) {
|
|
26
|
+
return z.fromJSONSchema(sanitize(schema) as JSONSchema.Schema)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type AnySchema = Record<string, unknown>
|
|
30
|
+
|
|
31
|
+
/** True for a `$ref` that can't be resolved in a standalone schema object. */
|
|
32
|
+
function isDanglingComponentRef(node: AnySchema): boolean {
|
|
33
|
+
return (
|
|
34
|
+
typeof node.$ref === 'string' &&
|
|
35
|
+
(node.$ref).startsWith('#/components/')
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Recursively (a) merge `allOf` members into their parent so composition
|
|
41
|
+
* resolves locally, and (b) replace any dangling `#/components/…` `$ref` with
|
|
42
|
+
* a permissive empty schema. Pure — returns a fresh tree, never mutates input.
|
|
43
|
+
*/
|
|
44
|
+
function sanitize(input: unknown): unknown {
|
|
45
|
+
if(Array.isArray(input)) {
|
|
46
|
+
return input.map(sanitize)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if(input === null || typeof input !== 'object') {
|
|
50
|
+
return input
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const node = input as AnySchema
|
|
54
|
+
|
|
55
|
+
if(isDanglingComponentRef(node)) {
|
|
56
|
+
// Drop the ref; keep any sibling keys (rare) sanitized.
|
|
57
|
+
const { $ref: _ref, ...rest } = node
|
|
58
|
+
void _ref
|
|
59
|
+
return sanitizeEntries(rest)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Flatten allOf into the parent object. Each member is sanitized first so
|
|
63
|
+
// its own refs/allOf collapse; object members merge their `properties`,
|
|
64
|
+
// `required`, and scalar keys upward.
|
|
65
|
+
if(Array.isArray(node.allOf)) {
|
|
66
|
+
const { allOf, ...rest } = node
|
|
67
|
+
let merged: AnySchema = sanitizeEntries(rest)
|
|
68
|
+
for(const member of allOf as unknown[]) {
|
|
69
|
+
merged = mergeObjectSchemas(merged, sanitize(member) as AnySchema)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return merged
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return sanitizeEntries(node)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Sanitize every value of an object schema's keys. */
|
|
79
|
+
function sanitizeEntries(node: AnySchema): AnySchema {
|
|
80
|
+
const out: AnySchema = {}
|
|
81
|
+
for(const [k, v] of Object.entries(node)) {
|
|
82
|
+
out[k] = sanitize(v)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return out
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Merge two (already-sanitized) object schemas for `allOf` flattening: union
|
|
90
|
+
* `properties`, union `required`, and let later members win on scalar keys.
|
|
91
|
+
* Both sides are expected to be object-shaped; non-object members fall back to
|
|
92
|
+
* a plain key spread (the rare case).
|
|
93
|
+
*/
|
|
94
|
+
function mergeObjectSchemas(a: AnySchema, b: AnySchema): AnySchema {
|
|
95
|
+
const out: AnySchema = { ...a, ...b }
|
|
96
|
+
|
|
97
|
+
const aProps = a.properties as AnySchema | undefined
|
|
98
|
+
const bProps = b.properties as AnySchema | undefined
|
|
99
|
+
if(aProps || bProps) {
|
|
100
|
+
out.properties = { ...aProps, ...bProps }
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const aReq = Array.isArray(a.required) ? (a.required as string[]) : []
|
|
104
|
+
const bReq = Array.isArray(b.required) ? (b.required as string[]) : []
|
|
105
|
+
if(aReq.length || bReq.length) {
|
|
106
|
+
out.required = Array.from(new Set([...aReq, ...bReq]))
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// `type` should stay `object` after merging two object schemas.
|
|
110
|
+
if(a.type === 'object' || b.type === 'object' || out.properties) {
|
|
111
|
+
out.type = 'object'
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return out
|
|
115
|
+
}
|
package/src/mcp/api/tools.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
2
2
|
import type {
|
|
3
|
-
|
|
3
|
+
ReclaimClient
|
|
4
4
|
} from '@reclaimprotocol/client'
|
|
5
|
+
import type {
|
|
6
|
+
IOperationArgs, IOperationId
|
|
7
|
+
} from '@reclaimprotocol/client/openapi'
|
|
5
8
|
import { remapErrorAsResponse } from '../remap_errors.ts'
|
|
6
9
|
import { MCP_TOOLS } from './operations.gen.ts'
|
|
7
10
|
|
|
@@ -28,9 +31,12 @@ export function registerTools(server: McpServer, client: ReclaimClient) {
|
|
|
28
31
|
server.registerTool(
|
|
29
32
|
toSnakeCase(opId),
|
|
30
33
|
shape,
|
|
31
|
-
async(args:
|
|
34
|
+
async(args: unknown) => {
|
|
32
35
|
try {
|
|
33
|
-
const result =
|
|
36
|
+
const result = await client.call(
|
|
37
|
+
opId as IOperationId,
|
|
38
|
+
args as IOperationArgs<IOperationId>,
|
|
39
|
+
)
|
|
34
40
|
return {
|
|
35
41
|
content: [{
|
|
36
42
|
type: 'text' as const, text: JSON.stringify(result.data, null, 2)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server instructions shown to the LLM when running in BUILDER mode
|
|
3
|
+
* (`USE_OLD_DEVTOOLS=false`). The prose lives in `skill/builder-mode.md`
|
|
4
|
+
* (published via the `files` array) so it can be edited as markdown without
|
|
5
|
+
* touching code. The path resolves identically from `src/mcp` (dev) and
|
|
6
|
+
* `lib/mcp` (published) — both are two levels below the package root.
|
|
7
|
+
* Old-devtools mode has its own reduced set in `../old/instructions.ts`.
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync } from 'node:fs'
|
|
10
|
+
import { fileURLToPath } from 'node:url'
|
|
11
|
+
|
|
12
|
+
export const BUILDER_MODE_INSTRUCTIONS = readFileSync(
|
|
13
|
+
fileURLToPath(new URL('../../skill/builder-mode.md', import.meta.url)),
|
|
14
|
+
'utf8',
|
|
15
|
+
).trim()
|
package/src/mcp/server.ts
CHANGED
|
@@ -6,13 +6,14 @@ import {
|
|
|
6
6
|
CallToolRequestSchema,
|
|
7
7
|
ListToolsRequestSchema,
|
|
8
8
|
} from '@modelcontextprotocol/sdk/types.js'
|
|
9
|
-
import {
|
|
9
|
+
import type { JSONSchema } from 'zod/v4/core'
|
|
10
|
+
import { toZod } from './api/to-zod.ts'
|
|
10
11
|
import { remapErrorAsResponse } from './remap_errors.ts'
|
|
11
12
|
|
|
12
13
|
export interface ToolDefinition {
|
|
13
14
|
name: string
|
|
14
15
|
description: string
|
|
15
|
-
inputSchema: JSONSchema
|
|
16
|
+
inputSchema: JSONSchema.ObjectSchema
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
export interface RegisteredTool {
|
|
@@ -38,7 +39,7 @@ export function defineTool<TArgs>(
|
|
|
38
39
|
definition: ToolDefinition,
|
|
39
40
|
handler: (args: TArgs) => Promise<unknown>,
|
|
40
41
|
): RegisteredTool {
|
|
41
|
-
const schema =
|
|
42
|
+
const schema = toZod(definition.inputSchema)
|
|
42
43
|
return {
|
|
43
44
|
definition,
|
|
44
45
|
handler: async(raw) => {
|
|
@@ -59,7 +60,7 @@ export function registerToolList(server: McpServer, tools: RegisteredTool[]) {
|
|
|
59
60
|
tool.definition.name,
|
|
60
61
|
{
|
|
61
62
|
description: tool.definition.description,
|
|
62
|
-
inputSchema:
|
|
63
|
+
inputSchema: toZod(tool.definition.inputSchema),
|
|
63
64
|
},
|
|
64
65
|
async(args) => {
|
|
65
66
|
try {
|
package/src/mcp/start.ts
CHANGED
|
@@ -8,12 +8,14 @@ import { OLD_MODE_INSTRUCTIONS } from '../old/instructions.ts'
|
|
|
8
8
|
import { buildOldBackendTools } from '../old/tools/build.ts'
|
|
9
9
|
import { NAME, VERSION } from '../pkg.ts'
|
|
10
10
|
import { registerTools } from './api/tools.ts'
|
|
11
|
-
import { buildAgentTools } from './tools/agent/build.ts'
|
|
12
11
|
import {
|
|
12
|
+
buildAgentTools,
|
|
13
13
|
buildCredentialTools,
|
|
14
14
|
buildLocalCredentialTools,
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
buildVerificationTools,
|
|
16
|
+
readSession,
|
|
17
|
+
} from './tools/index.ts'
|
|
18
|
+
import { BUILDER_MODE_INSTRUCTIONS } from './instructions.ts'
|
|
17
19
|
import { registerToolList } from './server.ts'
|
|
18
20
|
|
|
19
21
|
export async function startMcpServer() {
|
|
@@ -21,7 +23,11 @@ export async function startMcpServer() {
|
|
|
21
23
|
|
|
22
24
|
const server = new McpServer(
|
|
23
25
|
{ name: NAME, version: VERSION },
|
|
24
|
-
|
|
26
|
+
{
|
|
27
|
+
instructions: oldMode
|
|
28
|
+
? OLD_MODE_INSTRUCTIONS
|
|
29
|
+
: BUILDER_MODE_INSTRUCTIONS,
|
|
30
|
+
},
|
|
25
31
|
)
|
|
26
32
|
|
|
27
33
|
// Agent tools (Chrome CDP capture, provider synthesis, replay, proof) are
|
|
@@ -64,6 +70,10 @@ export async function startMcpServer() {
|
|
|
64
70
|
// Register credential tools for ETH credential management.
|
|
65
71
|
registerToolList(server, buildCredentialTools(client))
|
|
66
72
|
|
|
73
|
+
// Higher-level verification orchestrations (e.g. fetch + decrypt result).
|
|
74
|
+
// Authenticates with RECLAIM_ORG_SECRET, not the session client.
|
|
75
|
+
registerToolList(server, buildVerificationTools())
|
|
76
|
+
|
|
67
77
|
// Add auto-generated tools with snake_case wrappers
|
|
68
78
|
// for every MCP-tagged operation.
|
|
69
79
|
registerTools(server, client)
|
|
@@ -13,9 +13,8 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import type { ReclaimClient } from '@reclaimprotocol/client'
|
|
16
|
-
import { setCryptoImplementation } from '@reclaimprotocol/tls'
|
|
17
|
-
import { webcryptoCrypto } from '@reclaimprotocol/tls/webcrypto'
|
|
18
16
|
import { ConfigStore } from '../../../config/store.ts'
|
|
17
|
+
import { ensureAttestorCrypto } from '../../../proof/proof-core.ts'
|
|
19
18
|
import { type RegisteredTool } from '../../server.ts'
|
|
20
19
|
import { analyzeTool } from './analyze.ts'
|
|
21
20
|
import { type AttachState, attachTool } from './attach.ts'
|
|
@@ -38,21 +37,6 @@ export interface AgentState {
|
|
|
38
37
|
secrets: SecretStore
|
|
39
38
|
}
|
|
40
39
|
|
|
41
|
-
let cryptoInitialized = false
|
|
42
|
-
|
|
43
|
-
/** One-time crypto backend init for @reclaimprotocol/tls. The package
|
|
44
|
-
* ships with an empty `crypto = {}` and defers backend choice to the
|
|
45
|
-
* caller; without this, the first proof call dies inside the SDK with
|
|
46
|
-
* `crypto.randomBytes is not a function`. */
|
|
47
|
-
function ensureCryptoInit() {
|
|
48
|
-
if(cryptoInitialized) {
|
|
49
|
-
return
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
setCryptoImplementation(webcryptoCrypto)
|
|
53
|
-
cryptoInitialized = true
|
|
54
|
-
}
|
|
55
|
-
|
|
56
40
|
function buildAgentState(): AgentState {
|
|
57
41
|
return {
|
|
58
42
|
attach: { config: new ConfigStore() },
|
|
@@ -70,7 +54,7 @@ export function buildAgentTools(
|
|
|
70
54
|
client?: ReclaimClient,
|
|
71
55
|
): RegisteredTool[] {
|
|
72
56
|
const state = buildAgentState()
|
|
73
|
-
|
|
57
|
+
ensureAttestorCrypto()
|
|
74
58
|
const tools: RegisteredTool[] = []
|
|
75
59
|
tools.push(attachTool(state.attach))
|
|
76
60
|
for(const t of captureTools(state.attach, state.captures)) {
|
|
@@ -135,11 +135,6 @@ export function proofTool(secrets: SecretStore): RegisteredTool {
|
|
|
135
135
|
inputSchema: {
|
|
136
136
|
type: 'object',
|
|
137
137
|
properties: {
|
|
138
|
-
// `type: 'object'` is required so MCP clients (the LLM)
|
|
139
|
-
// serialize the value as an object, not a JSON-stringified
|
|
140
|
-
// string. `properties: {}` is required so zod-from-json-schema
|
|
141
|
-
// compiles to a passthrough instead of strict-strip — leaving
|
|
142
|
-
// it off makes the server receive `{}`.
|
|
143
138
|
provider: { type: 'object', properties: {} },
|
|
144
139
|
secretParamsRef: { type: 'string' },
|
|
145
140
|
attestorUrl: { type: 'string' },
|
|
@@ -173,8 +168,7 @@ export function proofTool(secrets: SecretStore): RegisteredTool {
|
|
|
173
168
|
const result = await runAttestorProof(
|
|
174
169
|
provider as ReclaimProvider,
|
|
175
170
|
resolved,
|
|
176
|
-
attestorUrl,
|
|
177
|
-
ownerAddress,
|
|
171
|
+
{ attestorUrl, ownerAddress },
|
|
178
172
|
)
|
|
179
173
|
|
|
180
174
|
// Persist the full claim to disk for the dev to inspect/share.
|
|
@@ -2,6 +2,7 @@ import { randomUUID } from 'node:crypto'
|
|
|
2
2
|
import { draftProvider } from '../../../provider/draft.ts'
|
|
3
3
|
import { OPRF_MAX_BYTES } from '../../../provider/matcher.ts'
|
|
4
4
|
import type { OprfMode } from '../../../provider/schema.ts'
|
|
5
|
+
import { verificationWarnings } from '../../../provider/verification-checks.ts'
|
|
5
6
|
import { defineTool, type RegisteredTool } from '../../server.ts'
|
|
6
7
|
import type { CaptureStore } from './capture.ts'
|
|
7
8
|
|
|
@@ -48,7 +49,11 @@ export function proposeTool(
|
|
|
48
49
|
'cleartext. Skill should ask the dev first. `oprf-raw` ' +
|
|
49
50
|
'is the only variant that runs ' +
|
|
50
51
|
'without external deps; `oprf` needs gnark (Linux/macOS), ' +
|
|
51
|
-
'`oprf-mpc` needs a TEE attestor.'
|
|
52
|
+
'`oprf-mpc` needs a TEE attestor. ' +
|
|
53
|
+
'The response may include `verificationWarnings` — advisory ' +
|
|
54
|
+
'author-only decisions (e.g. a user-specific URL part needing ' +
|
|
55
|
+
'the {{context.<name>}}-vs-bare call). Surface each to the ' +
|
|
56
|
+
'dev verbatim and resolve before publishing.',
|
|
52
57
|
inputSchema: {
|
|
53
58
|
type: 'object',
|
|
54
59
|
properties: {
|
|
@@ -105,7 +110,13 @@ export function proposeTool(
|
|
|
105
110
|
}
|
|
106
111
|
|
|
107
112
|
const secretParamsRef = secrets.put(realSecrets)
|
|
108
|
-
|
|
113
|
+
const warnings = verificationWarnings(provider)
|
|
114
|
+
return {
|
|
115
|
+
provider,
|
|
116
|
+
secretRefs,
|
|
117
|
+
secretParamsRef,
|
|
118
|
+
...(warnings.length ? { verificationWarnings: warnings } : {}),
|
|
119
|
+
}
|
|
109
120
|
},
|
|
110
121
|
)
|
|
111
122
|
}
|
|
@@ -26,8 +26,16 @@ export function createVersionFromCaptureTool(
|
|
|
26
26
|
'hand-construct that shape or call create_provider_version directly. ' +
|
|
27
27
|
'Omit `version` to have the tool auto-select the next available ' +
|
|
28
28
|
'version (it lists existing versions and bumps past the highest). ' +
|
|
29
|
-
'
|
|
30
|
-
'
|
|
29
|
+
'The version lands on the draft branch — to go live, call ' +
|
|
30
|
+
'`publish_provider_version` (PRIVATE) or ' +
|
|
31
|
+
'`submit_provider_version_for_review` (PUBLIC) afterwards. ' +
|
|
32
|
+
'`requiredContext` is derived from any {{context.<name>}} ' +
|
|
33
|
+
'placeholders and returned on the created version — when ' +
|
|
34
|
+
'present, tell the dev verbatim which context fields consumers ' +
|
|
35
|
+
'MUST send when creating sessions (verification matches those ' +
|
|
36
|
+
'values exactly; a missing field is a 400 at session create). ' +
|
|
37
|
+
'Refine types/descriptions via `update_provider_version` while ' +
|
|
38
|
+
'still on draft.',
|
|
31
39
|
inputSchema: {
|
|
32
40
|
type: 'object',
|
|
33
41
|
properties: {
|
|
@@ -16,11 +16,6 @@ export function replayTool(secrets: SecretStore): RegisteredTool {
|
|
|
16
16
|
inputSchema: {
|
|
17
17
|
type: 'object',
|
|
18
18
|
properties: {
|
|
19
|
-
// `type: 'object'` is required so MCP clients (the LLM)
|
|
20
|
-
// serialize the value as an object, not a JSON-stringified
|
|
21
|
-
// string. `properties: {}` is required so zod-from-json-schema
|
|
22
|
-
// compiles to a passthrough instead of strict-strip — leaving
|
|
23
|
-
// it off makes the server receive `{}`.
|
|
24
19
|
provider: { type: 'object', properties: {} },
|
|
25
20
|
secretParamsRef: { type: 'string' },
|
|
26
21
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReclaimClient } from '@reclaimprotocol/client'
|
|
2
2
|
import type {
|
|
3
|
-
CredentialAttachSession
|
|
4
|
-
} from '
|
|
3
|
+
CredentialAttachSession
|
|
4
|
+
} from '@reclaimprotocol/client/openapi'
|
|
5
5
|
import { defineTool, type RegisteredTool } from '../../server.ts'
|
|
6
6
|
import { writeSession } from './session-cache.ts'
|
|
7
7
|
|
|
@@ -21,10 +21,9 @@ export function authenticateTool(client: ReclaimClient): RegisteredTool {
|
|
|
21
21
|
'Returns `LINKED` with a 2-day bearer token when confirmed, ' +
|
|
22
22
|
'`PENDING` if not yet, or `EXPIRED` if too long has passed.\n\n' +
|
|
23
23
|
'The token is cached in ~/.reclaim/config.json automatically.\n\n' +
|
|
24
|
-
'
|
|
25
|
-
'
|
|
26
|
-
'
|
|
27
|
-
"credential's `address` and the target `orgId`.",
|
|
24
|
+
'This bearer token authenticates dashboard/org-management calls ' +
|
|
25
|
+
'(e.g. list_orgs, issuing an org secret). Programmatic verification ' +
|
|
26
|
+
'calls use a separate org secret (rorg_…, set as RECLAIM_ORG_SECRET).',
|
|
28
27
|
inputSchema: {
|
|
29
28
|
type: 'object',
|
|
30
29
|
properties: {
|
|
@@ -68,7 +67,7 @@ async function checkSession(
|
|
|
68
67
|
client: ReclaimClient,
|
|
69
68
|
code: string,
|
|
70
69
|
): Promise<unknown> {
|
|
71
|
-
let session:
|
|
70
|
+
let session: CredentialAttachSession
|
|
72
71
|
try {
|
|
73
72
|
const sessionResult = (await client.call('GetAttachSession', {
|
|
74
73
|
params: { code }
|
|
@@ -93,7 +92,9 @@ async function checkSession(
|
|
|
93
92
|
if(token) {
|
|
94
93
|
writeSession({
|
|
95
94
|
token,
|
|
96
|
-
expiresAt: new Date(
|
|
95
|
+
expiresAt: new Date(
|
|
96
|
+
Date.now() + 2 * 24 * 60 * 60 * 1000
|
|
97
|
+
).toISOString(),
|
|
97
98
|
})
|
|
98
99
|
client.setToken(token)
|
|
99
100
|
return {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ReclaimClient } from '@reclaimprotocol/client'
|
|
2
|
+
import type { RegisteredTool } from '../../server.ts'
|
|
3
|
+
import { authenticateTool } from './authenticate.ts'
|
|
4
|
+
import { importTool } from './import.ts'
|
|
5
|
+
import { issueTool } from './issue.ts'
|
|
6
|
+
import { resolveOwnerKeyTool } from './resolve-owner-key.ts'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Local-only key tools — no backend client needed. These manage the eth
|
|
10
|
+
* proof-owner key entirely on disk (as a secp256k1 PEM) or via env: generate,
|
|
11
|
+
* import, and resolve which key to sign proofs with. No `~/.reclaim` caching;
|
|
12
|
+
* useful in BOTH builder and OLD-devtools mode.
|
|
13
|
+
*/
|
|
14
|
+
export function buildLocalCredentialTools(): RegisteredTool[] {
|
|
15
|
+
return [
|
|
16
|
+
resolveOwnerKeyTool(),
|
|
17
|
+
issueTool(),
|
|
18
|
+
importTool(),
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Full builder-mode credential set: the local key tools plus the backend
|
|
24
|
+
* `reclaim_authenticate` device-code flow. Old mode does NOT use the
|
|
25
|
+
* authenticate tool — it has its own.
|
|
26
|
+
*/
|
|
27
|
+
export function buildCredentialTools(client: ReclaimClient): RegisteredTool[] {
|
|
28
|
+
return [
|
|
29
|
+
authenticateTool(client),
|
|
30
|
+
...buildLocalCredentialTools(),
|
|
31
|
+
]
|
|
32
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional X25519 decryption key — only needed when testing ENCRYPTED callback
|
|
3
|
+
* payloads in the consumer role. Resolution is file-only (no env var, no path
|
|
4
|
+
* override, no `~/.reclaim` caching):
|
|
5
|
+
*
|
|
6
|
+
* 1. An X25519 PKCS#8 PEM file named `reclaim-decrypt.pem` in the project
|
|
7
|
+
* root. Mint it with openssl:
|
|
8
|
+
*
|
|
9
|
+
* openssl genpkey -algorithm X25519 -out reclaim-decrypt.pem
|
|
10
|
+
*
|
|
11
|
+
* 2. Absent — plaintext-only testing (no decryption key; encrypted
|
|
12
|
+
* deliveries surface a clear error).
|
|
13
|
+
*
|
|
14
|
+
* The PEM *content* is loaded via the client's `loadDecryptionKey` (jose
|
|
15
|
+
* `ECDH-ES`) and passed straight through as `ReclaimConfig.credential` / to
|
|
16
|
+
* `decryptCallback`.
|
|
17
|
+
*/
|
|
18
|
+
import {
|
|
19
|
+
type DecryptionKey,
|
|
20
|
+
loadDecryptionKey,
|
|
21
|
+
} from '@reclaimprotocol/client'
|
|
22
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
23
|
+
import { join } from 'node:path'
|
|
24
|
+
import { findProjectRoot } from '../../../paths.ts'
|
|
25
|
+
|
|
26
|
+
/** Default X25519 PEM filename the agent looks for in the project root. */
|
|
27
|
+
export const DEFAULT_DECRYPT_PEM = 'reclaim-decrypt.pem'
|
|
28
|
+
|
|
29
|
+
/** Resolve the decrypt-PEM path (the default file in the project root). */
|
|
30
|
+
export function decryptPemPath(
|
|
31
|
+
projectDir = findProjectRoot(process.cwd()),
|
|
32
|
+
): string {
|
|
33
|
+
return join(projectDir, DEFAULT_DECRYPT_PEM)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Read the raw decryption-key PEM string from the default file, without loading
|
|
38
|
+
* it. Returns `undefined` when the file is absent (plaintext-only).
|
|
39
|
+
*/
|
|
40
|
+
export function resolveDecryptKeyInput(
|
|
41
|
+
projectDir = findProjectRoot(process.cwd()),
|
|
42
|
+
): string | undefined {
|
|
43
|
+
const pemPath = decryptPemPath(projectDir)
|
|
44
|
+
if(existsSync(pemPath)) {
|
|
45
|
+
return readFileSync(pemPath, 'utf8')
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return undefined
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Load the optional decryption key. Returns `undefined` when the PEM file is
|
|
53
|
+
* absent (the consumer then handles only plaintext deliveries).
|
|
54
|
+
*/
|
|
55
|
+
export async function resolveDecryptionKey(
|
|
56
|
+
projectDir = findProjectRoot(process.cwd()),
|
|
57
|
+
): Promise<DecryptionKey | undefined> {
|
|
58
|
+
const input = resolveDecryptKeyInput(projectDir)
|
|
59
|
+
if(input === undefined) {
|
|
60
|
+
return undefined
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return loadDecryptionKey(input)
|
|
64
|
+
}
|