@bazaar.ai/mcp-human-agents 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. package/.env.example +15 -0
  2. package/README.md +178 -0
  3. package/dist/mcp-server/src/bin.d.ts +3 -0
  4. package/dist/mcp-server/src/bin.d.ts.map +1 -0
  5. package/dist/mcp-server/src/bin.js +10 -0
  6. package/dist/mcp-server/src/bin.js.map +1 -0
  7. package/dist/mcp-server/src/cli/setup.d.ts +2 -0
  8. package/dist/mcp-server/src/cli/setup.d.ts.map +1 -0
  9. package/dist/mcp-server/src/cli/setup.js +274 -0
  10. package/dist/mcp-server/src/cli/setup.js.map +1 -0
  11. package/dist/mcp-server/src/config/defaults.d.ts +16 -0
  12. package/dist/mcp-server/src/config/defaults.d.ts.map +1 -0
  13. package/dist/mcp-server/src/config/defaults.js +19 -0
  14. package/dist/mcp-server/src/config/defaults.js.map +1 -0
  15. package/dist/mcp-server/src/config/env.d.ts +73 -0
  16. package/dist/mcp-server/src/config/env.d.ts.map +1 -0
  17. package/dist/mcp-server/src/config/env.js +72 -0
  18. package/dist/mcp-server/src/config/env.js.map +1 -0
  19. package/dist/mcp-server/src/config/index.d.ts +3 -0
  20. package/dist/mcp-server/src/config/index.d.ts.map +1 -0
  21. package/dist/mcp-server/src/config/index.js +22 -0
  22. package/dist/mcp-server/src/config/index.js.map +1 -0
  23. package/dist/mcp-server/src/context/generator.d.ts +16 -0
  24. package/dist/mcp-server/src/context/generator.d.ts.map +1 -0
  25. package/dist/mcp-server/src/context/generator.js +61 -0
  26. package/dist/mcp-server/src/context/generator.js.map +1 -0
  27. package/dist/mcp-server/src/context/index.d.ts +3 -0
  28. package/dist/mcp-server/src/context/index.d.ts.map +1 -0
  29. package/dist/mcp-server/src/context/index.js +10 -0
  30. package/dist/mcp-server/src/context/index.js.map +1 -0
  31. package/dist/mcp-server/src/context/templates.d.ts +8 -0
  32. package/dist/mcp-server/src/context/templates.d.ts.map +1 -0
  33. package/dist/mcp-server/src/context/templates.js +41 -0
  34. package/dist/mcp-server/src/context/templates.js.map +1 -0
  35. package/dist/mcp-server/src/git/branch.d.ts +13 -0
  36. package/dist/mcp-server/src/git/branch.d.ts.map +1 -0
  37. package/dist/mcp-server/src/git/branch.js +49 -0
  38. package/dist/mcp-server/src/git/branch.js.map +1 -0
  39. package/dist/mcp-server/src/git/diff.d.ts +10 -0
  40. package/dist/mcp-server/src/git/diff.d.ts.map +1 -0
  41. package/dist/mcp-server/src/git/diff.js +39 -0
  42. package/dist/mcp-server/src/git/diff.js.map +1 -0
  43. package/dist/mcp-server/src/git/index.d.ts +5 -0
  44. package/dist/mcp-server/src/git/index.d.ts.map +1 -0
  45. package/dist/mcp-server/src/git/index.js +16 -0
  46. package/dist/mcp-server/src/git/index.js.map +1 -0
  47. package/dist/mcp-server/src/git/merge.d.ts +6 -0
  48. package/dist/mcp-server/src/git/merge.d.ts.map +1 -0
  49. package/dist/mcp-server/src/git/merge.js +30 -0
  50. package/dist/mcp-server/src/git/merge.js.map +1 -0
  51. package/dist/mcp-server/src/git/worktree.d.ts +11 -0
  52. package/dist/mcp-server/src/git/worktree.d.ts.map +1 -0
  53. package/dist/mcp-server/src/git/worktree.js +38 -0
  54. package/dist/mcp-server/src/git/worktree.js.map +1 -0
  55. package/dist/mcp-server/src/http-wrapper.d.ts +6 -0
  56. package/dist/mcp-server/src/http-wrapper.d.ts.map +1 -0
  57. package/dist/mcp-server/src/http-wrapper.js +85 -0
  58. package/dist/mcp-server/src/http-wrapper.js.map +1 -0
  59. package/dist/mcp-server/src/index.d.ts +2 -0
  60. package/dist/mcp-server/src/index.d.ts.map +1 -0
  61. package/dist/mcp-server/src/index.js +28 -0
  62. package/dist/mcp-server/src/index.js.map +1 -0
  63. package/dist/mcp-server/src/platform-client/client.d.ts +17 -0
  64. package/dist/mcp-server/src/platform-client/client.d.ts.map +1 -0
  65. package/dist/mcp-server/src/platform-client/client.js +68 -0
  66. package/dist/mcp-server/src/platform-client/client.js.map +1 -0
  67. package/dist/mcp-server/src/platform-client/index.d.ts +5 -0
  68. package/dist/mcp-server/src/platform-client/index.d.ts.map +1 -0
  69. package/dist/mcp-server/src/platform-client/index.js +10 -0
  70. package/dist/mcp-server/src/platform-client/index.js.map +1 -0
  71. package/dist/mcp-server/src/platform-client/mock-client.d.ts +28 -0
  72. package/dist/mcp-server/src/platform-client/mock-client.d.ts.map +1 -0
  73. package/dist/mcp-server/src/platform-client/mock-client.js +75 -0
  74. package/dist/mcp-server/src/platform-client/mock-client.js.map +1 -0
  75. package/dist/mcp-server/src/platform-client/polling.d.ts +9 -0
  76. package/dist/mcp-server/src/platform-client/polling.d.ts.map +1 -0
  77. package/dist/mcp-server/src/platform-client/polling.js +40 -0
  78. package/dist/mcp-server/src/platform-client/polling.js.map +1 -0
  79. package/dist/mcp-server/src/platform-client/types.d.ts +2 -0
  80. package/dist/mcp-server/src/platform-client/types.d.ts.map +1 -0
  81. package/dist/mcp-server/src/platform-client/types.js +3 -0
  82. package/dist/mcp-server/src/platform-client/types.js.map +1 -0
  83. package/dist/mcp-server/src/provisioning/authorized-keys.d.ts +14 -0
  84. package/dist/mcp-server/src/provisioning/authorized-keys.d.ts.map +1 -0
  85. package/dist/mcp-server/src/provisioning/authorized-keys.js +48 -0
  86. package/dist/mcp-server/src/provisioning/authorized-keys.js.map +1 -0
  87. package/dist/mcp-server/src/provisioning/cleanup.d.ts +19 -0
  88. package/dist/mcp-server/src/provisioning/cleanup.d.ts.map +1 -0
  89. package/dist/mcp-server/src/provisioning/cleanup.js +96 -0
  90. package/dist/mcp-server/src/provisioning/cleanup.js.map +1 -0
  91. package/dist/mcp-server/src/provisioning/index.d.ts +6 -0
  92. package/dist/mcp-server/src/provisioning/index.d.ts.map +1 -0
  93. package/dist/mcp-server/src/provisioning/index.js +24 -0
  94. package/dist/mcp-server/src/provisioning/index.js.map +1 -0
  95. package/dist/mcp-server/src/provisioning/linux-user.d.ts +15 -0
  96. package/dist/mcp-server/src/provisioning/linux-user.d.ts.map +1 -0
  97. package/dist/mcp-server/src/provisioning/linux-user.js +62 -0
  98. package/dist/mcp-server/src/provisioning/linux-user.js.map +1 -0
  99. package/dist/mcp-server/src/provisioning/privileged.d.ts +40 -0
  100. package/dist/mcp-server/src/provisioning/privileged.d.ts.map +1 -0
  101. package/dist/mcp-server/src/provisioning/privileged.js +123 -0
  102. package/dist/mcp-server/src/provisioning/privileged.js.map +1 -0
  103. package/dist/mcp-server/src/provisioning/ssh-config.d.ts +21 -0
  104. package/dist/mcp-server/src/provisioning/ssh-config.d.ts.map +1 -0
  105. package/dist/mcp-server/src/provisioning/ssh-config.js +161 -0
  106. package/dist/mcp-server/src/provisioning/ssh-config.js.map +1 -0
  107. package/dist/mcp-server/src/provisioning/tmux-session.d.ts +37 -0
  108. package/dist/mcp-server/src/provisioning/tmux-session.d.ts.map +1 -0
  109. package/dist/mcp-server/src/provisioning/tmux-session.js +123 -0
  110. package/dist/mcp-server/src/provisioning/tmux-session.js.map +1 -0
  111. package/dist/mcp-server/src/server.d.ts +3 -0
  112. package/dist/mcp-server/src/server.d.ts.map +1 -0
  113. package/dist/mcp-server/src/server.js +67 -0
  114. package/dist/mcp-server/src/server.js.map +1 -0
  115. package/dist/mcp-server/src/state/gig-store.d.ts +19 -0
  116. package/dist/mcp-server/src/state/gig-store.d.ts.map +1 -0
  117. package/dist/mcp-server/src/state/gig-store.js +52 -0
  118. package/dist/mcp-server/src/state/gig-store.js.map +1 -0
  119. package/dist/mcp-server/src/state/index.d.ts +4 -0
  120. package/dist/mcp-server/src/state/index.d.ts.map +1 -0
  121. package/dist/mcp-server/src/state/index.js +8 -0
  122. package/dist/mcp-server/src/state/index.js.map +1 -0
  123. package/dist/mcp-server/src/state/persistence.d.ts +13 -0
  124. package/dist/mcp-server/src/state/persistence.d.ts.map +1 -0
  125. package/dist/mcp-server/src/state/persistence.js +48 -0
  126. package/dist/mcp-server/src/state/persistence.js.map +1 -0
  127. package/dist/mcp-server/src/state/types.d.ts +15 -0
  128. package/dist/mcp-server/src/state/types.d.ts.map +1 -0
  129. package/dist/mcp-server/src/state/types.js +3 -0
  130. package/dist/mcp-server/src/state/types.js.map +1 -0
  131. package/dist/mcp-server/src/tools/dismiss-human.d.ts +25 -0
  132. package/dist/mcp-server/src/tools/dismiss-human.d.ts.map +1 -0
  133. package/dist/mcp-server/src/tools/dismiss-human.js +78 -0
  134. package/dist/mcp-server/src/tools/dismiss-human.js.map +1 -0
  135. package/dist/mcp-server/src/tools/index.d.ts +9 -0
  136. package/dist/mcp-server/src/tools/index.d.ts.map +1 -0
  137. package/dist/mcp-server/src/tools/index.js +20 -0
  138. package/dist/mcp-server/src/tools/index.js.map +1 -0
  139. package/dist/mcp-server/src/tools/list-humans.d.ts +18 -0
  140. package/dist/mcp-server/src/tools/list-humans.d.ts.map +1 -0
  141. package/dist/mcp-server/src/tools/list-humans.js +35 -0
  142. package/dist/mcp-server/src/tools/list-humans.js.map +1 -0
  143. package/dist/mcp-server/src/tools/message-human.d.ts +10 -0
  144. package/dist/mcp-server/src/tools/message-human.d.ts.map +1 -0
  145. package/dist/mcp-server/src/tools/message-human.js +19 -0
  146. package/dist/mcp-server/src/tools/message-human.js.map +1 -0
  147. package/dist/mcp-server/src/tools/schemas/dismiss-human.schema.d.ts +19 -0
  148. package/dist/mcp-server/src/tools/schemas/dismiss-human.schema.d.ts.map +1 -0
  149. package/dist/mcp-server/src/tools/schemas/dismiss-human.schema.js +22 -0
  150. package/dist/mcp-server/src/tools/schemas/dismiss-human.schema.js.map +1 -0
  151. package/dist/mcp-server/src/tools/schemas/list-humans.schema.d.ts +4 -0
  152. package/dist/mcp-server/src/tools/schemas/list-humans.schema.d.ts.map +1 -0
  153. package/dist/mcp-server/src/tools/schemas/list-humans.schema.js +7 -0
  154. package/dist/mcp-server/src/tools/schemas/list-humans.schema.js.map +1 -0
  155. package/dist/mcp-server/src/tools/schemas/message-human.schema.d.ts +13 -0
  156. package/dist/mcp-server/src/tools/schemas/message-human.schema.d.ts.map +1 -0
  157. package/dist/mcp-server/src/tools/schemas/message-human.schema.js +9 -0
  158. package/dist/mcp-server/src/tools/schemas/message-human.schema.js.map +1 -0
  159. package/dist/mcp-server/src/tools/schemas/summon-human.schema.d.ts +22 -0
  160. package/dist/mcp-server/src/tools/schemas/summon-human.schema.d.ts.map +1 -0
  161. package/dist/mcp-server/src/tools/schemas/summon-human.schema.js +18 -0
  162. package/dist/mcp-server/src/tools/schemas/summon-human.schema.js.map +1 -0
  163. package/dist/mcp-server/src/tools/summon-human.d.ts +31 -0
  164. package/dist/mcp-server/src/tools/summon-human.d.ts.map +1 -0
  165. package/dist/mcp-server/src/tools/summon-human.js +137 -0
  166. package/dist/mcp-server/src/tools/summon-human.js.map +1 -0
  167. package/dist/mcp-server/src/tunnel/client.d.ts +16 -0
  168. package/dist/mcp-server/src/tunnel/client.d.ts.map +1 -0
  169. package/dist/mcp-server/src/tunnel/client.js +100 -0
  170. package/dist/mcp-server/src/tunnel/client.js.map +1 -0
  171. package/dist/mcp-server/src/tunnel/index.d.ts +6 -0
  172. package/dist/mcp-server/src/tunnel/index.d.ts.map +1 -0
  173. package/dist/mcp-server/src/tunnel/index.js +28 -0
  174. package/dist/mcp-server/src/tunnel/index.js.map +1 -0
  175. package/dist/mcp-server/src/utils/errors.d.ts +28 -0
  176. package/dist/mcp-server/src/utils/errors.d.ts.map +1 -0
  177. package/dist/mcp-server/src/utils/errors.js +66 -0
  178. package/dist/mcp-server/src/utils/errors.js.map +1 -0
  179. package/dist/mcp-server/src/utils/exec.d.ts +7 -0
  180. package/dist/mcp-server/src/utils/exec.d.ts.map +1 -0
  181. package/dist/mcp-server/src/utils/exec.js +22 -0
  182. package/dist/mcp-server/src/utils/exec.js.map +1 -0
  183. package/dist/mcp-server/src/utils/ip.d.ts +6 -0
  184. package/dist/mcp-server/src/utils/ip.d.ts.map +1 -0
  185. package/dist/mcp-server/src/utils/ip.js +33 -0
  186. package/dist/mcp-server/src/utils/ip.js.map +1 -0
  187. package/dist/mcp-server/src/utils/logger.d.ts +20 -0
  188. package/dist/mcp-server/src/utils/logger.d.ts.map +1 -0
  189. package/dist/mcp-server/src/utils/logger.js +41 -0
  190. package/dist/mcp-server/src/utils/logger.js.map +1 -0
  191. package/dist/shared/src/contractor.types.d.ts +20 -0
  192. package/dist/shared/src/contractor.types.d.ts.map +1 -0
  193. package/dist/shared/src/contractor.types.js +3 -0
  194. package/dist/shared/src/contractor.types.js.map +1 -0
  195. package/dist/shared/src/gig.types.d.ts +32 -0
  196. package/dist/shared/src/gig.types.d.ts.map +1 -0
  197. package/dist/shared/src/gig.types.js +21 -0
  198. package/dist/shared/src/gig.types.js.map +1 -0
  199. package/dist/shared/src/index.d.ts +5 -0
  200. package/dist/shared/src/index.d.ts.map +1 -0
  201. package/dist/shared/src/index.js +21 -0
  202. package/dist/shared/src/index.js.map +1 -0
  203. package/dist/shared/src/mcp-tool.types.d.ts +45 -0
  204. package/dist/shared/src/mcp-tool.types.d.ts.map +1 -0
  205. package/dist/shared/src/mcp-tool.types.js +3 -0
  206. package/dist/shared/src/mcp-tool.types.js.map +1 -0
  207. package/dist/shared/src/platform-api.types.d.ts +73 -0
  208. package/dist/shared/src/platform-api.types.d.ts.map +1 -0
  209. package/dist/shared/src/platform-api.types.js +3 -0
  210. package/dist/shared/src/platform-api.types.js.map +1 -0
  211. package/package.json +41 -0
  212. package/src/bin.ts +7 -0
  213. package/src/cli/setup.ts +317 -0
  214. package/src/config/defaults.ts +21 -0
  215. package/src/config/env.ts +74 -0
  216. package/src/config/index.ts +2 -0
  217. package/src/context/generator.ts +71 -0
  218. package/src/context/index.ts +6 -0
  219. package/src/context/templates.ts +41 -0
  220. package/src/git/branch.ts +46 -0
  221. package/src/git/diff.ts +34 -0
  222. package/src/git/index.ts +4 -0
  223. package/src/git/merge.ts +36 -0
  224. package/src/git/worktree.ts +42 -0
  225. package/src/http-wrapper.ts +94 -0
  226. package/src/index.ts +32 -0
  227. package/src/platform-client/client.ts +93 -0
  228. package/src/platform-client/index.ts +4 -0
  229. package/src/platform-client/mock-client.ts +92 -0
  230. package/src/platform-client/polling.ts +53 -0
  231. package/src/platform-client/types.ts +9 -0
  232. package/src/provisioning/authorized-keys.ts +52 -0
  233. package/src/provisioning/cleanup.ts +106 -0
  234. package/src/provisioning/index.ts +13 -0
  235. package/src/provisioning/linux-user.ts +66 -0
  236. package/src/provisioning/privileged.ts +128 -0
  237. package/src/provisioning/ssh-config.ts +197 -0
  238. package/src/provisioning/tmux-session.ts +136 -0
  239. package/src/server.ts +111 -0
  240. package/src/state/gig-store.ts +56 -0
  241. package/src/state/index.ts +3 -0
  242. package/src/state/persistence.ts +42 -0
  243. package/src/state/types.ts +14 -0
  244. package/src/tools/dismiss-human.ts +103 -0
  245. package/src/tools/index.ts +9 -0
  246. package/src/tools/list-humans.ts +54 -0
  247. package/src/tools/message-human.ts +28 -0
  248. package/src/tools/schemas/dismiss-human.schema.ts +21 -0
  249. package/src/tools/schemas/list-humans.schema.ts +6 -0
  250. package/src/tools/schemas/message-human.schema.ts +8 -0
  251. package/src/tools/schemas/summon-human.schema.ts +19 -0
  252. package/src/tools/summon-human.ts +180 -0
  253. package/src/tunnel/client.ts +116 -0
  254. package/src/tunnel/index.ts +26 -0
  255. package/src/utils/errors.ts +64 -0
  256. package/src/utils/exec.ts +29 -0
  257. package/src/utils/ip.ts +31 -0
  258. package/src/utils/logger.ts +55 -0
  259. package/tsconfig.json +20 -0
package/.env.example ADDED
@@ -0,0 +1,15 @@
1
+ # Platform API
2
+ PLATFORM_API_URL=http://localhost:3000
3
+ PLATFORM_API_KEY=your-api-key-here
4
+
5
+ # VM Configuration
6
+ VM_EXTERNAL_IP=auto # "auto" to detect, or set explicitly
7
+
8
+ # Behavior
9
+ POLL_INTERVAL_MS=3000
10
+ POLL_TIMEOUT_MS=300000
11
+ CLEANUP_WARNING_SECONDS=30
12
+ USE_MOCK_PLATFORM=true # Set to true for local development without platform
13
+
14
+ # State Persistence
15
+ STATE_FILE_PATH=/var/lib/human-agents/state.json
package/README.md ADDED
@@ -0,0 +1,178 @@
1
+ # Bazaar MCP Server
2
+
3
+ The MCP server that lets an AI agent (Claude Code, etc.) **summon a real
4
+ human contractor** when it gets stuck. Posts a gig to the Bazaar
5
+ platform, waits for a contractor to be matched, provisions their
6
+ access, and opens a reverse tunnel so the contractor can connect via
7
+ the web terminal — no ngrok or public IP needed.
8
+
9
+ ---
10
+
11
+ ## Quick Setup (3 steps)
12
+
13
+ ### 1. Sign up & get an API key
14
+
15
+ 1. Create an account on the Bazaar dashboard
16
+ 2. Go to **API Keys** in the sidebar and click **Create Key**
17
+ 3. Copy the key (`bzr_live_...`) — you won't see it again
18
+
19
+ ### 2. Run the setup script
20
+
21
+ ```bash
22
+ npx @bazaar.ai/mcp-human-agents --setup --api-key=bzr_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
23
+ ```
24
+
25
+ The setup script will:
26
+ - Check for prerequisites (sshd, tmux, git) and offer to install them
27
+ - Validate your API key against the platform
28
+ - Configure sudo permissions for contractor provisioning
29
+ - Register the MCP server with Claude Code
30
+
31
+ ### 3. Restart Claude Code
32
+
33
+ Restart Claude Code so the new MCP server is picked up. Verify with:
34
+
35
+ ```bash
36
+ claude mcp list
37
+ # → bazaar npx @bazaar.ai/mcp-human-agents
38
+ ```
39
+
40
+ That's it. Ask Claude to _"summon a human contractor"_ and the platform
41
+ handles matching, provisioning, and connectivity automatically.
42
+
43
+ ---
44
+
45
+ ## How It Works
46
+
47
+ ```
48
+ Developer Machine Bazaar Platform
49
+ ├── Claude Code ├── human-layer API
50
+ │ └── bazaar MCP server │ ├── gig matching
51
+ │ ├── creates local user │ ├── ephemeral SSH keys
52
+ │ ├── configures SSH + tmux │ └── web terminal relay
53
+ │ └── opens reverse tunnel ─────► │
54
+ │ └── Dashboard
55
+ Contractor (anywhere) ├── gig notifications
56
+ └── Browser ─► web terminal ─────────────────┘
57
+ ```
58
+
59
+ 1. Claude Code calls `summon_human` → MCP server creates a gig on the platform
60
+ 2. Platform auto-matches an available contractor
61
+ 3. MCP server provisions a Linux user, SSH key, and tmux session locally
62
+ 4. MCP server opens a **reverse WebSocket tunnel** back to the platform
63
+ 5. Contractor opens the web terminal in the dashboard
64
+ 6. Terminal traffic flows: browser → platform → tunnel → local sshd
65
+ 7. When done, Claude calls `dismiss_human` → cleanup + tunnel close
66
+
67
+ ### MCP Tools
68
+
69
+ | Tool | Description |
70
+ |------|-------------|
71
+ | `summon_human` | Post a gig, match a contractor, provision access |
72
+ | `dismiss_human` | Revoke access, optionally merge changes, report completion |
73
+ | `list_humans` | List active contractors on this machine |
74
+ | `message_human` | Send a message to a contractor's tmux session |
75
+
76
+ ---
77
+
78
+ ## Configuration
79
+
80
+ The setup script handles configuration automatically. For reference,
81
+ these are the environment variables used:
82
+
83
+ | Variable | Default | Description |
84
+ |----------|---------|-------------|
85
+ | `PLATFORM_API_URL` | `http://localhost:3000` | Bazaar platform API endpoint |
86
+ | `PLATFORM_API_KEY` | _(required)_ | Your Bazaar API key |
87
+ | `USE_MOCK_PLATFORM` | `false` | Set `true` for offline testing with mock data |
88
+ | `TUNNEL_ENABLED` | `true` | Reverse tunnel mode (no ngrok needed) |
89
+ | `PROVISIONING_USE_SUDO` | `false` | Use sudo for privileged commands |
90
+ | `VM_EXTERNAL_IP` | `auto` | Only needed when `TUNNEL_ENABLED=false` |
91
+ | `VM_EXTERNAL_SSH_PORT` | `22` | Only needed when `TUNNEL_ENABLED=false` |
92
+ | `PLATFORM_PROJECT_ID` | _(auto)_ | Auto-created on first gig if omitted |
93
+ | `POLL_TIMEOUT_MS` | `300000` | Max wait for contractor matching (5 min) |
94
+ | `STATE_FILE_PATH` | `/var/lib/human-agents/state.json` | Crash recovery state |
95
+
96
+ ---
97
+
98
+ ## Advanced: Manual Setup
99
+
100
+ If you prefer to configure everything manually instead of using the
101
+ setup script:
102
+
103
+ ### 1. Install prerequisites
104
+
105
+ ```bash
106
+ sudo apt-get update
107
+ sudo apt-get install -y openssh-server tmux git curl
108
+ sudo service ssh start
109
+ ```
110
+
111
+ ### 2. Configure sudoers (if not running as root)
112
+
113
+ Replace `<youruser>` with your username (`whoami`):
114
+
115
+ ```bash
116
+ sudo tee /etc/sudoers.d/bazaar-mcp >/dev/null <<'EOF'
117
+ <youruser> ALL=(root) NOPASSWD: /usr/sbin/useradd, /usr/sbin/userdel, /usr/sbin/usermod, /usr/bin/pkill
118
+ <youruser> ALL=(root) NOPASSWD: /usr/sbin/sshd, /bin/systemctl reload sshd, /bin/systemctl reload ssh, /usr/sbin/service ssh reload
119
+ <youruser> ALL=(root) NOPASSWD: /usr/bin/tee, /bin/chmod, /bin/chown, /bin/cp, /bin/mkdir
120
+ <youruser> ALL=(ALL:ALL) NOPASSWD: /usr/bin/tmux
121
+ EOF
122
+ sudo chmod 0440 /etc/sudoers.d/bazaar-mcp
123
+ sudo visudo -c # Must print "parsed OK"
124
+ ```
125
+
126
+ ### 3. Register with Claude Code
127
+
128
+ ```bash
129
+ claude mcp add bazaar \
130
+ -e PLATFORM_API_URL=http://localhost:3000 \
131
+ -e PLATFORM_API_KEY=bzr_live_xxxx \
132
+ -e USE_MOCK_PLATFORM=false \
133
+ -e TUNNEL_ENABLED=true \
134
+ -e PROVISIONING_USE_SUDO=true \
135
+ -- npx @bazaar.ai/mcp-human-agents
136
+ ```
137
+
138
+ ### 4. Legacy direct-SSH mode (no tunnel)
139
+
140
+ If you need contractors to SSH directly (e.g., for debugging), disable
141
+ the tunnel and provide a public endpoint:
142
+
143
+ ```bash
144
+ claude mcp add bazaar \
145
+ -e PLATFORM_API_URL=http://localhost:3000 \
146
+ -e PLATFORM_API_KEY=bzr_live_xxxx \
147
+ -e USE_MOCK_PLATFORM=false \
148
+ -e TUNNEL_ENABLED=false \
149
+ -e VM_EXTERNAL_IP=0.tcp.ngrok.io \
150
+ -e VM_EXTERNAL_SSH_PORT=17832 \
151
+ -e PROVISIONING_USE_SUDO=true \
152
+ -- npx @bazaar.ai/mcp-human-agents
153
+ ```
154
+
155
+ ---
156
+
157
+ ## Troubleshooting
158
+
159
+ **`sudo: a password is required`**
160
+ The sudoers file isn't being read. Run `sudo visudo -c` and check that
161
+ `/etc/sudoers.d/bazaar-mcp` exists and has mode `0440`.
162
+
163
+ **`tmux: server failed to start`**
164
+ The contractor user's home directory may not exist. The MCP server runs
165
+ `useradd -m` which creates it. If you're seeing this, something is
166
+ wrong with your distro's `useradd` defaults.
167
+
168
+ **Polling times out**
169
+ No contractor is available, or the matching service isn't running.
170
+ Check the platform logs for `autoMatch` messages.
171
+
172
+ **Tunnel WebSocket keeps reconnecting**
173
+ Check that the platform API is reachable from your machine. The tunnel
174
+ client auto-reconnects with backoff on connection drops.
175
+
176
+ **`useradd: user '<name>' already exists`**
177
+ Leftover from a previous gig. Run `sudo userdel -r <name>` manually,
178
+ or call `dismiss_human` to clean up properly.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../../../src/bin.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ if (process.argv.includes("--setup")) {
5
+ import("./cli/setup.js").then((m) => m.runSetup());
6
+ }
7
+ else {
8
+ import("./index.js");
9
+ }
10
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../../../src/bin.ts"],"names":[],"mappings":";;;AAEA,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;IACrC,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;AACrD,CAAC;KAAM,CAAC;IACN,MAAM,CAAC,YAAY,CAAC,CAAC;AACvB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function runSetup(): Promise<void>;
2
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../../src/cli/setup.ts"],"names":[],"mappings":"AAyNA,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAmG9C"}
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runSetup = runSetup;
4
+ const promises_1 = require("node:readline/promises");
5
+ const node_child_process_1 = require("node:child_process");
6
+ const node_process_1 = require("node:process");
7
+ // TEMPORARY: ngrok tunnel for early testing. Replace with production URL
8
+ // (e.g. https://api.bazaar.ai) before public launch.
9
+ const PLATFORM_API_URL_DEFAULT = "https://ingrid-hypocycloidal-kaliyah.ngrok-free.dev";
10
+ // ── Helpers ──────────────────────────────────────────────────────────
11
+ function log(msg) {
12
+ node_process_1.stderr.write(`${msg}\n`);
13
+ }
14
+ function success(msg) {
15
+ node_process_1.stderr.write(`\x1b[32m✓\x1b[0m ${msg}\n`);
16
+ }
17
+ function warn(msg) {
18
+ node_process_1.stderr.write(`\x1b[33m!\x1b[0m ${msg}\n`);
19
+ }
20
+ function fail(msg) {
21
+ node_process_1.stderr.write(`\x1b[31m✗\x1b[0m ${msg}\n`);
22
+ }
23
+ function run(cmd, opts) {
24
+ const result = (0, node_child_process_1.execSync)(cmd, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], ...opts });
25
+ return String(result).trim();
26
+ }
27
+ function canRun(cmd) {
28
+ try {
29
+ run(cmd);
30
+ return true;
31
+ }
32
+ catch {
33
+ return false;
34
+ }
35
+ }
36
+ // ── Setup Steps ──────────────────────────────────────────────────────
37
+ async function checkClaude() {
38
+ if (canRun("claude --version")) {
39
+ success("Claude Code CLI found");
40
+ return true;
41
+ }
42
+ fail("Claude Code CLI not found. Install it first: https://docs.anthropic.com/en/docs/claude-code");
43
+ return false;
44
+ }
45
+ function checkPrereqs() {
46
+ const required = [
47
+ { cmd: "sshd -v 2>&1 || true", name: "openssh-server" },
48
+ { cmd: "which tmux", name: "tmux" },
49
+ { cmd: "which git", name: "git" },
50
+ ];
51
+ const missing = [];
52
+ for (const { cmd, name } of required) {
53
+ if (canRun(cmd)) {
54
+ success(`${name} found`);
55
+ }
56
+ else {
57
+ warn(`${name} not found`);
58
+ missing.push(name);
59
+ }
60
+ }
61
+ return { missing };
62
+ }
63
+ async function promptApiKey(rl) {
64
+ // Check CLI args first
65
+ const keyArg = process.argv.find((a) => a.startsWith("--api-key="));
66
+ if (keyArg) {
67
+ const key = keyArg.split("=")[1];
68
+ if (key && key.startsWith("bzr_live_")) {
69
+ return key;
70
+ }
71
+ }
72
+ log("");
73
+ log("You need a Bazaar API key. Get one from the dashboard:");
74
+ log(" → Go to API Keys in the sidebar, then click Create Key");
75
+ log("");
76
+ while (true) {
77
+ const key = await rl.question("Paste your API key (bzr_live_...): ");
78
+ const trimmed = key.trim();
79
+ if (trimmed.startsWith("bzr_live_") && trimmed.length > 20) {
80
+ return trimmed;
81
+ }
82
+ warn("API key should start with 'bzr_live_' — try again");
83
+ }
84
+ }
85
+ async function promptPlatformUrl(rl) {
86
+ // Check CLI args
87
+ const urlArg = process.argv.find((a) => a.startsWith("--platform-url="));
88
+ if (urlArg) {
89
+ return urlArg.split("=").slice(1).join("=");
90
+ }
91
+ log("");
92
+ const url = await rl.question(`Platform API URL [${PLATFORM_API_URL_DEFAULT}]: `);
93
+ return url.trim() || PLATFORM_API_URL_DEFAULT;
94
+ }
95
+ async function validateApiKey(apiKey, platformUrl) {
96
+ try {
97
+ const res = await fetch(`${platformUrl}/api/users/me`, {
98
+ headers: { Authorization: `Bearer ${apiKey}` },
99
+ });
100
+ if (res.ok) {
101
+ const data = (await res.json());
102
+ success(`Authenticated as ${data.email || data.name || "user"}`);
103
+ return true;
104
+ }
105
+ fail(`API key validation failed: ${res.status}`);
106
+ return false;
107
+ }
108
+ catch (err) {
109
+ fail(`Cannot reach platform at ${platformUrl}: ${err}`);
110
+ return false;
111
+ }
112
+ }
113
+ async function configureSudoers(rl) {
114
+ const user = run("whoami");
115
+ if (user === "root") {
116
+ success("Running as root — no sudoers configuration needed");
117
+ return;
118
+ }
119
+ log("");
120
+ log("The MCP server needs sudo access for contractor provisioning");
121
+ log("(user creation, SSH config, tmux). This writes a NOPASSWD sudoers");
122
+ log(`rule scoped to specific commands for user '${user}'.`);
123
+ log("");
124
+ const answer = await rl.question("Configure sudoers now? [Y/n]: ");
125
+ if (answer.trim().toLowerCase() === "n") {
126
+ warn("Skipped sudoers — you'll need to configure this manually or run as root");
127
+ return;
128
+ }
129
+ const sudoersContent = `# Bazaar MCP server — contractor provisioning
130
+ ${user} ALL=(root) NOPASSWD: /usr/sbin/useradd, /usr/sbin/userdel, /usr/sbin/usermod, /usr/bin/pkill
131
+ ${user} ALL=(root) NOPASSWD: /usr/sbin/sshd, /bin/systemctl reload sshd, /bin/systemctl reload ssh, /usr/sbin/service ssh reload
132
+ ${user} ALL=(root) NOPASSWD: /usr/bin/tee, /bin/chmod, /bin/chown, /bin/cp, /bin/mkdir
133
+ ${user} ALL=(ALL:ALL) NOPASSWD: /usr/bin/tmux
134
+ `;
135
+ try {
136
+ (0, node_child_process_1.execSync)(`echo '${sudoersContent.replace(/'/g, "'\\''")}' | sudo tee /etc/sudoers.d/bazaar-mcp > /dev/null && sudo chmod 0440 /etc/sudoers.d/bazaar-mcp`, { stdio: "pipe" });
137
+ // Validate
138
+ run("sudo visudo -c");
139
+ success("Sudoers rule installed at /etc/sudoers.d/bazaar-mcp");
140
+ }
141
+ catch (err) {
142
+ warn(`Failed to configure sudoers: ${err}`);
143
+ warn("You may need to run this manually — see the README");
144
+ }
145
+ }
146
+ function createStateDir() {
147
+ try {
148
+ run("sudo mkdir -p /var/lib/human-agents && sudo chmod 777 /var/lib/human-agents");
149
+ success("State directory created at /var/lib/human-agents");
150
+ }
151
+ catch {
152
+ warn("Could not create /var/lib/human-agents — state will use fallback");
153
+ }
154
+ }
155
+ function registerMcpServer(apiKey, platformUrl) {
156
+ const isRoot = run("whoami") === "root";
157
+ // Build the env vars for claude mcp add
158
+ const envFlags = [
159
+ `-e PLATFORM_API_URL=${platformUrl}`,
160
+ `-e PLATFORM_API_KEY=${apiKey}`,
161
+ `-e USE_MOCK_PLATFORM=false`,
162
+ `-e TUNNEL_ENABLED=true`,
163
+ isRoot ? "" : `-e PROVISIONING_USE_SUDO=true`,
164
+ ]
165
+ .filter(Boolean)
166
+ .join(" ");
167
+ // Use npx to run the package (works whether installed locally or globally)
168
+ const cmd = `claude mcp add bazaar ${envFlags} -- npx -y @bazaar.ai/mcp-human-agents`;
169
+ try {
170
+ run(cmd, { stdio: "pipe" });
171
+ success("MCP server registered with Claude Code");
172
+ return true;
173
+ }
174
+ catch (err) {
175
+ // If `claude mcp add` isn't available, show the manual command
176
+ warn("Could not auto-register. Run this manually:");
177
+ log("");
178
+ log(` ${cmd}`);
179
+ log("");
180
+ return false;
181
+ }
182
+ }
183
+ // ── Main ─────────────────────────────────────────────────────────────
184
+ async function runSetup() {
185
+ const rl = (0, promises_1.createInterface)({ input: node_process_1.stdin, output: node_process_1.stderr });
186
+ try {
187
+ log("");
188
+ log("╔══════════════════════════════════════════╗");
189
+ log("║ Bazaar MCP Server Setup ║");
190
+ log("╚══════════════════════════════════════════╝");
191
+ log("");
192
+ // 1. Check Claude CLI
193
+ const hasClaude = await checkClaude();
194
+ // 2. Check system prereqs
195
+ log("");
196
+ log("Checking system prerequisites...");
197
+ const { missing } = checkPrereqs();
198
+ if (missing.length > 0) {
199
+ log("");
200
+ const answer = await rl.question(`Install missing packages (${missing.join(", ")})? [Y/n]: `);
201
+ if (answer.trim().toLowerCase() !== "n") {
202
+ try {
203
+ run(`sudo apt-get update -qq && sudo apt-get install -y ${missing.join(" ")}`, {
204
+ stdio: "inherit",
205
+ });
206
+ success("Packages installed");
207
+ }
208
+ catch {
209
+ warn("Failed to install packages — please install manually");
210
+ }
211
+ }
212
+ }
213
+ // 3. Get API key
214
+ const apiKey = await promptApiKey(rl);
215
+ // 4. Get platform URL
216
+ const platformUrl = await promptPlatformUrl(rl);
217
+ // 5. Validate API key
218
+ log("");
219
+ log("Validating API key...");
220
+ const valid = await validateApiKey(apiKey, platformUrl);
221
+ if (!valid) {
222
+ warn("Continuing anyway — you can fix the API key later");
223
+ }
224
+ // 6. Configure sudoers
225
+ await configureSudoers(rl);
226
+ // 7. Create state directory
227
+ createStateDir();
228
+ // 8. Start sshd if not running
229
+ try {
230
+ run("pgrep sshd > /dev/null || sudo service ssh start");
231
+ success("sshd is running");
232
+ }
233
+ catch {
234
+ warn("Could not start sshd — contractor SSH access may not work");
235
+ }
236
+ // 9. Register MCP server
237
+ log("");
238
+ log("Registering MCP server with Claude Code...");
239
+ if (hasClaude) {
240
+ registerMcpServer(apiKey, platformUrl);
241
+ }
242
+ else {
243
+ warn("Claude CLI not found — showing manual command:");
244
+ log("");
245
+ const isRoot = run("whoami") === "root";
246
+ const envFlags = [
247
+ `-e PLATFORM_API_URL=${platformUrl}`,
248
+ `-e PLATFORM_API_KEY=${apiKey}`,
249
+ `-e USE_MOCK_PLATFORM=false`,
250
+ `-e TUNNEL_ENABLED=true`,
251
+ isRoot ? "" : `-e PROVISIONING_USE_SUDO=true`,
252
+ ]
253
+ .filter(Boolean)
254
+ .join(" ");
255
+ log(` claude mcp add bazaar ${envFlags} -- npx -y @bazaar.ai/mcp-human-agents`);
256
+ log("");
257
+ }
258
+ // Done
259
+ log("");
260
+ log("╔══════════════════════════════════════════╗");
261
+ log("║ Setup Complete! ║");
262
+ log("╚══════════════════════════════════════════╝");
263
+ log("");
264
+ log("Next steps:");
265
+ log(" 1. Restart Claude Code to load the new MCP server");
266
+ log(' 2. Ask Claude to "summon a human contractor"');
267
+ log(" 3. The contractor connects via the web terminal on the dashboard");
268
+ log("");
269
+ }
270
+ finally {
271
+ rl.close();
272
+ }
273
+ }
274
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../../src/cli/setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /** Default timeout for shell commands (ms). */
2
+ export declare const EXEC_TIMEOUT_MS = 30000;
3
+ /** How often to poll the platform for contractor assignment (ms). */
4
+ export declare const DEFAULT_POLL_INTERVAL_MS = 3000;
5
+ /** Max time to wait for a contractor to be assigned (ms). */
6
+ export declare const DEFAULT_POLL_TIMEOUT_MS = 300000;
7
+ /** Seconds to warn a contractor before killing their tmux session. */
8
+ export declare const DEFAULT_CLEANUP_WARNING_SECONDS = 30;
9
+ /** Marker comments for sshd_config blocks managed by human-layer. */
10
+ export declare const SSHD_MARKER_PREFIX = "# BEGIN human-layer:";
11
+ export declare const SSHD_MARKER_SUFFIX = "# END human-layer:";
12
+ /** Path to sshd_config. */
13
+ export declare const SSHD_CONFIG_PATH = "/etc/ssh/sshd_config";
14
+ /** tmux session name prefix. */
15
+ export declare const TMUX_SESSION_PREFIX = "hl-";
16
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../../../src/config/defaults.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,eAAO,MAAM,eAAe,QAAS,CAAC;AAEtC,qEAAqE;AACrE,eAAO,MAAM,wBAAwB,OAAQ,CAAC;AAE9C,6DAA6D;AAC7D,eAAO,MAAM,uBAAuB,SAAU,CAAC;AAE/C,sEAAsE;AACtE,eAAO,MAAM,+BAA+B,KAAK,CAAC;AAElD,qEAAqE;AACrE,eAAO,MAAM,kBAAkB,yBAAyB,CAAC;AACzD,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD,2BAA2B;AAC3B,eAAO,MAAM,gBAAgB,yBAAyB,CAAC;AAEvD,gCAAgC;AAChC,eAAO,MAAM,mBAAmB,QAAQ,CAAC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TMUX_SESSION_PREFIX = exports.SSHD_CONFIG_PATH = exports.SSHD_MARKER_SUFFIX = exports.SSHD_MARKER_PREFIX = exports.DEFAULT_CLEANUP_WARNING_SECONDS = exports.DEFAULT_POLL_TIMEOUT_MS = exports.DEFAULT_POLL_INTERVAL_MS = exports.EXEC_TIMEOUT_MS = void 0;
4
+ /** Default timeout for shell commands (ms). */
5
+ exports.EXEC_TIMEOUT_MS = 30_000;
6
+ /** How often to poll the platform for contractor assignment (ms). */
7
+ exports.DEFAULT_POLL_INTERVAL_MS = 3_000;
8
+ /** Max time to wait for a contractor to be assigned (ms). */
9
+ exports.DEFAULT_POLL_TIMEOUT_MS = 300_000;
10
+ /** Seconds to warn a contractor before killing their tmux session. */
11
+ exports.DEFAULT_CLEANUP_WARNING_SECONDS = 30;
12
+ /** Marker comments for sshd_config blocks managed by human-layer. */
13
+ exports.SSHD_MARKER_PREFIX = "# BEGIN human-layer:";
14
+ exports.SSHD_MARKER_SUFFIX = "# END human-layer:";
15
+ /** Path to sshd_config. */
16
+ exports.SSHD_CONFIG_PATH = "/etc/ssh/sshd_config";
17
+ /** tmux session name prefix. */
18
+ exports.TMUX_SESSION_PREFIX = "hl-";
19
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../../../src/config/defaults.ts"],"names":[],"mappings":";;;AAAA,+CAA+C;AAClC,QAAA,eAAe,GAAG,MAAM,CAAC;AAEtC,qEAAqE;AACxD,QAAA,wBAAwB,GAAG,KAAK,CAAC;AAE9C,6DAA6D;AAChD,QAAA,uBAAuB,GAAG,OAAO,CAAC;AAE/C,sEAAsE;AACzD,QAAA,+BAA+B,GAAG,EAAE,CAAC;AAElD,qEAAqE;AACxD,QAAA,kBAAkB,GAAG,sBAAsB,CAAC;AAC5C,QAAA,kBAAkB,GAAG,oBAAoB,CAAC;AAEvD,2BAA2B;AACd,QAAA,gBAAgB,GAAG,sBAAsB,CAAC;AAEvD,gCAAgC;AACnB,QAAA,mBAAmB,GAAG,KAAK,CAAC"}
@@ -0,0 +1,73 @@
1
+ import { z } from "zod";
2
+ declare const EnvSchema: z.ZodObject<{
3
+ PLATFORM_API_URL: z.ZodDefault<z.ZodString>;
4
+ PLATFORM_API_KEY: z.ZodDefault<z.ZodString>;
5
+ /**
6
+ * Hostname or IP the contractor will SSH into. Only needed when
7
+ * TUNNEL_ENABLED=false (legacy direct-SSH mode). When the dev box is
8
+ * exposed via `ngrok tcp`, set this to the ngrok host (e.g.
9
+ * `0.tcp.ngrok.io`). Default `"auto"` triggers cloud metadata + local
10
+ * network detection.
11
+ */
12
+ VM_EXTERNAL_IP: z.ZodDefault<z.ZodString>;
13
+ /**
14
+ * Public SSH port. Only needed when TUNNEL_ENABLED=false.
15
+ */
16
+ VM_EXTERNAL_SSH_PORT: z.ZodDefault<z.ZodNumber>;
17
+ /**
18
+ * Optional explicit project ID to attach gigs to. If unset, the API
19
+ * will auto-create a default project for the user behind the API key.
20
+ */
21
+ PLATFORM_PROJECT_ID: z.ZodOptional<z.ZodString>;
22
+ POLL_INTERVAL_MS: z.ZodDefault<z.ZodNumber>;
23
+ POLL_TIMEOUT_MS: z.ZodDefault<z.ZodNumber>;
24
+ CLEANUP_WARNING_SECONDS: z.ZodDefault<z.ZodNumber>;
25
+ USE_MOCK_PLATFORM: z.ZodDefault<z.ZodEffects<z.ZodString, boolean, string>>;
26
+ STATE_FILE_PATH: z.ZodDefault<z.ZodString>;
27
+ /**
28
+ * When true, the provisioning code prepends `sudo -n` to privileged
29
+ * commands. Set this to `true` when the MCP server is NOT running as
30
+ * root and instead has NOPASSWD sudo for the relevant commands.
31
+ * See `human-layer/mcp-server/README.md` for the sudoers template.
32
+ */
33
+ PROVISIONING_USE_SUDO: z.ZodDefault<z.ZodEffects<z.ZodString, boolean, string>>;
34
+ /**
35
+ * When true, the MCP server opens a reverse WebSocket tunnel to the
36
+ * platform so contractors can connect without ngrok or public IPs.
37
+ * When false, falls back to legacy direct-SSH mode using
38
+ * VM_EXTERNAL_IP / VM_EXTERNAL_SSH_PORT.
39
+ */
40
+ TUNNEL_ENABLED: z.ZodDefault<z.ZodEffects<z.ZodString, boolean, string>>;
41
+ }, "strip", z.ZodTypeAny, {
42
+ PLATFORM_API_URL: string;
43
+ PLATFORM_API_KEY: string;
44
+ VM_EXTERNAL_IP: string;
45
+ VM_EXTERNAL_SSH_PORT: number;
46
+ POLL_INTERVAL_MS: number;
47
+ POLL_TIMEOUT_MS: number;
48
+ CLEANUP_WARNING_SECONDS: number;
49
+ USE_MOCK_PLATFORM: boolean;
50
+ STATE_FILE_PATH: string;
51
+ PROVISIONING_USE_SUDO: boolean;
52
+ TUNNEL_ENABLED: boolean;
53
+ PLATFORM_PROJECT_ID?: string | undefined;
54
+ }, {
55
+ PLATFORM_API_URL?: string | undefined;
56
+ PLATFORM_API_KEY?: string | undefined;
57
+ VM_EXTERNAL_IP?: string | undefined;
58
+ VM_EXTERNAL_SSH_PORT?: number | undefined;
59
+ PLATFORM_PROJECT_ID?: string | undefined;
60
+ POLL_INTERVAL_MS?: number | undefined;
61
+ POLL_TIMEOUT_MS?: number | undefined;
62
+ CLEANUP_WARNING_SECONDS?: number | undefined;
63
+ USE_MOCK_PLATFORM?: string | undefined;
64
+ STATE_FILE_PATH?: string | undefined;
65
+ PROVISIONING_USE_SUDO?: string | undefined;
66
+ TUNNEL_ENABLED?: string | undefined;
67
+ }>;
68
+ export type Env = z.infer<typeof EnvSchema>;
69
+ export declare function getEnv(): Env;
70
+ /** For testing: override the cached env. */
71
+ export declare function setEnv(env: Env): void;
72
+ export {};
73
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../../src/config/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,QAAA,MAAM,SAAS;;;IAGb;;;;;;OAMG;;IAEH;;OAEG;;IAEH;;;OAGG;;;;;;;IAYH;;;;;OAKG;;IAKH;;;;;OAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKH,CAAC;AAEH,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAI5C,wBAAgB,MAAM,IAAI,GAAG,CAK5B;AAED,4CAA4C;AAC5C,wBAAgB,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAErC"}