@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.
- package/CHANGELOG.md +393 -0
- package/README.md +32 -269
- package/dist/bootstrap.d.ts +12 -0
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +77 -122
- package/dist/bootstrap.js.map +1 -1
- package/dist/docs/guidelines/ui/guidelines/core.md +1 -1
- package/dist/docs/resources/overview.md +4 -2
- package/dist/docs/resources/patterns.md +237 -176
- package/dist/docs/resources/ui.md +48 -17
- package/dist/docs/templates/bootstrap/frontend/app/(tabs)/profile.template.tsx +0 -26
- package/dist/docs/templates/bootstrap/frontend/app/_layout.template.tsx +3 -2
- package/dist/docs/templates/bootstrap/frontend/app/login.template.tsx +1 -1
- package/dist/docs/upgrades/57.20.0.md +238 -0
- package/dist/docs/versioned/next/approval-rubric.md +30 -12
- package/dist/docs/versioned/next/explanation/README.md +5 -0
- package/dist/docs/versioned/next/explanation/account-linking.md +169 -0
- package/dist/docs/versioned/next/explanation/admin-interface.md +1 -1
- package/dist/docs/versioned/next/explanation/agent-guidelines.md +173 -0
- package/dist/docs/versioned/next/explanation/ai-development-loop.md +196 -0
- package/dist/docs/versioned/next/explanation/authentication.md +45 -1
- package/dist/docs/versioned/next/explanation/consent-forms.md +105 -0
- package/dist/docs/versioned/next/explanation/example-coverage.md +1 -0
- package/dist/docs/versioned/next/explanation/local-first-data.md +1 -1
- package/dist/docs/versioned/next/explanation/organizations.md +37 -0
- package/dist/docs/versioned/next/explanation/planning-plugins.md +4 -0
- package/dist/docs/versioned/next/explanation/responsive-design.md +143 -0
- package/dist/docs/versioned/next/explanation/roadmap-seed-issues.md +11 -0
- package/dist/docs/versioned/next/explanation/schema-metadata.md +5 -0
- package/dist/docs/versioned/next/how-to/README.md +7 -2
- package/dist/docs/versioned/next/how-to/audit-log.md +22 -3
- package/dist/docs/versioned/next/how-to/automate-terreno-upgrades.md +169 -0
- package/dist/docs/versioned/next/how-to/build-list-detail-screens.md +160 -0
- package/dist/docs/versioned/next/how-to/circleci.md +15 -5
- package/dist/docs/versioned/next/how-to/configure-better-auth.md +673 -53
- package/dist/docs/versioned/next/how-to/create-a-terreno-app.md +8 -5
- package/dist/docs/versioned/next/how-to/debug-with-mcp.md +393 -23
- package/dist/docs/versioned/next/how-to/enable-mcp-oauth.md +54 -3
- package/dist/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +9 -0
- package/dist/docs/versioned/next/how-to/password-reset.md +1 -1
- package/dist/docs/versioned/next/how-to/recover-locked-out-user.md +112 -0
- package/dist/docs/versioned/next/how-to/run-tests-locally.md +37 -8
- package/dist/docs/versioned/next/how-to/set-up-social-login.md +424 -0
- package/dist/docs/versioned/next/how-to/set-up-terreno-mcp.md +241 -36
- package/dist/docs/versioned/next/how-to/sign-consent-on-behalf.md +139 -0
- package/dist/docs/versioned/next/how-to/upgrade-terreno.md +4 -0
- package/dist/docs/versioned/next/implementationPlans/ai-dev-loop-boost.md +47 -32
- package/dist/docs/versioned/next/implementationPlans/auth-experience.md +952 -0
- package/dist/docs/versioned/next/implementationPlans/consent-forms.md +8 -0
- package/dist/docs/versioned/next/implementationPlans/list-detail-layout.md +297 -0
- package/dist/docs/versioned/next/implementationPlans/login-redesign/HANDOFF.md +211 -0
- package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/AnotherWay.html +121 -0
- package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/BackupCode.html +72 -0
- package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/Cancelled.html +87 -0
- package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/ContinueEmail.html +64 -0
- package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/FirstVisit.html +81 -0
- package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/Main.html +88 -0
- package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/ManageAccounts.html +77 -0
- package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/NotLinked.html +92 -0
- package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/SigningIn.html +60 -0
- package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/TwoFactor.html +76 -0
- package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/TwoFactorError.html +81 -0
- package/dist/docs/versioned/next/implementationPlans/login-redesign/boards/WrongPassword.html +69 -0
- package/dist/docs/versioned/next/implementationPlans/mcp-boost-parity.md +1 -1
- package/dist/docs/versioned/next/plans/2026-10-23-provisional-consent.md +297 -0
- package/dist/docs/versioned/next/plans/2026-10-29-fix-mcp-oauth-native-and-machine.md +68 -0
- package/dist/docs/versioned/next/reference/README.md +1 -0
- package/dist/docs/versioned/next/reference/account-security.md +700 -0
- package/dist/docs/versioned/next/reference/admin-backend.md +3 -1
- package/dist/docs/versioned/next/reference/admin-frontend.md +225 -1
- package/dist/docs/versioned/next/reference/api.md +461 -35
- package/dist/docs/versioned/next/reference/cli.md +1 -1
- package/dist/docs/versioned/next/reference/comms.md +8 -0
- package/dist/docs/versioned/next/reference/create-terreno-app.md +3 -1
- package/dist/docs/versioned/next/reference/environment-variables.md +9 -3
- package/dist/docs/versioned/next/reference/legacy/rtk.md +19 -3
- package/dist/docs/versioned/next/reference/lifecycle-plugin.md +6 -0
- package/dist/docs/versioned/next/reference/mcp-server.md +1158 -441
- package/dist/docs/versioned/next/reference/syncdb.md +8 -1
- package/dist/docs/versioned/next/reference/ui.md +1271 -27
- package/dist/docs/versioned/next/tasks/ai-dev-loop-boost.md +28 -16
- package/dist/docs/versioned/next/tutorials/README.md +4 -0
- package/dist/httpApp.d.ts +14 -0
- package/dist/httpApp.d.ts.map +1 -0
- package/dist/httpApp.js +99 -0
- package/dist/httpApp.js.map +1 -0
- package/dist/index.js +8 -90
- package/dist/index.js.map +1 -1
- package/dist/local/localTools.d.ts.map +1 -1
- package/dist/local/localTools.js +44 -14
- package/dist/local/localTools.js.map +1 -1
- package/dist/local/metro/metroDevSession.d.ts +18 -0
- package/dist/local/metro/metroDevSession.d.ts.map +1 -1
- package/dist/local/metro/metroDevSession.js +42 -3
- package/dist/local/metro/metroDevSession.js.map +1 -1
- package/dist/local/tools/databaseQuery.d.ts.map +1 -1
- package/dist/local/tools/databaseQuery.js +3 -13
- package/dist/local/tools/databaseQuery.js.map +1 -1
- package/dist/local/tools/databaseSchema.d.ts.map +1 -1
- package/dist/local/tools/databaseSchema.js +3 -13
- package/dist/local/tools/databaseSchema.js.map +1 -1
- package/dist/local/tools/localMongo.d.ts +10 -0
- package/dist/local/tools/localMongo.d.ts.map +1 -0
- package/dist/local/tools/localMongo.js +30 -0
- package/dist/local/tools/localMongo.js.map +1 -0
- package/dist/local/tools/runtime.d.ts +18 -2
- package/dist/local/tools/runtime.d.ts.map +1 -1
- package/dist/local/tools/runtime.js +75 -20
- package/dist/local/tools/runtime.js.map +1 -1
- package/dist/local/tools/syncDb.d.ts +11 -0
- package/dist/local/tools/syncDb.d.ts.map +1 -1
- package/dist/local/tools/syncDb.js +15 -3
- package/dist/local/tools/syncDb.js.map +1 -1
- package/dist/rateLimit.d.ts +35 -0
- package/dist/rateLimit.d.ts.map +1 -0
- package/dist/rateLimit.js +112 -0
- package/dist/rateLimit.js.map +1 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +42 -60
- package/dist/tools.js.map +1 -1
- package/package.json +4 -3
- package/src/docs/guidelines/ui/guidelines/core.md +1 -1
- package/src/docs/resources/overview.md +4 -2
- package/src/docs/resources/patterns.md +237 -176
- package/src/docs/resources/ui.md +48 -17
- package/src/docs/templates/bootstrap/frontend/app/(tabs)/profile.template.tsx +0 -26
- package/src/docs/templates/bootstrap/frontend/app/_layout.template.tsx +3 -2
- package/src/docs/templates/bootstrap/frontend/app/login.template.tsx +1 -1
- package/src/docs/upgrades/57.20.0.md +238 -0
- package/src/docs/versioned/next/approval-rubric.md +30 -12
- package/src/docs/versioned/next/explanation/README.md +5 -0
- package/src/docs/versioned/next/explanation/account-linking.md +169 -0
- package/src/docs/versioned/next/explanation/admin-interface.md +1 -1
- package/src/docs/versioned/next/explanation/agent-guidelines.md +173 -0
- package/src/docs/versioned/next/explanation/ai-development-loop.md +196 -0
- package/src/docs/versioned/next/explanation/authentication.md +45 -1
- package/src/docs/versioned/next/explanation/consent-forms.md +105 -0
- package/src/docs/versioned/next/explanation/example-coverage.md +1 -0
- package/src/docs/versioned/next/explanation/local-first-data.md +1 -1
- package/src/docs/versioned/next/explanation/organizations.md +37 -0
- package/src/docs/versioned/next/explanation/planning-plugins.md +4 -0
- package/src/docs/versioned/next/explanation/responsive-design.md +143 -0
- package/src/docs/versioned/next/explanation/roadmap-seed-issues.md +11 -0
- package/src/docs/versioned/next/explanation/schema-metadata.md +5 -0
- package/src/docs/versioned/next/how-to/README.md +7 -2
- package/src/docs/versioned/next/how-to/audit-log.md +22 -3
- package/src/docs/versioned/next/how-to/automate-terreno-upgrades.md +169 -0
- package/src/docs/versioned/next/how-to/build-list-detail-screens.md +160 -0
- package/src/docs/versioned/next/how-to/circleci.md +15 -5
- package/src/docs/versioned/next/how-to/configure-better-auth.md +673 -53
- package/src/docs/versioned/next/how-to/create-a-terreno-app.md +8 -5
- package/src/docs/versioned/next/how-to/debug-with-mcp.md +393 -23
- package/src/docs/versioned/next/how-to/enable-mcp-oauth.md +54 -3
- package/src/docs/versioned/next/how-to/migrate-rtk-to-syncdb.md +9 -0
- package/src/docs/versioned/next/how-to/password-reset.md +1 -1
- package/src/docs/versioned/next/how-to/recover-locked-out-user.md +112 -0
- package/src/docs/versioned/next/how-to/run-tests-locally.md +37 -8
- package/src/docs/versioned/next/how-to/set-up-social-login.md +424 -0
- package/src/docs/versioned/next/how-to/set-up-terreno-mcp.md +241 -36
- package/src/docs/versioned/next/how-to/sign-consent-on-behalf.md +139 -0
- package/src/docs/versioned/next/how-to/upgrade-terreno.md +4 -0
- package/src/docs/versioned/next/implementationPlans/ai-dev-loop-boost.md +47 -32
- package/src/docs/versioned/next/implementationPlans/auth-experience.md +952 -0
- package/src/docs/versioned/next/implementationPlans/consent-forms.md +8 -0
- package/src/docs/versioned/next/implementationPlans/list-detail-layout.md +297 -0
- package/src/docs/versioned/next/implementationPlans/login-redesign/HANDOFF.md +211 -0
- package/src/docs/versioned/next/implementationPlans/login-redesign/boards/AnotherWay.html +121 -0
- package/src/docs/versioned/next/implementationPlans/login-redesign/boards/BackupCode.html +72 -0
- package/src/docs/versioned/next/implementationPlans/login-redesign/boards/Cancelled.html +87 -0
- package/src/docs/versioned/next/implementationPlans/login-redesign/boards/ContinueEmail.html +64 -0
- package/src/docs/versioned/next/implementationPlans/login-redesign/boards/FirstVisit.html +81 -0
- package/src/docs/versioned/next/implementationPlans/login-redesign/boards/Main.html +88 -0
- package/src/docs/versioned/next/implementationPlans/login-redesign/boards/ManageAccounts.html +77 -0
- package/src/docs/versioned/next/implementationPlans/login-redesign/boards/NotLinked.html +92 -0
- package/src/docs/versioned/next/implementationPlans/login-redesign/boards/SigningIn.html +60 -0
- package/src/docs/versioned/next/implementationPlans/login-redesign/boards/TwoFactor.html +76 -0
- package/src/docs/versioned/next/implementationPlans/login-redesign/boards/TwoFactorError.html +81 -0
- package/src/docs/versioned/next/implementationPlans/login-redesign/boards/WrongPassword.html +69 -0
- package/src/docs/versioned/next/implementationPlans/mcp-boost-parity.md +1 -1
- package/src/docs/versioned/next/plans/2026-10-23-provisional-consent.md +297 -0
- package/src/docs/versioned/next/plans/2026-10-29-fix-mcp-oauth-native-and-machine.md +68 -0
- package/src/docs/versioned/next/reference/README.md +1 -0
- package/src/docs/versioned/next/reference/account-security.md +700 -0
- package/src/docs/versioned/next/reference/admin-backend.md +3 -1
- package/src/docs/versioned/next/reference/admin-frontend.md +225 -1
- package/src/docs/versioned/next/reference/api.md +461 -35
- package/src/docs/versioned/next/reference/cli.md +1 -1
- package/src/docs/versioned/next/reference/comms.md +8 -0
- package/src/docs/versioned/next/reference/create-terreno-app.md +3 -1
- package/src/docs/versioned/next/reference/environment-variables.md +9 -3
- package/src/docs/versioned/next/reference/legacy/rtk.md +19 -3
- package/src/docs/versioned/next/reference/lifecycle-plugin.md +6 -0
- package/src/docs/versioned/next/reference/mcp-server.md +1158 -441
- package/src/docs/versioned/next/reference/syncdb.md +8 -1
- package/src/docs/versioned/next/reference/ui.md +1271 -27
- package/src/docs/versioned/next/tasks/ai-dev-loop-boost.md +28 -16
- package/src/docs/versioned/next/tutorials/README.md +4 -0
|
@@ -1,65 +1,264 @@
|
|
|
1
1
|
# Set up Terreno MCP
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
stdio server inspects the app, database, logs, Metro, and Redux state.
|
|
3
|
+
Connect your editor to both Terreno MCP servers:
|
|
5
4
|
|
|
6
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
35
|
+
"url": "https://mcp.terreno.app/mcp"
|
|
18
36
|
},
|
|
19
37
|
"terreno-local": {
|
|
20
|
-
"
|
|
21
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
33
|
-
claude mcp add
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
|
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
|
|
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/>
|
|
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
|
|
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
|
-
| `
|
|
75
|
-
| `
|
|
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
|
|
78
|
-
| `read_logs` | local | Merged backend
|
|
79
|
-
| `last_error` | local |
|
|
80
|
-
| `get_rtk_state`
|
|
81
|
-
| `
|
|
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**:
|
|
87
|
-
3. **Hermes single-connection contention**: opening React Native DevTools steals the CDP connection the log tools need.
|
|
88
|
-
4. **
|
|
89
|
-
5. **Hosted server has no rate limiting** (AI5)
|
|
90
|
-
6. **Composition is undocumented**: `expo
|
|
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
|
|
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,
|
|
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
|
|
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 (
|
|
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 `
|
|
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)
|