@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.
Files changed (204) hide show
  1. package/README.md +1 -1
  2. package/lib/cdp/capture-engine.d.ts +66 -0
  3. package/lib/cdp/capture-engine.js +153 -0
  4. package/lib/cdp/capture.d.ts +9 -20
  5. package/lib/cdp/capture.js +14 -138
  6. package/lib/cdp/index.d.ts +3 -0
  7. package/lib/cdp/index.js +6 -0
  8. package/lib/config/store.d.ts +7 -6
  9. package/lib/config/store.js +2 -2
  10. package/lib/index.d.ts +2 -2
  11. package/lib/index.js +1 -1
  12. package/lib/mcp/api/operations.gen.d.ts +101 -45
  13. package/lib/mcp/api/operations.gen.js +996 -126
  14. package/lib/mcp/api/to-zod.d.ts +24 -0
  15. package/lib/mcp/api/to-zod.js +94 -0
  16. package/lib/mcp/api/tools.js +1 -1
  17. package/lib/mcp/credentials/authenticate.d.ts +3 -0
  18. package/lib/mcp/{tools/credentials → credentials}/authenticate.js +3 -3
  19. package/lib/mcp/credentials/build.d.ts +5 -0
  20. package/lib/mcp/credentials/build.js +18 -0
  21. package/lib/mcp/{tools/credentials → credentials}/cache.d.ts +9 -9
  22. package/lib/mcp/{tools/credentials → credentials}/cache.js +36 -19
  23. package/lib/mcp/credentials/import.d.ts +2 -0
  24. package/lib/mcp/{tools/credentials → credentials}/import.js +2 -2
  25. package/lib/mcp/credentials/issue.d.ts +2 -0
  26. package/lib/mcp/{tools/credentials → credentials}/issue.js +4 -4
  27. package/lib/mcp/credentials/keypair.d.ts +17 -0
  28. package/lib/mcp/credentials/keypair.js +48 -0
  29. package/lib/mcp/credentials/link.d.ts +3 -0
  30. package/lib/mcp/credentials/link.js +107 -0
  31. package/lib/mcp/{tools/credentials → credentials}/list-cached.d.ts +1 -1
  32. package/lib/mcp/{tools/credentials → credentials}/list-cached.js +5 -5
  33. package/lib/mcp/credentials/owner-key.d.ts +23 -0
  34. package/lib/mcp/credentials/owner-key.js +58 -0
  35. package/lib/mcp/credentials/paths.d.ts +12 -0
  36. package/lib/mcp/credentials/paths.js +35 -0
  37. package/lib/mcp/credentials/poll.d.ts +27 -0
  38. package/lib/mcp/credentials/poll.js +61 -0
  39. package/lib/mcp/{tools/credentials → credentials}/resolve-owner-key.d.ts +1 -1
  40. package/lib/mcp/{tools/credentials → credentials}/resolve-owner-key.js +2 -2
  41. package/lib/mcp/credentials/session-cache.d.ts +14 -0
  42. package/lib/mcp/credentials/session-cache.js +42 -0
  43. package/lib/mcp/{tools/credentials → credentials}/status.d.ts +1 -1
  44. package/lib/mcp/credentials/status.js +76 -0
  45. package/lib/mcp/instructions.d.ts +1 -0
  46. package/lib/mcp/instructions.js +11 -0
  47. package/lib/mcp/register.d.ts +38 -0
  48. package/lib/mcp/register.js +80 -0
  49. package/lib/mcp/server.d.ts +2 -2
  50. package/lib/mcp/server.js +3 -3
  51. package/lib/mcp/start.js +10 -4
  52. package/lib/mcp/tools/agent/build.js +2 -15
  53. package/lib/mcp/tools/agent/index.d.ts +2 -0
  54. package/lib/mcp/tools/agent/index.js +3 -0
  55. package/lib/mcp/tools/agent/proof.js +1 -6
  56. package/lib/mcp/tools/agent/propose.js +13 -2
  57. package/lib/mcp/tools/agent/publish.js +10 -2
  58. package/lib/mcp/tools/agent/replay.js +0 -5
  59. package/lib/mcp/tools/analyze.d.ts +3 -0
  60. package/lib/mcp/tools/analyze.js +26 -0
  61. package/lib/mcp/tools/attach.d.ts +11 -0
  62. package/lib/mcp/tools/attach.js +72 -0
  63. package/lib/mcp/tools/authenticate/authenticate.js +107 -0
  64. package/lib/mcp/tools/authenticate/build.d.ts +15 -0
  65. package/lib/mcp/tools/authenticate/build.js +28 -0
  66. package/lib/mcp/tools/authenticate/decrypt-key.d.ts +32 -0
  67. package/lib/mcp/tools/authenticate/decrypt-key.js +49 -0
  68. package/lib/mcp/tools/authenticate/eth-key.d.ts +38 -0
  69. package/lib/mcp/tools/authenticate/eth-key.js +130 -0
  70. package/lib/mcp/tools/authenticate/import.js +57 -0
  71. package/lib/mcp/tools/authenticate/index.d.ts +2 -0
  72. package/lib/mcp/tools/authenticate/index.js +4 -0
  73. package/lib/mcp/tools/authenticate/issue.js +42 -0
  74. package/lib/mcp/tools/authenticate/resolve-owner-key.d.ts +13 -0
  75. package/lib/mcp/tools/authenticate/resolve-owner-key.js +53 -0
  76. package/lib/mcp/tools/capture.d.ts +10 -0
  77. package/lib/mcp/tools/capture.js +142 -0
  78. package/lib/mcp/tools/eval.d.ts +5 -0
  79. package/lib/mcp/tools/eval.js +127 -0
  80. package/lib/mcp/tools/find.d.ts +3 -0
  81. package/lib/mcp/tools/find.js +60 -0
  82. package/lib/mcp/tools/index.d.ts +3 -0
  83. package/lib/mcp/tools/index.js +6 -0
  84. package/lib/mcp/tools/owner-key.d.ts +2 -0
  85. package/lib/mcp/tools/owner-key.js +63 -0
  86. package/lib/mcp/tools/proof.d.ts +3 -0
  87. package/lib/mcp/tools/proof.js +214 -0
  88. package/lib/mcp/tools/propose.d.ts +9 -0
  89. package/lib/mcp/tools/propose.js +75 -0
  90. package/lib/mcp/tools/publish.d.ts +3 -0
  91. package/lib/mcp/tools/publish.js +59 -0
  92. package/lib/mcp/tools/replay.d.ts +3 -0
  93. package/lib/mcp/tools/replay.js +46 -0
  94. package/lib/mcp/tools/session.d.ts +10 -0
  95. package/lib/mcp/tools/session.js +29 -0
  96. package/lib/mcp/tools/verification/build.d.ts +12 -0
  97. package/lib/mcp/tools/verification/build.js +14 -0
  98. package/lib/mcp/tools/verification/diagnose.d.ts +11 -0
  99. package/lib/mcp/tools/verification/diagnose.js +132 -0
  100. package/lib/mcp/tools/verification/index.d.ts +1 -0
  101. package/lib/mcp/tools/verification/index.js +2 -0
  102. package/lib/mcp/tools/verification/result.d.ts +12 -0
  103. package/lib/mcp/tools/verification/result.js +126 -0
  104. package/lib/mcp/verifications/build.d.ts +5 -0
  105. package/lib/mcp/verifications/build.js +14 -0
  106. package/lib/mcp/verifications/create.d.ts +3 -0
  107. package/lib/mcp/verifications/create.js +57 -0
  108. package/lib/mcp/verifications/find.d.ts +3 -0
  109. package/lib/mcp/verifications/find.js +37 -0
  110. package/lib/mcp/verifications/get.d.ts +3 -0
  111. package/lib/mcp/verifications/get.js +26 -0
  112. package/lib/mcp/verifications/update.d.ts +3 -0
  113. package/lib/mcp/verifications/update.js +78 -0
  114. package/lib/old/client.d.ts +3 -0
  115. package/lib/old/instructions.d.ts +0 -6
  116. package/lib/old/instructions.js +6 -24
  117. package/lib/old/to-register.d.ts +3 -0
  118. package/lib/old/to-register.js +35 -7
  119. package/lib/old/tools/publish.js +13 -1
  120. package/lib/proof/attestor.d.ts +33 -1
  121. package/lib/proof/attestor.js +67 -61
  122. package/lib/proof/index.d.ts +5 -0
  123. package/lib/proof/index.js +6 -0
  124. package/lib/proof/proof-core.d.ts +35 -0
  125. package/lib/proof/proof-core.js +73 -0
  126. package/lib/proof/zk-files.d.ts +14 -0
  127. package/lib/proof/zk-files.js +73 -0
  128. package/lib/provider/index.d.ts +5 -0
  129. package/lib/provider/index.js +9 -0
  130. package/lib/provider/to-version.d.ts +9 -12
  131. package/lib/provider/to-version.js +38 -4
  132. package/lib/provider/verification-checks.d.ts +12 -0
  133. package/lib/provider/verification-checks.js +30 -0
  134. package/lib/routes.gen.d.ts +271 -0
  135. package/lib/routes.gen.js +73 -0
  136. package/lib/types/openapi.gen.d.ts +3967 -0
  137. package/lib/types/openapi.gen.js +5 -0
  138. package/package.json +18 -10
  139. package/skill/SKILL.md +35 -14
  140. package/skill/builder-mode.md +9 -0
  141. package/skill/old-mode.md +13 -0
  142. package/src/cdp/capture-engine.ts +256 -0
  143. package/src/cdp/capture.ts +25 -185
  144. package/src/cdp/index.ts +6 -0
  145. package/src/config/store.ts +7 -6
  146. package/src/index.ts +2 -4
  147. package/src/mcp/api/operations.gen.ts +1023 -121
  148. package/src/mcp/api/to-zod.ts +115 -0
  149. package/src/mcp/api/tools.ts +9 -3
  150. package/src/mcp/instructions.ts +15 -0
  151. package/src/mcp/server.ts +5 -4
  152. package/src/mcp/start.ts +14 -4
  153. package/src/mcp/tools/agent/build.ts +2 -18
  154. package/src/mcp/tools/agent/index.ts +4 -0
  155. package/src/mcp/tools/agent/proof.ts +1 -7
  156. package/src/mcp/tools/agent/propose.ts +13 -2
  157. package/src/mcp/tools/agent/publish.ts +10 -2
  158. package/src/mcp/tools/agent/replay.ts +0 -5
  159. package/src/mcp/tools/{credentials → authenticate}/authenticate.ts +9 -8
  160. package/src/mcp/tools/authenticate/build.ts +32 -0
  161. package/src/mcp/tools/authenticate/decrypt-key.ts +64 -0
  162. package/src/mcp/tools/authenticate/eth-key.ts +182 -0
  163. package/src/mcp/tools/authenticate/import.ts +73 -0
  164. package/src/mcp/tools/authenticate/index.ts +4 -0
  165. package/src/mcp/tools/authenticate/issue.ts +50 -0
  166. package/src/mcp/tools/authenticate/resolve-owner-key.ts +60 -0
  167. package/src/mcp/tools/index.ts +6 -0
  168. package/src/mcp/tools/verification/build.ts +16 -0
  169. package/src/mcp/tools/verification/index.ts +2 -0
  170. package/src/mcp/tools/verification/result.ts +155 -0
  171. package/src/old/client.ts +3 -0
  172. package/src/old/instructions.ts +10 -25
  173. package/src/old/to-register.ts +62 -27
  174. package/src/old/tools/publish.ts +17 -1
  175. package/src/proof/attestor.ts +115 -69
  176. package/src/proof/index.ts +21 -0
  177. package/src/proof/proof-core.ts +109 -0
  178. package/src/proof/zk-files.ts +83 -0
  179. package/src/provider/index.ts +20 -0
  180. package/src/provider/to-version.ts +52 -11
  181. package/src/provider/verification-checks.ts +36 -0
  182. package/lib/mcp/tools/credentials/build.d.ts +0 -16
  183. package/lib/mcp/tools/credentials/build.js +0 -33
  184. package/lib/mcp/tools/credentials/status.js +0 -62
  185. package/src/mcp/tools/credentials/build.ts +0 -37
  186. package/src/mcp/tools/credentials/cache.ts +0 -161
  187. package/src/mcp/tools/credentials/env-file.ts +0 -101
  188. package/src/mcp/tools/credentials/import.ts +0 -72
  189. package/src/mcp/tools/credentials/issue.ts +0 -107
  190. package/src/mcp/tools/credentials/list-cached.ts +0 -66
  191. package/src/mcp/tools/credentials/register.ts +0 -49
  192. package/src/mcp/tools/credentials/resolve-owner-key.ts +0 -78
  193. package/src/mcp/tools/credentials/status.ts +0 -82
  194. package/src/types/openapi.ts +0 -7
  195. /package/lib/mcp/{tools/credentials → credentials}/env-file.d.ts +0 -0
  196. /package/lib/mcp/{tools/credentials → credentials}/env-file.js +0 -0
  197. /package/lib/mcp/{tools/credentials → credentials}/register.d.ts +0 -0
  198. /package/lib/mcp/{tools/credentials → credentials}/register.js +0 -0
  199. /package/lib/mcp/tools/{credentials → authenticate}/authenticate.d.ts +0 -0
  200. /package/lib/mcp/tools/{credentials → authenticate}/import.d.ts +0 -0
  201. /package/lib/mcp/tools/{credentials → authenticate}/issue.d.ts +0 -0
  202. /package/lib/mcp/tools/{credentials → authenticate}/session-cache.d.ts +0 -0
  203. /package/lib/mcp/tools/{credentials → authenticate}/session-cache.js +0 -0
  204. /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
+ }
@@ -1,7 +1,10 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
2
2
  import type {
3
- IOperationArgs, IOperationId, ReclaimClient
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: IOperationArgs<IOperationId>) => {
34
+ async(args: unknown) => {
32
35
  try {
33
- const result = (await client.call(opId as IOperationId, args))
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 { convertJsonSchemaToZod, type JSONSchema } from 'zod-from-json-schema'
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 = convertJsonSchemaToZod(definition.inputSchema)
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: convertJsonSchemaToZod(tool.definition.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
- } from './tools/credentials/build.ts'
16
- import { readSession } from './tools/credentials/session-cache.ts'
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
- oldMode ? { instructions: OLD_MODE_INSTRUCTIONS } : undefined,
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
- ensureCryptoInit()
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)) {
@@ -0,0 +1,4 @@
1
+ // Barrel for the agent tool group (Chrome CDP capture, provider synthesis,
2
+ // replay, zkTLS proof). Import from here, not the individual files.
3
+ export { buildAgentTools } from './build.ts'
4
+ export type { AgentState } from './build.ts'
@@ -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
- return { provider, secretRefs, secretParamsRef }
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
- 'For PRIVATE verifications the version goes live immediately; ' +
30
- 'for PUBLIC ones call submit_provider_version_for_review afterwards.',
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 as Session
4
- } from '../../../types/openapi.ts'
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
- 'To then link a credential to an org (needed only to use it ' +
25
- 'for verification in production), use the token with the ' +
26
- 'generated tools: `list_orgs` → `link_credential` with the ' +
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: 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(Date.now() + 2 * 24 * 60 * 60 * 1000).toISOString(),
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
+ }