@terreno/mcp 57.19.2 → 57.20.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 (197) hide show
  1. package/CHANGELOG.md +393 -0
  2. package/README.md +32 -269
  3. package/dist/bootstrap.d.ts +12 -0
  4. package/dist/bootstrap.d.ts.map +1 -1
  5. package/dist/bootstrap.js +77 -122
  6. package/dist/bootstrap.js.map +1 -1
  7. package/dist/docs/guidelines/ui/guidelines/core.md +1 -1
  8. package/dist/docs/resources/overview.md +4 -2
  9. package/dist/docs/resources/patterns.md +237 -176
  10. package/dist/docs/resources/ui.md +48 -17
  11. package/dist/docs/templates/bootstrap/frontend/app/(tabs)/profile.template.tsx +0 -26
  12. package/dist/docs/templates/bootstrap/frontend/app/_layout.template.tsx +3 -2
  13. package/dist/docs/templates/bootstrap/frontend/app/login.template.tsx +1 -1
  14. package/dist/docs/upgrades/57.20.0.md +238 -0
  15. package/dist/docs/versioned/next/approval-rubric.md +30 -12
  16. package/dist/docs/versioned/next/explanation/README.md +5 -0
  17. package/dist/docs/versioned/next/explanation/account-linking.md +169 -0
  18. package/dist/docs/versioned/next/explanation/admin-interface.md +1 -1
  19. package/dist/docs/versioned/next/explanation/agent-guidelines.md +173 -0
  20. package/dist/docs/versioned/next/explanation/ai-development-loop.md +196 -0
  21. package/dist/docs/versioned/next/explanation/authentication.md +45 -1
  22. package/dist/docs/versioned/next/explanation/consent-forms.md +105 -0
  23. package/dist/docs/versioned/next/explanation/example-coverage.md +1 -0
  24. package/dist/docs/versioned/next/explanation/local-first-data.md +1 -1
  25. package/dist/docs/versioned/next/explanation/organizations.md +37 -0
  26. package/dist/docs/versioned/next/explanation/planning-plugins.md +4 -0
  27. package/dist/docs/versioned/next/explanation/responsive-design.md +143 -0
  28. package/dist/docs/versioned/next/explanation/roadmap-seed-issues.md +11 -0
  29. package/dist/docs/versioned/next/explanation/schema-metadata.md +5 -0
  30. package/dist/docs/versioned/next/how-to/README.md +7 -2
  31. package/dist/docs/versioned/next/how-to/audit-log.md +22 -3
  32. package/dist/docs/versioned/next/how-to/automate-terreno-upgrades.md +169 -0
  33. package/dist/docs/versioned/next/how-to/build-list-detail-screens.md +160 -0
  34. package/dist/docs/versioned/next/how-to/circleci.md +15 -5
  35. package/dist/docs/versioned/next/how-to/configure-better-auth.md +673 -53
  36. package/dist/docs/versioned/next/how-to/create-a-terreno-app.md +8 -5
  37. package/dist/docs/versioned/next/how-to/debug-with-mcp.md +393 -23
  38. package/dist/docs/versioned/next/how-to/enable-mcp-oauth.md +54 -3
  39. package/dist/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +9 -0
  40. package/dist/docs/versioned/next/how-to/password-reset.md +1 -1
  41. package/dist/docs/versioned/next/how-to/recover-locked-out-user.md +112 -0
  42. package/dist/docs/versioned/next/how-to/run-tests-locally.md +37 -8
  43. package/dist/docs/versioned/next/how-to/set-up-social-login.md +424 -0
  44. package/dist/docs/versioned/next/how-to/set-up-terreno-mcp.md +241 -36
  45. package/dist/docs/versioned/next/how-to/sign-consent-on-behalf.md +139 -0
  46. package/dist/docs/versioned/next/how-to/upgrade-terreno.md +4 -0
  47. package/dist/docs/versioned/next/implementationPlans/ai-dev-loop-boost.md +47 -32
  48. package/dist/docs/versioned/next/implementationPlans/auth-experience.md +952 -0
  49. package/dist/docs/versioned/next/implementationPlans/consent-forms.md +8 -0
  50. package/dist/docs/versioned/next/implementationPlans/list-detail-layout.md +297 -0
  51. package/dist/docs/versioned/next/implementationPlans/login-redesign/HANDOFF.md +211 -0
  52. package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/AnotherWay.html +121 -0
  53. package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/BackupCode.html +72 -0
  54. package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/Cancelled.html +87 -0
  55. package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/ContinueEmail.html +64 -0
  56. package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/FirstVisit.html +81 -0
  57. package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/Main.html +88 -0
  58. package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/ManageAccounts.html +77 -0
  59. package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/NotLinked.html +92 -0
  60. package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/SigningIn.html +60 -0
  61. package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/TwoFactor.html +76 -0
  62. package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/TwoFactorError.html +81 -0
  63. package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/WrongPassword.html +69 -0
  64. package/dist/docs/versioned/next/implementationPlans/mcp-boost-parity.md +1 -1
  65. package/dist/docs/versioned/next/plans/2026-10-23-provisional-consent.md +297 -0
  66. package/dist/docs/versioned/next/plans/2026-10-29-fix-mcp-oauth-native-and-machine.md +68 -0
  67. package/dist/docs/versioned/next/reference/README.md +1 -0
  68. package/dist/docs/versioned/next/reference/account-security.md +700 -0
  69. package/dist/docs/versioned/next/reference/admin-backend.md +3 -1
  70. package/dist/docs/versioned/next/reference/admin-frontend.md +225 -1
  71. package/dist/docs/versioned/next/reference/api.md +461 -35
  72. package/dist/docs/versioned/next/reference/cli.md +1 -1
  73. package/dist/docs/versioned/next/reference/comms.md +8 -0
  74. package/dist/docs/versioned/next/reference/create-terreno-app.md +3 -1
  75. package/dist/docs/versioned/next/reference/environment-variables.md +9 -3
  76. package/dist/docs/versioned/next/reference/legacy/rtk.md +19 -3
  77. package/dist/docs/versioned/next/reference/lifecycle-plugin.md +6 -0
  78. package/dist/docs/versioned/next/reference/mcp-server.md +1158 -441
  79. package/dist/docs/versioned/next/reference/syncdb.md +8 -1
  80. package/dist/docs/versioned/next/reference/ui.md +1271 -27
  81. package/dist/docs/versioned/next/tasks/ai-dev-loop-boost.md +28 -16
  82. package/dist/docs/versioned/next/tutorials/README.md +4 -0
  83. package/dist/httpApp.d.ts +14 -0
  84. package/dist/httpApp.d.ts.map +1 -0
  85. package/dist/httpApp.js +99 -0
  86. package/dist/httpApp.js.map +1 -0
  87. package/dist/index.js +8 -90
  88. package/dist/index.js.map +1 -1
  89. package/dist/local/localTools.d.ts.map +1 -1
  90. package/dist/local/localTools.js +44 -14
  91. package/dist/local/localTools.js.map +1 -1
  92. package/dist/local/metro/metroDevSession.d.ts +18 -0
  93. package/dist/local/metro/metroDevSession.d.ts.map +1 -1
  94. package/dist/local/metro/metroDevSession.js +42 -3
  95. package/dist/local/metro/metroDevSession.js.map +1 -1
  96. package/dist/local/tools/databaseQuery.d.ts.map +1 -1
  97. package/dist/local/tools/databaseQuery.js +3 -13
  98. package/dist/local/tools/databaseQuery.js.map +1 -1
  99. package/dist/local/tools/databaseSchema.d.ts.map +1 -1
  100. package/dist/local/tools/databaseSchema.js +3 -13
  101. package/dist/local/tools/databaseSchema.js.map +1 -1
  102. package/dist/local/tools/localMongo.d.ts +10 -0
  103. package/dist/local/tools/localMongo.d.ts.map +1 -0
  104. package/dist/local/tools/localMongo.js +30 -0
  105. package/dist/local/tools/localMongo.js.map +1 -0
  106. package/dist/local/tools/runtime.d.ts +18 -2
  107. package/dist/local/tools/runtime.d.ts.map +1 -1
  108. package/dist/local/tools/runtime.js +75 -20
  109. package/dist/local/tools/runtime.js.map +1 -1
  110. package/dist/local/tools/syncDb.d.ts +11 -0
  111. package/dist/local/tools/syncDb.d.ts.map +1 -1
  112. package/dist/local/tools/syncDb.js +15 -3
  113. package/dist/local/tools/syncDb.js.map +1 -1
  114. package/dist/rateLimit.d.ts +35 -0
  115. package/dist/rateLimit.d.ts.map +1 -0
  116. package/dist/rateLimit.js +112 -0
  117. package/dist/rateLimit.js.map +1 -0
  118. package/dist/tools.d.ts.map +1 -1
  119. package/dist/tools.js +42 -60
  120. package/dist/tools.js.map +1 -1
  121. package/package.json +4 -3
  122. package/src/docs/guidelines/ui/guidelines/core.md +1 -1
  123. package/src/docs/resources/overview.md +4 -2
  124. package/src/docs/resources/patterns.md +237 -176
  125. package/src/docs/resources/ui.md +48 -17
  126. package/src/docs/templates/bootstrap/frontend/app/(tabs)/profile.template.tsx +0 -26
  127. package/src/docs/templates/bootstrap/frontend/app/_layout.template.tsx +3 -2
  128. package/src/docs/templates/bootstrap/frontend/app/login.template.tsx +1 -1
  129. package/src/docs/upgrades/57.20.0.md +238 -0
  130. package/src/docs/versioned/next/approval-rubric.md +30 -12
  131. package/src/docs/versioned/next/explanation/README.md +5 -0
  132. package/src/docs/versioned/next/explanation/account-linking.md +169 -0
  133. package/src/docs/versioned/next/explanation/admin-interface.md +1 -1
  134. package/src/docs/versioned/next/explanation/agent-guidelines.md +173 -0
  135. package/src/docs/versioned/next/explanation/ai-development-loop.md +196 -0
  136. package/src/docs/versioned/next/explanation/authentication.md +45 -1
  137. package/src/docs/versioned/next/explanation/consent-forms.md +105 -0
  138. package/src/docs/versioned/next/explanation/example-coverage.md +1 -0
  139. package/src/docs/versioned/next/explanation/local-first-data.md +1 -1
  140. package/src/docs/versioned/next/explanation/organizations.md +37 -0
  141. package/src/docs/versioned/next/explanation/planning-plugins.md +4 -0
  142. package/src/docs/versioned/next/explanation/responsive-design.md +143 -0
  143. package/src/docs/versioned/next/explanation/roadmap-seed-issues.md +11 -0
  144. package/src/docs/versioned/next/explanation/schema-metadata.md +5 -0
  145. package/src/docs/versioned/next/how-to/README.md +7 -2
  146. package/src/docs/versioned/next/how-to/audit-log.md +22 -3
  147. package/src/docs/versioned/next/how-to/automate-terreno-upgrades.md +169 -0
  148. package/src/docs/versioned/next/how-to/build-list-detail-screens.md +160 -0
  149. package/src/docs/versioned/next/how-to/circleci.md +15 -5
  150. package/src/docs/versioned/next/how-to/configure-better-auth.md +673 -53
  151. package/src/docs/versioned/next/how-to/create-a-terreno-app.md +8 -5
  152. package/src/docs/versioned/next/how-to/debug-with-mcp.md +393 -23
  153. package/src/docs/versioned/next/how-to/enable-mcp-oauth.md +54 -3
  154. package/src/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +9 -0
  155. package/src/docs/versioned/next/how-to/password-reset.md +1 -1
  156. package/src/docs/versioned/next/how-to/recover-locked-out-user.md +112 -0
  157. package/src/docs/versioned/next/how-to/run-tests-locally.md +37 -8
  158. package/src/docs/versioned/next/how-to/set-up-social-login.md +424 -0
  159. package/src/docs/versioned/next/how-to/set-up-terreno-mcp.md +241 -36
  160. package/src/docs/versioned/next/how-to/sign-consent-on-behalf.md +139 -0
  161. package/src/docs/versioned/next/how-to/upgrade-terreno.md +4 -0
  162. package/src/docs/versioned/next/implementationPlans/ai-dev-loop-boost.md +47 -32
  163. package/src/docs/versioned/next/implementationPlans/auth-experience.md +952 -0
  164. package/src/docs/versioned/next/implementationPlans/consent-forms.md +8 -0
  165. package/src/docs/versioned/next/implementationPlans/list-detail-layout.md +297 -0
  166. package/src/docs/versioned/next/implementationPlans/login-redesign/HANDOFF.md +211 -0
  167. package/src/docs/versioned/next/implementationPlans/login-redesign/boards/AnotherWay.html +121 -0
  168. package/src/docs/versioned/next/implementationPlans/login-redesign/boards/BackupCode.html +72 -0
  169. package/src/docs/versioned/next/implementationPlans/login-redesign/boards/Cancelled.html +87 -0
  170. package/src/docs/versioned/next/implementationPlans/login-redesign/boards/ContinueEmail.html +64 -0
  171. package/src/docs/versioned/next/implementationPlans/login-redesign/boards/FirstVisit.html +81 -0
  172. package/src/docs/versioned/next/implementationPlans/login-redesign/boards/Main.html +88 -0
  173. package/src/docs/versioned/next/implementationPlans/login-redesign/boards/ManageAccounts.html +77 -0
  174. package/src/docs/versioned/next/implementationPlans/login-redesign/boards/NotLinked.html +92 -0
  175. package/src/docs/versioned/next/implementationPlans/login-redesign/boards/SigningIn.html +60 -0
  176. package/src/docs/versioned/next/implementationPlans/login-redesign/boards/TwoFactor.html +76 -0
  177. package/src/docs/versioned/next/implementationPlans/login-redesign/boards/TwoFactorError.html +81 -0
  178. package/src/docs/versioned/next/implementationPlans/login-redesign/boards/WrongPassword.html +69 -0
  179. package/src/docs/versioned/next/implementationPlans/mcp-boost-parity.md +1 -1
  180. package/src/docs/versioned/next/plans/2026-10-23-provisional-consent.md +297 -0
  181. package/src/docs/versioned/next/plans/2026-10-29-fix-mcp-oauth-native-and-machine.md +68 -0
  182. package/src/docs/versioned/next/reference/README.md +1 -0
  183. package/src/docs/versioned/next/reference/account-security.md +700 -0
  184. package/src/docs/versioned/next/reference/admin-backend.md +3 -1
  185. package/src/docs/versioned/next/reference/admin-frontend.md +225 -1
  186. package/src/docs/versioned/next/reference/api.md +461 -35
  187. package/src/docs/versioned/next/reference/cli.md +1 -1
  188. package/src/docs/versioned/next/reference/comms.md +8 -0
  189. package/src/docs/versioned/next/reference/create-terreno-app.md +3 -1
  190. package/src/docs/versioned/next/reference/environment-variables.md +9 -3
  191. package/src/docs/versioned/next/reference/legacy/rtk.md +19 -3
  192. package/src/docs/versioned/next/reference/lifecycle-plugin.md +6 -0
  193. package/src/docs/versioned/next/reference/mcp-server.md +1158 -441
  194. package/src/docs/versioned/next/reference/syncdb.md +8 -1
  195. package/src/docs/versioned/next/reference/ui.md +1271 -27
  196. package/src/docs/versioned/next/tasks/ai-dev-loop-boost.md +28 -16
  197. package/src/docs/versioned/next/tutorials/README.md +4 -0
@@ -1,65 +1,264 @@
1
1
  # Set up Terreno MCP
2
2
 
3
- Configure both Terreno servers: the hosted server supplies documentation and generators; the local
4
- stdio server inspects the app, database, logs, Metro, and Redux state.
3
+ Connect your editor to both Terreno MCP servers:
5
4
 
6
- Install Bun 1.4 or newer to enable the local server's built-in WebView browser automation.
5
+ - **`terreno`** (hosted, Streamable HTTP) supplies documentation search and code generators.
6
+ - **`terreno-local`** (stdio, runs in your repository) reads the app's packages, database, logs,
7
+ Metro, and client state.
7
8
 
8
- ## Cursor
9
+ Apps made with `create-terreno-app` already contain both configurations. Use this guide to check
10
+ them, to add them to an older app, or to fix a server that does not connect.
9
11
 
10
- Add `.cursor/mcp.json` at the app repository root:
12
+ Prerequisites: Bun 1.4 or newer. The local server's bin is `#!/usr/bin/env bun`, and its `browser`
13
+ tool needs Bun 1.4.
14
+
15
+ ## 1. Configure Cursor
16
+
17
+ Create `.cursor/mcp.json` at the app repository root. This is the file `create-terreno-app` writes:
11
18
 
12
19
  ```json
13
20
  {
14
21
  "mcpServers": {
22
+ "expo": {
23
+ "type": "http",
24
+ "url": "https://mcp.expo.dev/mcp"
25
+ },
26
+ "playwright": {
27
+ "args": [
28
+ "-y",
29
+ "@playwright/mcp@0.0.76"
30
+ ],
31
+ "command": "npx"
32
+ },
15
33
  "terreno": {
16
34
  "type": "http",
17
- "url": "https://mcp.terreno.flourish.health/mcp"
35
+ "url": "https://mcp.terreno.app/mcp"
18
36
  },
19
37
  "terreno-local": {
20
- "command": "bunx",
21
- "args": ["terreno-mcp-local"]
38
+ "args": [
39
+ "-p",
40
+ "@terreno/mcp",
41
+ "terreno-mcp-local"
42
+ ],
43
+ "command": "bunx"
22
44
  }
23
45
  }
24
46
  }
25
47
  ```
26
48
 
27
- ## Claude Code
49
+ Only `terreno` and `terreno-local` are required. `expo` and `playwright` are optional; see
50
+ [step 5](#5-optional-add-expo-mcp-and-playwright-mcp).
51
+
52
+ Keep `-p @terreno/mcp` in the `terreno-local` args. The bin is named `terreno-mcp-local`, but the
53
+ npm package is `@terreno/mcp`. Without `-p`, `bunx` looks for an npm package named
54
+ `terreno-mcp-local`, gets a 404, and the server never starts.
55
+
56
+ Open the app repository root as the Cursor workspace. Then open Cursor's MCP settings and confirm
57
+ each server is enabled and lists its tools. If `terreno-local` reports the wrong project root, set
58
+ `TERRENO_PROJECT_ROOT` in its entry (step 4).
59
+
60
+ ## 2. Configure Claude Code
61
+
62
+ Claude Code reads project servers from `.mcp.json` at the repository root. `create-terreno-app`
63
+ writes the same content there as in `.cursor/mcp.json`, so the two files are byte-for-byte
64
+ identical:
65
+
66
+ ```json
67
+ {
68
+ "mcpServers": {
69
+ "expo": {
70
+ "type": "http",
71
+ "url": "https://mcp.expo.dev/mcp"
72
+ },
73
+ "playwright": {
74
+ "args": [
75
+ "-y",
76
+ "@playwright/mcp@0.0.76"
77
+ ],
78
+ "command": "npx"
79
+ },
80
+ "terreno": {
81
+ "type": "http",
82
+ "url": "https://mcp.terreno.app/mcp"
83
+ },
84
+ "terreno-local": {
85
+ "args": [
86
+ "-p",
87
+ "@terreno/mcp",
88
+ "terreno-mcp-local"
89
+ ],
90
+ "command": "bunx"
91
+ }
92
+ }
93
+ }
94
+ ```
95
+
96
+ Run `claude` from the repository root. On the first run, Claude Code asks you to approve the
97
+ project's servers. Approve them. Then check the servers:
98
+
99
+ ```bash
100
+ claude mcp list
101
+ ```
102
+
103
+ A server you have not approved yet is listed as `⏸ Pending approval`. After approval, each server
104
+ reports `✔ Connected`.
105
+
106
+ To register the two Terreno servers without editing the file, run these commands from the
107
+ repository root. `--scope project` writes the servers to `.mcp.json`:
108
+
109
+ ```bash
110
+ claude mcp add --scope project --transport http terreno https://mcp.terreno.app/mcp
111
+ claude mcp add --scope project terreno-local -- bunx -p @terreno/mcp terreno-mcp-local
112
+ ```
113
+
114
+ ## 3. Check the hosted endpoint
115
+
116
+ The hosted server's URL is `https://mcp.terreno.app/mcp`. It speaks MCP Streamable HTTP
117
+ (`"type": "http"`). `POST /` is accepted as an alias, but configure the `/mcp` path. Requests must
118
+ send `Accept: application/json, text/event-stream`; MCP clients do this for you.
119
+ `create-terreno-app` writes this URL into `.cursor/mcp.json` and `.mcp.json`. Use
120
+ `--mcp-server-url` to point a new app at a different deployment.
121
+
122
+ Check that the host answers:
123
+
124
+ ```bash
125
+ curl -s https://mcp.terreno.app/
126
+ ```
127
+
128
+ A working host returns `{"mcpEndpoint":"/mcp","service":"terreno-mcp","status":"ok"}`. If the
129
+ command prints `Could not resolve host: mcp.terreno.app`, or the editor reports
130
+ `getaddrinfo ENOTFOUND mcp.terreno.app`, that hostname does not resolve yet. Until it does, set the
131
+ `terreno` URL to `https://mcp.terreno.flourish.health/mcp` in `.cursor/mcp.json` and `.mcp.json`. It
132
+ serves the same service and tools.
133
+
134
+ ### Moving off `mcp.terreno.flourish.health`
135
+
136
+ Earlier docs and scaffolds used `https://mcp.terreno.flourish.health/mcp`. That hostname serves the
137
+ same Cloud Run service and keeps working for at least one release after the release that announces
138
+ `mcp.terreno.app`. Replace the old URL in `.cursor/mcp.json`, `.mcp.json`, and any
139
+ `claude mcp add` registration:
28
140
 
29
- Use the same project-scoped `.mcp.json`, or register the servers from the repository root:
141
+ For a project `.mcp.json`, edit the `url` in the file. For a registration you added with
142
+ `claude mcp add` outside the project file, re-add it in the same scope:
30
143
 
31
144
  ```bash
32
- claude mcp add --transport http terreno https://mcp.terreno.flourish.health/mcp
33
- claude mcp add terreno-local -- bunx terreno-mcp-local
145
+ claude mcp remove --scope local terreno
146
+ claude mcp add --scope local --transport http terreno https://mcp.terreno.app/mcp
34
147
  ```
35
148
 
36
- ## Configure local discovery
149
+ The operator cutover (domain mapping, DNS, retiring the old hostname) is in the
150
+ [infra/flourish README](https://github.com/TerrenoLabs/terreno/blob/master/infra/flourish/README.md#hosted-mcp-hostname).
37
151
 
38
- Run the local server from the app root. It discovers bootstrap apps with `backend/` and `frontend/`,
39
- and this monorepo's `example-backend/` logs. Set these variables only when discovery needs help:
152
+ ## 4. Give the local server what it needs
40
153
 
41
- | Variable | Use |
154
+ `terreno-local` starts without any of the items below, but each tool reads only what it can find.
155
+ The full rules are in the
156
+ [local server reference](../reference/mcp-server.md#local-server-terreno-mcp-local).
157
+
158
+ | Need | What to do |
42
159
  | --- | --- |
43
- | `TERRENO_PROJECT_ROOT` | Absolute app/monorepo root |
44
- | `TERRENO_METRO_URL` | Metro origin when the frontend script does not expose `--port` |
45
- | `MONGO_URI` | MongoDB used by `database_schema` and read-only `database_query` |
46
- | `TERRENO_MCP_EVAL=1` | Explicitly enable `evaluate`, `navigate`, and SyncDB state changes |
47
- | `BUN_CHROME_PATH` | Chrome/Chromium/Edge binary when Bun cannot auto-discover one |
48
-
49
- Backend and browser JSONL normally live under `<backend cwd>/.terreno/logs/`. Keep Metro running to
50
- collect Metro `/events` and app console output over CDP. Hermes accepts one debugger connection, so
51
- close React Native DevTools if the local MCP reports that CDP is unavailable.
52
-
53
- ## Verify
54
-
55
- Restart the editor's MCP clients, then ask it to call `application_info`. Confirm the result lists
56
- the app's installed `@terreno/*` versions. Next call `read_logs` with
57
- `{"sources":["backend","browser"]}`; an empty `entries` array is valid before the app logs anything.
58
- Call `browser` with `{"action":"open","url":"http://localhost:8082"}`, then `{"action":"snapshot"}`
59
- to confirm the agent can inspect the running web app. Finish with `{"action":"close"}`.
60
- If the app creates a SyncDB client with `debug: true`, call
61
- `get_syncdb_state` and confirm it returns the client name, status, collections,
62
- outbox, conflicts, cursors, and debug events.
160
+ | Project root | Start the editor in the app repository root. The server walks up from its working directory looking for a `package.json` with `backend/` and `frontend/` workspaces, and otherwise uses the working directory itself. Apps from `create-terreno-app` have no root `package.json`, so the walk-up never matches from a subfolder: start the editor at the app root or set `TERRENO_PROJECT_ROOT`. |
161
+ | A reachable MongoDB | Put `MONGO_URI` in `backend/.env` (`create-terreno-app` does this) or export it. `database_schema` and `database_query` use it. |
162
+ | Backend log file | Run the backend with `bun run dev`. Outside production the `@terreno/api` logger writes `backend/.terreno/logs/app.log`, which `read_logs` and `last_error` read. |
163
+ | Metro for app logs | Keep `bun run web` (or `start`, `ios`, `android`) running in `frontend/`. The server reads Metro on the script's `--port` (8082 in generated apps). Set `TERRENO_METRO_URL` for another origin. |
164
+
165
+ Set environment variables for the server in its config entry with `env`. For example, to point the
166
+ server at a root and allow the gated tools:
167
+
168
+ ```json
169
+ "terreno-local": {
170
+ "args": [
171
+ "-p",
172
+ "@terreno/mcp",
173
+ "terreno-mcp-local"
174
+ ],
175
+ "command": "bunx",
176
+ "env": {
177
+ "TERRENO_MCP_EVAL": "1",
178
+ "TERRENO_PROJECT_ROOT": "/absolute/path/to/my-app"
179
+ }
180
+ }
181
+ ```
182
+
183
+ `TERRENO_MCP_EVAL=1` enables `evaluate`, `navigate`, and SyncDB state changes; leave it out unless
184
+ you need them. Every variable is listed under
185
+ [Environment variables](../reference/mcp-server.md#environment-variables).
186
+
187
+ Hermes accepts one debugger connection. Close React Native DevTools if the local server reports
188
+ that CDP is unavailable.
189
+
190
+ ## 5. Optional: add expo-mcp and Playwright MCP
191
+
192
+ `create-terreno-app` adds two more servers next to the Terreno ones. Keep them when you want the
193
+ agent to drive the app, or delete their entries from both files:
194
+
195
+ - **`expo`** (`https://mcp.expo.dev/mcp`) takes screenshots and taps in the iOS simulator or
196
+ Android emulator. It asks you to sign in with your Expo account the first time it connects. Its
197
+ simulator tools also need the `expo-mcp` dev package in the app
198
+ (`cd frontend && bunx expo install expo-mcp --dev`) and a dev server started with
199
+ `EXPO_UNSTABLE_MCP_SERVER=1`, which the generated frontend scripts already set. See
200
+ [Expo MCP Server](https://docs.expo.dev/eas/ai/mcp/).
201
+ - **`playwright`** (`npx -y @playwright/mcp@0.0.76`) drives the web app in a full browser. The
202
+ version is pinned so `npx` does not resolve a moving `@latest`.
203
+
204
+ These servers interact with the app. Terreno's servers observe what the app did behind the screen.
205
+ Read [How this composes](../explanation/ai-development-loop.md#how-this-composes) for the division
206
+ of labor, including when a flow should become a Maestro test.
207
+
208
+ ## 6. Verify
209
+
210
+ 1. Restart the editor's MCP clients.
211
+ 2. Ask the agent: "Call the `application_info` tool from `terreno-local`."
212
+ 3. Confirm the result lists your app's `@terreno/*` packages. For an app generated with
213
+ `create-terreno-app` and no `bun install` yet, the result is (project root shortened):
214
+
215
+ ```markdown
216
+ # Application info
217
+
218
+ - **projectRoot**: `…/setup-check`
219
+ - **root package**: (none) @ ?
220
+ - **bun.lock present**: no
221
+
222
+ ## Backend workspace (backend/)
223
+ - **name**: @setup-check/backend
224
+ - **version**: 1.0.0
225
+ - @terreno/admin-backend: ^57.14.0
226
+ - @terreno/api: ^57.14.0
227
+ - @terreno/api-health: ^57.14.0
228
+ - **mongoose**: 9.7.4
229
+ - **@types/bun**: ^1.4.0
230
+
231
+ ## Frontend workspace (frontend/)
232
+ - **name**: @setup-check/frontend
233
+ - **version**: 1.0.0
234
+ - @terreno/admin-frontend: ^57.14.0
235
+ - @terreno/rtk: ^57.14.0
236
+ - @terreno/syncdb: ^57.14.0
237
+ - @terreno/ui: ^57.14.0
238
+ - **expo**: ~57.0.14
239
+ - **react**: 19.2.3
240
+ - **react-native**: 0.86.2
241
+ - **@types/bun**: ^1.4.0
242
+ ```
243
+
244
+ The versions are the ranges declared in each `package.json`, not resolved versions. If
245
+ `projectRoot` is not your app, set `TERRENO_PROJECT_ROOT` (step 4).
246
+ 4. Ask the agent to call `terreno_search_docs` from `terreno` with any query. A list of doc results
247
+ confirms the hosted server.
248
+
249
+ With the backend and frontend running, check the runtime tools too:
250
+
251
+ - Call `read_logs` with `{"sources":["backend","browser"]}`. An empty `entries` array is valid
252
+ before the app logs anything. A `create-terreno-app` app sends web console errors and warnings
253
+ to the backend with `installTerrenoDevConsoleLogger({baseUrl})` in `frontend/app/_layout.tsx`.
254
+ Its `backend/.env` sets `NODE_ENV=development`, which the backend needs to accept them. In
255
+ another app, add the same call at startup and run the backend with `NODE_ENV=development` or
256
+ `TERRENO_BROWSER_LOGS=true`.
257
+ - Call `browser` with `{"action":"open","url":"http://localhost:8082"}`, then
258
+ `{"action":"snapshot"}`, to confirm the agent can inspect the web app. Finish with
259
+ `{"action":"close"}`.
260
+ - If the app creates its SyncDB client with `debug: true`, call `get_syncdb_state` and confirm it
261
+ returns the client name, status, collections, outbox, conflicts, cursors, and debug events.
63
262
 
64
263
  The CLI exposes the same local tools without MCP:
65
264
 
@@ -67,3 +266,9 @@ The CLI exposes the same local tools without MCP:
67
266
  terreno info
68
267
  terreno logs --sources backend,browser
69
268
  ```
269
+
270
+ ## Related
271
+
272
+ - [MCP server reference](../reference/mcp-server.md): every tool, variable, and discovery rule
273
+ - [Debug a Terreno app with MCP](debug-with-mcp.md): the loop on a real failure
274
+ - [AI development loop](../explanation/ai-development-loop.md): how the servers fit together
@@ -0,0 +1,139 @@
1
+ # Sign consent on a user's behalf
2
+
3
+ Let staff record consent for a user ahead of time, for example after a guardian agrees by
4
+ phone at intake. The form counts as signed from then on, and the user still sees it and signs
5
+ it themselves. Concepts: [Consent forms](../explanation/consent-forms.md#provisional-signatures).
6
+
7
+ ## 1. Pass access control to ConsentApp
8
+
9
+ Add `userSchema.plugin(rbacUserPlugin)` (from `@terreno/api`) to your User schema so users
10
+ have a `roles` field and role assignments are saved. Then wire RBAC into the app:
11
+
12
+ ```typescript
13
+ import {
14
+ backfillAdmins,
15
+ ConsentApp,
16
+ createAccess,
17
+ rbacRouter,
18
+ TerrenoApp,
19
+ terrenoStatements,
20
+ } from "@terreno/api";
21
+
22
+ const access = createAccess({
23
+ connection: mongoose.connection,
24
+ statements: terrenoStatements,
25
+ userModel: User,
26
+ });
27
+
28
+ // After connecting to MongoDB: create or update the built-in roles.
29
+ await access.roles.seedDefaults();
30
+ // Give existing `admin: true` users the superadmin role, so they keep their access.
31
+ await backfillAdmins({access, userModel: User, wetRun: true});
32
+
33
+ new TerrenoApp({accessControl: access, userModel: User})
34
+ .register(rbacRouter({access, userModel: User}))
35
+ .register(new ConsentApp({accessControl: access, auditTrail: true}))
36
+ .start();
37
+ ```
38
+
39
+ With `accessControl`, any authenticated user whose roles grant
40
+ `consentResponse:signOnBehalf` may sign, read statuses, and void for other users. Without it,
41
+ only `user.admin` users may, and `ConsentApp` logs a warning at startup. With
42
+ `accessControl`, `user.admin` alone no longer grants signing: the user needs a role that
43
+ grants it. Turn on
44
+ `auditTrail` to keep the signer's IP address and user agent and a snapshot of the content they
45
+ signed. `rbacRouter` mounts the `/rbac` role API used in step 2.
46
+
47
+ Register `AuditApp` too if you want every provisional signature, status read, and void in the
48
+ audit log.
49
+
50
+ ## 2. Grant the permission
51
+
52
+ The built-in `admin` role includes `consentResponse: ["signOnBehalf"]`. Databases created
53
+ before this release get it the next time roles are seeded (`access.roles.seedDefaults()`),
54
+ without losing other grants on an unsealed `admin` role. `superadmin` has every action.
55
+
56
+ For staff who are not admins, create a role and assign it. `$TOKEN` must belong to a user
57
+ whose roles grant `rbac:manageRoles` and `rbac:assignRoles`, such as `superadmin`; the
58
+ built-in `admin` role has neither.
59
+
60
+ ```bash
61
+ curl -X POST "$API/rbac/roles" -H "Authorization: Bearer $TOKEN" \
62
+ -H "Content-Type: application/json" \
63
+ -d '{"name": "intake-staff", "displayName": "Intake staff",
64
+ "permissions": {"consentResponse": ["signOnBehalf"]}}'
65
+
66
+ curl -X PUT "$API/rbac/users/$STAFF_USER_ID/roles" -H "Authorization: Bearer $TOKEN" \
67
+ -H "Content-Type: application/json" -d '{"roleNames": ["intake-staff"]}'
68
+ ```
69
+
70
+ There is no relationship check: a permitted signer can sign for any user. Give the role only
71
+ to staff who should have that reach.
72
+
73
+ ## 3. Mount the signer screen
74
+
75
+ ```tsx
76
+ import {Page, ProvisionalConsentSigner} from "@terreno/ui";
77
+ import {useLocalSearchParams} from "expo-router";
78
+ import {terrenoApi} from "@/store/sdk";
79
+
80
+ const ConsentSignScreen: React.FC = () => {
81
+ const {userId} = useLocalSearchParams<{userId: string}>();
82
+ return (
83
+ <Page backButton title="Sign consent on behalf">
84
+ <ProvisionalConsentSigner api={terrenoApi} userId={userId} />
85
+ </Page>
86
+ );
87
+ };
88
+ ```
89
+
90
+ Put the route outside your admin area if non-admin staff use it. The component lists every
91
+ form that applies to the user with its status. Staff open a pending form, read it,
92
+ write a note saying how consent was obtained, and sign. The user then sees "Signed on your
93
+ behalf by <name> on <date>" above the form in their consent gate, but not the note.
94
+
95
+ Build your own UI with `useProvisionalConsent({api, userId})` instead, which returns
96
+ `statuses`, `sign`, and `voidSignature`.
97
+
98
+ ## 4. Check whether a user is considered signed
99
+
100
+ ```typescript
101
+ import {getConsentStatuses} from "@terreno/api";
102
+
103
+ const rows = await getConsentStatuses({resolveConsentForms, userId});
104
+ const canSchedule = rows.filter((row) => row.form.required).every((row) => row.isConsented);
105
+ ```
106
+
107
+ `isConsented` is true for `signed` and `provisional`. The user's own answer always wins: once
108
+ they agree the row is `signed`, and once they decline it is `declined`. Pass the same
109
+ `resolveConsentForms` you gave `ConsentApp`. Clients call `GET /consent-responses/status?userId=`
110
+ for the same rows.
111
+
112
+ ## 5. Void a signature made in error
113
+
114
+ In `ProvisionalConsentSigner`, press "Void" on a provisional row and give a reason. Over HTTP:
115
+
116
+ ```bash
117
+ curl -X POST "$API/consent-responses/$RESPONSE_ID/void" -H "Authorization: Bearer $TOKEN" \
118
+ -H "Content-Type: application/json" -d '{"reason": "Signed for the wrong member"}'
119
+ ```
120
+
121
+ The record stays, with `voidedAt`, `voidedBy`, and `voidReason` set. The form returns to
122
+ `pending` and the user's notice disappears.
123
+
124
+ ## 6. Print a consent record
125
+
126
+ - `ProvisionalConsentSigner`: "Print" on a provisional, signed, or declined row, or on the
127
+ confirmation after signing.
128
+ - Admin: the "Print" button on `ConsentResponseViewer` (`@terreno/admin-frontend`).
129
+ - The user's own history: the print icon on a `ConsentHistory` entry
130
+ (`@terreno/admin-frontend`).
131
+
132
+ When the record is provisional, the printout includes a "Provisional signature" section with
133
+ the signer and date. Staff and
134
+ admin printouts also show the note; the user's own printout never does. To print your own
135
+ HTML, call `printConsentHtml({html: buildConsentPdfHtml(data)})` from `@terreno/ui`.
136
+
137
+ Reference: [ConsentApp](../reference/api.md#consent-forms-consentapp),
138
+ [consent components](../reference/ui.md#consent-components),
139
+ [consent records and PDFs](../reference/admin-frontend.md#consent-records-and-pdfs).
@@ -80,3 +80,7 @@ bun install
80
80
  ```
81
81
 
82
82
  If you already committed, `git revert` the upgrade commit or reset the branch to the pre-upgrade SHA before it was pushed. Do not leave a half-upgraded lockfile on `master`.
83
+
84
+ ## 8. Automate it
85
+
86
+ To have an agent open the upgrade pull request on a schedule, see [Automate Terreno upgrades](automate-terreno-upgrades.md).
@@ -7,19 +7,19 @@
7
7
  **Owner:** unassigned
8
8
  **Created:** 2026-07-27
9
9
  **Program:** [OSS launch](oss-launch-program.md)
10
- **Depends on:** PR [#802](https://github.com/TerrenoLabs/terreno/pull/802) merging (assumed)
11
- **RTK deprecation flag:** **Partial** — `get_rtk_state` and `installTerrenoDevConsoleLogger` are RTK-named surfaces delivered by #802 that must be renamed or relocated after #869. Marked tasks are blocked on both PRs.
10
+ **Depends on:** PR [#802](https://github.com/TerrenoLabs/terreno/pull/802) merging (assumed). **Reconciled 2026-10-12:** #802 and #869 were both closed unmerged, but their substance is on `master` through later PRs (CDP log tools, Metro sessions, the browser-log route, `@terreno/syncdb`, and `get_syncdb_state`; mainly #1128). Read "merged #802" in this plan as "current `master`".
11
+ **RTK deprecation flag:** **Partial** — `get_rtk_state` and `installTerrenoDevConsoleLogger` are RTK-named surfaces that must be renamed or relocated now that `@terreno/syncdb` exists (the #869 substance). Both are on `master`, so the marked tasks are no longer blocked on unmerged PRs.
12
12
 
13
13
  ## Goal
14
14
 
15
- Turn Terreno's AI-native pillar from a claim into a documented, demonstrable loop. The machinery mostly exists after PR #802 lands: an agent can search current docs, generate conventional code, run the app, read merged logs from four sources, see the last error with a stack, inspect client state, and drive navigation. What does not exist is any document that explains this as a single workflow, so nobody outside the team knows it is there.
15
+ Turn Terreno's AI-native pillar from a claim into a documented, demonstrable loop. The machinery exists on `master`: an agent can search current docs, generate conventional code, run the app, read merged logs from four sources, see the last error with a stack, inspect client state, and drive navigation. What does not exist is any document that explains this as a single workflow, so nobody outside the team knows it is there.
16
16
 
17
17
  This IP writes the story and closes the gaps that become obvious once the story is written down.
18
18
 
19
19
  ## Non-Goals
20
20
 
21
21
  - Building new MCP tools beyond renames and small gap-fillers.
22
- - Re-implementing UI automation — #802 deliberately composes `expo-mcp`, Playwright MCP, and Maestro rather than building tap/screenshot tooling.
22
+ - Re-implementing UI automation — #802 deliberately composes `expo-mcp`, Playwright MCP, and Maestro rather than building tap/screenshot tooling. (Fact check 2026-10-12: `master` has since added a web-only `browser` tool to `terreno-mcp-local`, built on Bun's WebView, with `snapshot` and `screenshot` actions. Native simulator interaction still comes from `expo-mcp`.)
23
23
  - The tutorial itself (that is [`docs-tutorials-ai-first`](docs-tutorials-ai-first.md), which depends on this IP's reference content).
24
24
  - Langfuse/observability for AI features inside consumer apps (that is `terreno-langfuse-integration.md`).
25
25
 
@@ -43,10 +43,10 @@ This IP writes the story and closes the gaps that become obvious once the story
43
43
  ```mermaid
44
44
  flowchart LR
45
45
  ASK["1. Ask<br/>terreno_search_docs<br/>terreno_get_component_docs"]
46
- GEN["2. Generate<br/>generate_model / route / screen<br/>validate_model_schema"]
46
+ GEN["2. Generate<br/>terreno_generate_model / _route / _screen<br/>terreno_validate_model_schema"]
47
47
  RUN["3. Run<br/>bun run backend:dev<br/>expo start"]
48
48
  OBS["4. Observe<br/>read_logs (backend/app/metro/browser)<br/>last_error<br/>get_client_state"]
49
- FIX["5. Fix<br/>navigate + screenshot<br/>regenerate typed client"]
49
+ FIX["5. Fix<br/>navigate + browser screenshot<br/>regenerate typed client"]
50
50
  ASK --> GEN --> RUN --> OBS --> FIX
51
51
  FIX -->|"iterate"| ASK
52
52
  ```
@@ -64,46 +64,61 @@ This loop is only half the AI story, and documenting it alone undersells it. The
64
64
 
65
65
  Every document produced by this IP must name both and explain that they compose: the pipeline's implement stage uses the loop's tools, and the loop's tools are most useful when driven by the pipeline's sequencing. `docs/explanation/ai-development-loop.md` and `docs/explanation/agentic-sdlc.md` are companion pages and must cross-link.
66
66
 
67
- ### Tool surface after #802
67
+ ### Tool surface (reconciled with master, 2026-10-12)
68
+
69
+ Every name below is registered in source. The hosted server (`terreno-mcp`, `mcp-server/src/index.ts`) registers tools from `mcp-server/src/tools.ts` and `mcp-server/src/bootstrap.ts`. The local stdio server (`terreno-mcp-local`, `mcp-server/src/local/`) registers tools only, from `mcp-server/src/local/localTools.ts`. Full input schemas and every environment variable, with the file that reads it, are in the Task 1.1 evidence (`.terreno/pipeline/ai-dev-loop-boost-evidence/inventory.md`).
68
70
 
69
71
  | Tool | Server | Purpose |
70
72
  |------|--------|---------|
71
- | `terreno_search_docs` | hosted | BM25 search over the docs corpus, multi-query |
72
- | `terreno_get_component_docs` | hosted | Full props table for a `@terreno/ui` component |
73
+ | `terreno_search_docs` | hosted | BM25 search over the docs corpus, multi-query, optional `packages` and lockstep `version` |
74
+ | `terreno_get_component_docs` | hosted | Full props table for a `@terreno/ui` component, optional `version` |
73
75
  | `terreno_get_upgrade_guide` | hosted | Concatenated upgrade notes for a version range |
74
- | `terreno_bootstrap_app` / `terreno_bootstrap_ai_rules` | hosted | Scaffold an app / agent rules |
75
- | `terreno_generate_*`, `terreno_validate_model_schema`, `terreno_install_admin` | hosted | Codegen |
76
+ | `terreno_search_update_notes` / `terreno_get_update_note` / `terreno_ask_update_help` | hosted | Search, fetch, and question bundled upgrade notes, plus help-API announcements when `TERRENO_HELP_API_URL` is set |
77
+ | `terreno_bootstrap_ai_rules` | hosted | Agent rule files for Cursor, Windsurf, Claude Code, and Copilot. App scaffolding moved to `bunx create-terreno-app`, and `terreno_bootstrap_app` no longer exists. |
78
+ | `terreno_generate_model` / `terreno_generate_route` / `terreno_generate_screen` / `terreno_generate_form_fields` | hosted | Codegen |
79
+ | `terreno_validate_model_schema` / `terreno_validate_ui_blocks` | hosted | Convention and block-document validation |
80
+ | `terreno_install_admin` | hosted | Admin panel integration snippets |
76
81
  | `application_info` | local | `@terreno/*` and toolchain versions |
77
- | `database_schema` / `database_query` | local | Mongo introspection, read-only allowlist |
78
- | `read_logs` | local | Merged backend + app (CDP) + Metro + browser logs |
79
- | `last_error` | local | Most recent error with stack across sources |
80
- | `get_rtk_state` → `get_client_state` | local | Store and cache inspection |
81
- | `evaluate` / `navigate` | local | CDP runtime, `TERRENO_MCP_EVAL=1` gated |
82
+ | `database_schema` / `database_query` | local | Mongo introspection with a read-only allowlist, using `MONGO_URI` or `backend/.env` |
83
+ | `read_logs` | local | Merged logs from `backend` (JSONL), `browser` (JSONL), `metro` (`/events`), and `app` (Hermes console over CDP) |
84
+ | `last_error` | local | Raw JSONL line of the newest error-level entry across the same four sources. A stack is included only when the entry carries one. |
85
+ | `get_rtk_state` | local | Redux auth and RTK Query cache inspection (in-process or CDP). It is not gated. This is the tool that AI1 renames to `get_client_state`; `get_client_state` does not exist yet. |
86
+ | `get_syncdb_state` / `syncdb_snapshot` / `syncdb_action` | local | SyncDB inspection, snapshots, and actions. `syncdb_action` is gated by `TERRENO_MCP_EVAL=1`. |
87
+ | `evaluate` / `navigate` | local | CDP `Runtime.evaluate` and expo-router navigation, both gated by `TERRENO_MCP_EVAL=1` |
88
+ | `browser` | local | Headless web driving through Bun 1.4 WebView: open, click, type, snapshot, and screenshot. Only its `evaluate` action is gated by `TERRENO_MCP_EVAL=1`. |
89
+
90
+ Prompts (hosted only): `terreno_bootstrap`, `terreno_create_crud_feature`, `terreno_create_api_endpoint`, `terreno_create_ui_component`, `terreno_create_form_screen`, `terreno_add_authentication`, `terreno_style_guide`, `terreno_migrate_to_terreno_app`, `terreno_upgrade`. Resources (hosted only): `terreno://docs/{overview,api,ui,syncdb,rtk,patterns}`, plus `terreno://docs/ui/components` and one `terreno://docs/ui/components/<slug>` per component.
82
91
 
83
92
  ### Gaps that surface once the story is written
84
93
 
85
- 1. **Naming**: `get_rtk_state` is named after a package being deprecated (AI1).
86
- 2. **Discovery**: nothing tells a developer to install `terreno-mcp-local`. `docs/reference/mcp-server.md` documents it, but no getting-started path mentions it.
87
- 3. **Hermes single-connection contention**: opening React Native DevTools steals the CDP connection the log tools need. #802 mitigates with lazy connect/release and status reporting; users need to know the symptom.
88
- 4. **No end-to-end setup guide**: MCP configuration is scattered across the README and the reference page, per-editor, with no single how-to.
89
- 5. **Hosted server has no rate limiting** (AI5) — a launch risk.
90
- 6. **Composition is undocumented**: `expo-mcp` and Playwright MCP wiring exists in bootstrap output but is not explained (AI4).
94
+ 1. **Naming**: `get_rtk_state` is named after a package being deprecated (AI1). It reads Redux only. SyncDB state has its own tool (`get_syncdb_state`), so `get_client_state` must decide whether to reuse that bridge or report the SyncDB layer itself.
95
+ 2. **Discovery**: `docs/how-to/set-up-terreno-mcp.md` now exists. It is linked from `docs/README.md`, `docs/how-to/README.md`, `docs/reference/mcp-server.md`, and the `terreno://docs/overview` resource, but not from the root `README.md` or `docs/tutorials/README.md`. `create-terreno-app` writes `terreno-local` into `.cursor/mcp.json` but does not point at the guide.
96
+ 3. **Hermes single-connection contention**: opening React Native DevTools steals the CDP connection the log tools need. `master` connects lazily and holds the socket for the life of the MCP process; there is no release. On close it reports `CDP disconnected` and reconnects on the next call. Status reaches the agent in `read_logs`' `connection` field (`CDP: …; Metro events: …`). Users need to know the symptom.
97
+ 4. **Setup guide is incomplete and inconsistent**: `docs/how-to/set-up-terreno-mcp.md` covers Cursor and Claude Code for both servers. It uses `https://mcp.terreno.flourish.health/mcp`, while `create-terreno-app` and the root README use `https://mcp.terreno.app` (AI6). It also omits `expo-mcp` and Playwright MCP.
98
+ 5. **Hosted server has no rate limiting** (AI5), which is a launch risk. Neither `mcp-server/src/index.ts` nor the `mcp_service` Cloud Run module in `terraform/main.tf` limits requests, and the service allows unauthenticated access. `@terreno/api`'s opt-in `rateLimit` does not apply, because the hosted server uses `createMcpExpressApp`, not `TerrenoApp`.
99
+ 6. **Composition is undocumented**: `create-terreno-app` writes `expo` (`https://mcp.expo.dev/mcp`) and `playwright` (`@playwright/mcp`) entries into `.cursor/mcp.json` (`create-terreno-app/src/generate.ts`), but no doc explains them (AI4).
100
+ 7. **Reference drift**: `docs/reference/mcp-server.md` has no sections for `application_info`, `database_schema`, `database_query`, `read_logs`, `last_error`, `get_rtk_state`, `evaluate`, `navigate`, or the three update-note tools. Its env table omits `TERRENO_HELP_API_URL`, `TERRENO_HELP_API_TOKEN`, `MONGO_URI`, `TERRENO_LOG_FILE`, and the Sentry variables. `mcp-server/README.md` omits `terreno_validate_ui_blocks` and lists only the SyncDB local tools.
91
101
 
92
102
  ### Documentation to produce
93
103
 
94
104
  | Document | Purpose |
95
105
  |----------|---------|
96
106
  | `docs/explanation/ai-development-loop.md` | The five-stage loop, why it is different, what the agent can and cannot see |
97
- | `docs/how-to/set-up-terreno-mcp.md` | Per-editor configuration for both Terreno servers plus composed servers |
98
- | `docs/how-to/debug-with-mcp.md` | Using `read_logs`, `last_error`, `get_client_state`, `navigate` on a real failure |
99
- | `docs/reference/mcp-server.md` | Updated with the complete post-#802 tool surface and every environment variable |
107
+ | `docs/how-to/set-up-terreno-mcp.md` | Per-editor configuration for both Terreno servers plus composed servers. This page already exists on `master`, so update it rather than create it. |
108
+ | `docs/how-to/debug-with-mcp.md` | Using `read_logs`, `last_error`, `get_client_state`, `navigate` on a real failure. This page already exists on `master` and covers `get_rtk_state` and the SyncDB tools; update it. |
109
+ | `docs/reference/mcp-server.md` | Updated with the complete tool surface on `master` and every environment variable |
100
110
  | `docs/explanation/agent-guidelines.md` | How per-package `.ai/` guidelines and `.rulesync/` rules reach an agent, and how consumers extend them |
101
111
 
102
112
  Companion page owned elsewhere: `docs/explanation/agentic-sdlc.md` (the process layer) from [`agentic-sdlc-plugin`](agentic-sdlc-plugin.md). Neither page should duplicate the other; each links the other as the missing half.
103
113
 
104
114
  ## Models / APIs
105
115
 
106
- No new models. `POST /__terreno/browser-logs` (dev-only, from #802) needs documenting including its production-disabled behavior and the `TERRENO_BROWSER_LOGS` override.
116
+ No new models. `POST /__terreno/browser-logs` (dev-only, `api/src/browserLogsRoute.ts`) needs documenting, including its production-disabled behavior and the `TERRENO_BROWSER_LOGS` override. Facts on `master`:
117
+
118
+ - Only `TerrenoApp` registers the route, not legacy `setupServer`.
119
+ - By default it is on only when `NODE_ENV === "development"`. An unset `NODE_ENV` leaves it off unless `TERRENO_BROWSER_LOGS=true`.
120
+ - It is never registered in `production`, so requests there get a 404.
121
+ - It returns 403 to clients that are neither loopback nor authenticated.
107
122
 
108
123
  ## Notifications
109
124
 
@@ -115,17 +130,18 @@ None. `installTerrenoDevConsoleLogger` is invisible instrumentation.
115
130
 
116
131
  ## Phases
117
132
 
118
- 1. **Reconcile with merged #802** — verify the actual tool names, parameters, and environment variables.
133
+ 1. **Reconcile with `master`** (#802 and #869 closed unmerged; their substance landed through later PRs): verify the actual tool names, parameters, and environment variables.
119
134
  2. **Reference completeness** — update `docs/reference/mcp-server.md` to the real surface.
120
135
  3. **The loop explainer** — `ai-development-loop.md`.
121
136
  4. **Setup and debug how-tos** — including composed servers.
122
- 5. **Gap fixes** — the `get_client_state` rename (post-#869), logger relocation, hosted rate limiting, discovery paths.
137
+ 5. **Gap fixes** — the `get_client_state` rename (`@terreno/syncdb` is on `master`), logger relocation, hosted rate limiting, discovery paths, and the CDP `Origin` header fix that Task 1.3 found (Task 5.5).
123
138
  6. **Agent guidelines explainer** — how guidelines reach agents and how consumers extend them.
124
139
 
125
140
  ## Feature Flags & Migrations
126
141
 
127
- - `TERRENO_MCP_EVAL=1` gates `evaluate` and `navigate`; never enabled by bootstrap defaults.
128
- - `TERRENO_BROWSER_LOGS` and `NODE_ENV` gate the browser-log route.
142
+ - `TERRENO_MCP_EVAL=1` (or `true`) gates `evaluate`, `navigate`, `syncdb_action`, and the `browser` tool's `evaluate` action. It does not gate `get_rtk_state`, `get_syncdb_state`, or `syncdb_snapshot`, which read app state over CDP with fixed expressions. The `.cursor/mcp.json` that `create-terreno-app` generates never sets it.
143
+ - `TERRENO_BROWSER_LOGS` and `NODE_ENV` gate the browser-log route (`api/src/browserLogsRoute.ts`). By default it is on only when `NODE_ENV=development`.
144
+ - `TERRENO_LOG_FILE` and `NODE_ENV` gate the backend JSONL file that `read_logs` reads (`api/src/logger.ts`). By default it is on whenever `NODE_ENV !== "production"`.
129
145
  - Renaming `get_rtk_state` to `get_client_state` is a breaking MCP tool change: keep the old name as an alias for one release with a deprecation note in its description.
130
146
 
131
147
  ## Not Included / Future Work
@@ -140,12 +156,11 @@ None. `installTerrenoDevConsoleLogger` is invisible instrumentation.
140
156
  **Create**
141
157
 
142
158
  - `docs/explanation/ai-development-loop.md`
143
- - `docs/how-to/set-up-terreno-mcp.md`
144
- - `docs/how-to/debug-with-mcp.md`
145
159
  - `docs/explanation/agent-guidelines.md`
146
160
 
147
161
  **Modify**
148
162
 
163
+ - `docs/how-to/set-up-terreno-mcp.md`, `docs/how-to/debug-with-mcp.md` (both already on `master`)
149
164
  - `docs/reference/mcp-server.md`, `mcp-server/README.md`
150
165
  - `mcp-server/src/local/tools/runtime.ts` (tool rename + alias)
151
166
  - `mcp-server/src/local/localTools.ts` (tool registration)