@reclaimprotocol/agent 0.1.1-dev.1 → 0.1.2
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/cdp/launcher.js +4 -3
- package/lib/config/store.d.ts +7 -6
- package/lib/config/store.js +2 -2
- package/lib/consts.d.ts +68 -0
- package/lib/consts.js +134 -0
- package/lib/index.d.ts +2 -2
- package/lib/index.js +1 -1
- package/lib/logger.js +2 -1
- package/lib/mcp/api/operations.gen.d.ts +100 -48
- package/lib/mcp/api/operations.gen.js +1129 -194
- 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 -8
- package/lib/mcp/server.js +3 -33
- package/lib/mcp/start.js +17 -11
- package/lib/mcp/tools/agent/build.d.ts +5 -9
- package/lib/mcp/tools/agent/build.js +7 -24
- 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 +3 -7
- package/lib/mcp/tools/agent/propose.js +13 -2
- package/lib/mcp/tools/agent/publish.js +172 -75
- 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 +19 -0
- package/lib/mcp/tools/authenticate/decrypt-key.js +46 -0
- package/lib/mcp/tools/authenticate/eth-key.d.ts +31 -0
- package/lib/mcp/tools/authenticate/eth-key.js +116 -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 +11 -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/flag.d.ts +4 -1
- package/lib/old/flag.js +4 -3
- package/lib/old/identity.d.ts +0 -10
- package/lib/old/identity.js +8 -7
- package/lib/old/instructions.d.ts +0 -6
- package/lib/old/instructions.js +6 -24
- package/lib/old/login-cdp.d.ts +0 -3
- package/lib/old/login-cdp.js +2 -4
- package/lib/old/to-register.d.ts +3 -0
- package/lib/old/to-register.js +32 -7
- package/lib/old/tools/authenticate.js +2 -1
- package/lib/old/tools/publish.js +71 -10
- package/lib/paths.js +2 -2
- package/lib/proof/attestor.d.ts +33 -1
- package/lib/proof/attestor.js +67 -64
- 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 +84 -0
- package/lib/provider/index.d.ts +5 -0
- package/lib/provider/index.js +9 -0
- package/lib/provider/injection-doc.d.ts +1 -0
- package/lib/provider/injection-doc.js +17 -0
- package/lib/provider/match-redaction-warning.d.ts +25 -0
- package/lib/provider/match-redaction-warning.js +35 -0
- package/lib/provider/schema.d.ts +16 -0
- package/lib/provider/schema.js +11 -1
- package/lib/provider/to-version.d.ts +61 -12
- package/lib/provider/to-version.js +109 -24
- 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 +16 -7
- package/skill/SKILL.md +35 -14
- package/skill/builder-mode.md +13 -0
- package/skill/injection-api.md +42 -0
- package/skill/old-mode.md +15 -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/cdp/launcher.ts +5 -4
- package/src/config/store.ts +7 -6
- package/src/consts.ts +164 -0
- package/src/index.ts +2 -4
- package/src/logger.ts +2 -1
- package/src/mcp/api/operations.gen.ts +1155 -194
- 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 -50
- package/src/mcp/start.ts +27 -11
- package/src/mcp/tools/agent/build.ts +7 -27
- package/src/mcp/tools/agent/index.ts +4 -0
- package/src/mcp/tools/agent/proof.ts +3 -8
- package/src/mcp/tools/agent/propose.ts +13 -2
- package/src/mcp/tools/agent/publish.ts +218 -92
- 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 +59 -0
- package/src/mcp/tools/authenticate/eth-key.ts +162 -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 +154 -0
- package/src/old/client.ts +3 -0
- package/src/old/flag.ts +4 -3
- package/src/old/identity.ts +8 -7
- package/src/old/instructions.ts +10 -25
- package/src/old/login-cdp.ts +2 -5
- package/src/old/to-register.ts +58 -26
- package/src/old/tools/authenticate.ts +2 -1
- package/src/old/tools/publish.ts +92 -16
- package/src/paths.ts +2 -2
- package/src/proof/attestor.ts +114 -72
- package/src/proof/index.ts +21 -0
- package/src/proof/proof-core.ts +119 -0
- package/src/provider/index.ts +20 -0
- package/src/provider/injection-doc.ts +21 -0
- package/src/provider/match-redaction-warning.ts +53 -0
- package/src/provider/schema.ts +23 -0
- package/src/provider/to-version.ts +180 -33
- 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
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
|
|
2
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
CallToolRequestSchema,
|
|
7
|
-
ListToolsRequestSchema,
|
|
8
|
-
} from '@modelcontextprotocol/sdk/types.js'
|
|
9
|
-
import { convertJsonSchemaToZod, type JSONSchema } from 'zod-from-json-schema'
|
|
2
|
+
import type { JSONSchema } from 'zod/v4/core'
|
|
3
|
+
import { toZod } from './api/to-zod.ts'
|
|
10
4
|
import { remapErrorAsResponse } from './remap_errors.ts'
|
|
11
5
|
|
|
12
6
|
export interface ToolDefinition {
|
|
13
7
|
name: string
|
|
14
8
|
description: string
|
|
15
|
-
inputSchema: JSONSchema
|
|
9
|
+
inputSchema: JSONSchema.ObjectSchema
|
|
16
10
|
}
|
|
17
11
|
|
|
18
12
|
export interface RegisteredTool {
|
|
@@ -38,7 +32,7 @@ export function defineTool<TArgs>(
|
|
|
38
32
|
definition: ToolDefinition,
|
|
39
33
|
handler: (args: TArgs) => Promise<unknown>,
|
|
40
34
|
): RegisteredTool {
|
|
41
|
-
const schema =
|
|
35
|
+
const schema = toZod(definition.inputSchema)
|
|
42
36
|
return {
|
|
43
37
|
definition,
|
|
44
38
|
handler: async(raw) => {
|
|
@@ -59,7 +53,7 @@ export function registerToolList(server: McpServer, tools: RegisteredTool[]) {
|
|
|
59
53
|
tool.definition.name,
|
|
60
54
|
{
|
|
61
55
|
description: tool.definition.description,
|
|
62
|
-
inputSchema:
|
|
56
|
+
inputSchema: toZod(tool.definition.inputSchema),
|
|
63
57
|
},
|
|
64
58
|
async(args) => {
|
|
65
59
|
try {
|
|
@@ -78,42 +72,3 @@ export function registerToolList(server: McpServer, tools: RegisteredTool[]) {
|
|
|
78
72
|
)
|
|
79
73
|
}
|
|
80
74
|
}
|
|
81
|
-
|
|
82
|
-
export class ReclaimMcpServer {
|
|
83
|
-
#tools = new Map<string, RegisteredTool>()
|
|
84
|
-
#server: Server
|
|
85
|
-
|
|
86
|
-
constructor() {
|
|
87
|
-
this.#server = new Server(
|
|
88
|
-
{ name: 'reclaim-agent', version: '0.1.0' },
|
|
89
|
-
{ capabilities: { tools: {} } },
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
this.#server.setRequestHandler(ListToolsRequestSchema, async() => ({
|
|
93
|
-
// Double-cast: our `ToolDefinition` carries the same fields as the
|
|
94
|
-
// SDK's `Tool` but the SDK's type is strict-narrowed and won't
|
|
95
|
-
// accept ours without going through `unknown`.
|
|
96
|
-
tools: [...this.#tools.values()].map(
|
|
97
|
-
(t) => t.definition as unknown as Tool,
|
|
98
|
-
),
|
|
99
|
-
}))
|
|
100
|
-
|
|
101
|
-
this.#server.setRequestHandler(CallToolRequestSchema, async(req) => {
|
|
102
|
-
const tool = this.#tools.get(req.params.name)
|
|
103
|
-
if(!tool) {
|
|
104
|
-
throw new Error(`unknown tool: ${req.params.name}`)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const result = await tool.handler(req.params.arguments ?? {})
|
|
108
|
-
return { content: [{ type: 'text', text: JSON.stringify(result) }] }
|
|
109
|
-
})
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
register(tool: RegisteredTool) {
|
|
113
|
-
this.#tools.set(tool.definition.name, tool)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async listen(): Promise<void> {
|
|
117
|
-
await this.#server.connect(new StdioServerTransport())
|
|
118
|
-
}
|
|
119
|
-
}
|
package/src/mcp/start.ts
CHANGED
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
2
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
3
|
+
import { ReclaimClient } from '@reclaimprotocol/client'
|
|
4
|
+
import {
|
|
5
|
+
agentDisabled,
|
|
6
|
+
apiToken,
|
|
7
|
+
apiUrl,
|
|
8
|
+
oldApiUrl,
|
|
9
|
+
useOldDevtools,
|
|
10
|
+
} from '../consts.ts'
|
|
11
|
+
import { ReclaimOldClient } from '../old/client.ts'
|
|
6
12
|
import { resolveInitialIdentity } from '../old/identity.ts'
|
|
7
13
|
import { OLD_MODE_INSTRUCTIONS } from '../old/instructions.ts'
|
|
8
14
|
import { buildOldBackendTools } from '../old/tools/build.ts'
|
|
9
15
|
import { NAME, VERSION } from '../pkg.ts'
|
|
10
16
|
import { registerTools } from './api/tools.ts'
|
|
11
|
-
import { buildAgentTools } from './tools/agent/build.ts'
|
|
12
17
|
import {
|
|
18
|
+
buildAgentTools,
|
|
13
19
|
buildCredentialTools,
|
|
14
20
|
buildLocalCredentialTools,
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
buildVerificationTools,
|
|
22
|
+
readSession,
|
|
23
|
+
} from './tools/index.ts'
|
|
24
|
+
import { BUILDER_MODE_INSTRUCTIONS } from './instructions.ts'
|
|
17
25
|
import { registerToolList } from './server.ts'
|
|
18
26
|
|
|
19
27
|
export async function startMcpServer() {
|
|
@@ -21,14 +29,18 @@ export async function startMcpServer() {
|
|
|
21
29
|
|
|
22
30
|
const server = new McpServer(
|
|
23
31
|
{ name: NAME, version: VERSION },
|
|
24
|
-
|
|
32
|
+
{
|
|
33
|
+
instructions: oldMode
|
|
34
|
+
? OLD_MODE_INSTRUCTIONS
|
|
35
|
+
: BUILDER_MODE_INSTRUCTIONS,
|
|
36
|
+
},
|
|
25
37
|
)
|
|
26
38
|
|
|
27
39
|
// Agent tools (Chrome CDP capture, provider synthesis, replay, proof) are
|
|
28
40
|
// backend-independent and registered in both modes. Skipped in hosted
|
|
29
41
|
// deployments — set RECLAIM_AGENT_DISABLED=1 to register only the API
|
|
30
42
|
// surface.
|
|
31
|
-
const agentToolsEnabled =
|
|
43
|
+
const agentToolsEnabled = !agentDisabled()
|
|
32
44
|
|
|
33
45
|
if(oldMode) {
|
|
34
46
|
// OLD-devtools mode (the default): the legacy backend is still in
|
|
@@ -36,7 +48,7 @@ export async function startMcpServer() {
|
|
|
36
48
|
// are disabled; a small ReclaimOldClient serves authenticate / publish /
|
|
37
49
|
// get_me_providers instead.
|
|
38
50
|
const oldClient = new ReclaimOldClient({
|
|
39
|
-
baseUrl:
|
|
51
|
+
baseUrl: oldApiUrl(),
|
|
40
52
|
identity: resolveInitialIdentity(),
|
|
41
53
|
})
|
|
42
54
|
|
|
@@ -49,9 +61,9 @@ export async function startMcpServer() {
|
|
|
49
61
|
// NOTE: registerTools() is intentionally NOT called — generated tools off.
|
|
50
62
|
} else {
|
|
51
63
|
const client = new ReclaimClient({
|
|
52
|
-
baseUrl:
|
|
64
|
+
baseUrl: apiUrl(),
|
|
53
65
|
// Priority: explicit env var → cached session token → unauthenticated
|
|
54
|
-
token:
|
|
66
|
+
token: apiToken() || readSession()?.token,
|
|
55
67
|
headers: { 'User-Agent': `${NAME}/${VERSION}` },
|
|
56
68
|
})
|
|
57
69
|
|
|
@@ -64,6 +76,10 @@ export async function startMcpServer() {
|
|
|
64
76
|
// Register credential tools for ETH credential management.
|
|
65
77
|
registerToolList(server, buildCredentialTools(client))
|
|
66
78
|
|
|
79
|
+
// Higher-level verification orchestrations (e.g. fetch + decrypt result).
|
|
80
|
+
// Authenticates with RECLAIM_ORG_SECRET, not the session client.
|
|
81
|
+
registerToolList(server, buildVerificationTools())
|
|
82
|
+
|
|
67
83
|
// Add auto-generated tools with snake_case wrappers
|
|
68
84
|
// for every MCP-tagged operation.
|
|
69
85
|
registerTools(server, client)
|
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Factory entry-point for embedding the reclaim-agent's MCP tools into
|
|
3
|
-
* a host MCP server.
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* the low-level wrapper around `@modelcontextprotocol/sdk`'s Server).
|
|
7
|
-
* - `@reclaimprotocol/client`'s MCP server (uses `McpServer`, the
|
|
8
|
-
* high-level SDK wrapper). Calls `registerAgentTools` to fold the
|
|
9
|
-
* agent's 16 tools alongside its auto-generated API tools.
|
|
3
|
+
* a host MCP server via `registerToolList` (server.ts) on the high-level
|
|
4
|
+
* `@modelcontextprotocol/sdk` `McpServer`. Folds the agent's tools
|
|
5
|
+
* alongside the auto-generated API tools.
|
|
10
6
|
*
|
|
11
7
|
* Shared state — Chrome attach state, capture store, secret store — is
|
|
12
8
|
* built once per server and threaded through every tool factory.
|
|
13
9
|
*/
|
|
14
10
|
|
|
15
11
|
import type { ReclaimClient } from '@reclaimprotocol/client'
|
|
16
|
-
import { setCryptoImplementation } from '@reclaimprotocol/tls'
|
|
17
|
-
import { webcryptoCrypto } from '@reclaimprotocol/tls/webcrypto'
|
|
18
12
|
import { ConfigStore } from '../../../config/store.ts'
|
|
13
|
+
import { ensureAttestorCrypto } from '../../../proof/proof-core.ts'
|
|
19
14
|
import { type RegisteredTool } from '../../server.ts'
|
|
20
15
|
import { analyzeTool } from './analyze.ts'
|
|
21
16
|
import { type AttachState, attachTool } from './attach.ts'
|
|
@@ -38,21 +33,6 @@ export interface AgentState {
|
|
|
38
33
|
secrets: SecretStore
|
|
39
34
|
}
|
|
40
35
|
|
|
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
36
|
function buildAgentState(): AgentState {
|
|
57
37
|
return {
|
|
58
38
|
attach: { config: new ConfigStore() },
|
|
@@ -61,8 +41,8 @@ function buildAgentState(): AgentState {
|
|
|
61
41
|
}
|
|
62
42
|
}
|
|
63
43
|
|
|
64
|
-
/** Build the flat list of `RegisteredTool` entries
|
|
65
|
-
*
|
|
44
|
+
/** Build the flat list of `RegisteredTool` entries, ready for
|
|
45
|
+
* `registerToolList`.
|
|
66
46
|
* Pass `client` to include the builder `create_provider_version_from_capture`;
|
|
67
47
|
* omit it (e.g. OLD-devtools mode) to register only the backend-independent
|
|
68
48
|
* capture/proof tools — old mode supplies its own publish tool. */
|
|
@@ -70,7 +50,7 @@ export function buildAgentTools(
|
|
|
70
50
|
client?: ReclaimClient,
|
|
71
51
|
): RegisteredTool[] {
|
|
72
52
|
const state = buildAgentState()
|
|
73
|
-
|
|
53
|
+
ensureAttestorCrypto()
|
|
74
54
|
const tools: RegisteredTool[] = []
|
|
75
55
|
tools.push(attachTool(state.attach))
|
|
76
56
|
for(const t of captureTools(state.attach, state.captures)) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mkdirSync, writeFileSync } from 'node:fs'
|
|
2
2
|
import { join } from 'node:path'
|
|
3
|
+
import { agentTraceEnabled } from '../../../consts.ts'
|
|
3
4
|
import { reclaimHomeDirPath } from '../../../paths.ts'
|
|
4
5
|
import {
|
|
5
6
|
runAttestorProof,
|
|
@@ -135,11 +136,6 @@ export function proofTool(secrets: SecretStore): RegisteredTool {
|
|
|
135
136
|
inputSchema: {
|
|
136
137
|
type: 'object',
|
|
137
138
|
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
139
|
provider: { type: 'object', properties: {} },
|
|
144
140
|
secretParamsRef: { type: 'string' },
|
|
145
141
|
attestorUrl: { type: 'string' },
|
|
@@ -173,8 +169,7 @@ export function proofTool(secrets: SecretStore): RegisteredTool {
|
|
|
173
169
|
const result = await runAttestorProof(
|
|
174
170
|
provider as ReclaimProvider,
|
|
175
171
|
resolved,
|
|
176
|
-
attestorUrl,
|
|
177
|
-
ownerAddress,
|
|
172
|
+
{ attestorUrl, ownerAddress },
|
|
178
173
|
)
|
|
179
174
|
|
|
180
175
|
// Persist the full claim to disk for the dev to inspect/share.
|
|
@@ -243,7 +238,7 @@ export function proofTool(secrets: SecretStore): RegisteredTool {
|
|
|
243
238
|
// when investigating proof failures and the file at runLogPath
|
|
244
239
|
// will carry the input provider, sentParams, full attestor log
|
|
245
240
|
// stream, and result.
|
|
246
|
-
if(
|
|
241
|
+
if(agentTraceEnabled()) {
|
|
247
242
|
const runLogPath = writeProofRunDump({
|
|
248
243
|
provider,
|
|
249
244
|
hasSecretParamsRef: secretParamsRef !== undefined,
|
|
@@ -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
|
}
|