@everystack/mcp 0.4.3 → 0.4.5

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/dist/index.cjs CHANGED
@@ -21685,7 +21685,7 @@ var RESOURCES = [
21685
21685
  {
21686
21686
  uri: "everystack://logging",
21687
21687
  name: "Logging & Analytics",
21688
- description: "Structured logging: log levels, crash reports, analytics events, S3 log storage, CloudWatch ingestion trigger, client SDK, admin dashboard integration.",
21688
+ description: "Structured logging: log levels, crash reports, analytics events, S3 log storage, CloudWatch ingestion trigger, client SDK, admin dashboard integration. Includes how to debug a 500 from its requestId, since error responses never carry the error text.",
21689
21689
  filename: "logging.md"
21690
21690
  },
21691
21691
  {
@@ -22411,7 +22411,9 @@ function registerDesignSchemaPrompt(server) {
22411
22411
  "Declare each table with `defineModel`, following these conventions:",
22412
22412
  "- UUID primary keys: `id: field.uuid().primaryKey().defaultRandom()`",
22413
22413
  "- Timestamps: `createdAt: field.timestamptz().defaultNow().notNull()`",
22414
- "- Soft delete: a `deletedAt: field.timestamptz()` field opts the table into soft-delete",
22414
+ "- Soft delete: a `deletedAt: field.timestamptz()` field PLUS `softDelete: true` \u2014 the flag is what",
22415
+ " excludes soft-deleted rows from public reads and the data API. The field alone does nothing:",
22416
+ " visibility is declared, never inferred from a column name",
22415
22417
  "- Foreign keys via relations: `field.uuid().references(() => Author)` / `belongsTo`/`hasMany`",
22416
22418
  "- Sensitive columns: `.private()` (hidden from the API); write-guarded: `.readonly()`",
22417
22419
  "- Named exports (PascalCase model var, e.g. `export const Post = defineModel('posts', \u2026)`)",
@@ -23733,7 +23735,7 @@ async function runGovernanceCli(argv) {
23733
23735
  }
23734
23736
 
23735
23737
  // src/index.ts
23736
- var version2 = (true ? "0.4.3" : null) ?? "0.3.0-dev";
23738
+ var version2 = (true ? "0.4.5" : null) ?? "0.3.0-dev";
23737
23739
  var INSTRUCTIONS = [
23738
23740
  "You govern how any agent builds everystack \u2014 a self-hosted application stack for Expo apps on AWS.",
23739
23741
  "Your job is not only to advise but to keep the build on-script: the architecture the maintainer",
package/dist/logging.md CHANGED
@@ -76,6 +76,30 @@ everystack logs:query --stage dev --level error --source api
76
76
  everystack logs:tail --stage dev # Raw CloudWatch output
77
77
  ```
78
78
 
79
+ ## Debugging a 500
80
+
81
+ An error response carries the id that finds the error, never the error itself:
82
+
83
+ ```json
84
+ { "error": "Internal Server Error", "requestId": "kBQF3n8s…" }
85
+ ```
86
+
87
+ Same id as the `x-request-id` header, and the handler logs the full error against it before
88
+ responding. Resolve it with:
89
+
90
+ ```bash
91
+ everystack logs:query --stage production --traceId kBQF3n8s…
92
+ ```
93
+
94
+ It is the CloudFront edge request id, so it also joins to the CDN access logs
95
+ (`x-edge-request-id`). Locally the same log line goes to stdout — no lookup needed.
96
+
97
+ **Never add error text to a response to make debugging easier.** Relation and column names handed
98
+ to an unauthenticated caller are schema disclosure. In particular do not gate it on
99
+ `ENVIRONMENT === 'dev'`: `ENVIRONMENT` is set from `$app.stage`, so that gate asks what someone
100
+ named their stage, not whether the caller is trusted. A test in `@everystack/server` fails the
101
+ build if such a gate is reintroduced. The request id is the debugging path.
102
+
79
103
  ## Plugin
80
104
 
81
105
  ```typescript
package/dist/security.md CHANGED
@@ -212,6 +212,20 @@ Effect: PATCH and DELETE auto-append `WHERE authorId = user.sub`. Returns 404 if
212
212
 
213
213
  Use both. rowOwnership catches IDOR at HTTP level with clear 404. RLS catches it at SQL level as a safety net.
214
214
 
215
+ ## Error responses never carry internals
216
+
217
+ A `500` returns `{ "error": "Internal Server Error", "requestId": "…" }` and nothing else. A
218
+ database error stringifies to `relation "games" does not exist` — schema disclosure to whoever
219
+ made the request.
220
+
221
+ **Never gate disclosure on the stage name.** `ENVIRONMENT` comes from `$app.stage`, so
222
+ `ENVIRONMENT === 'dev'` asks what someone named their stage, not whether the caller is trusted.
223
+ A publicly reachable stage named `dev` is a public stage. A test in `@everystack/server` fails the
224
+ build if such a gate appears in `src/`.
225
+
226
+ Debug from the id instead: `everystack logs:query --traceId <requestId>`. The full error is
227
+ already logged against it.
228
+
215
229
  ## Testing Checklist
216
230
 
217
231
  Before deploying RLS:
@@ -247,6 +261,7 @@ RESET ROLE;
247
261
  - [ ] Write RLS policies per table x role
248
262
  - [ ] Connect as `authenticator` (never use RDS master/superuser in production)
249
263
  - [ ] Test: SET ROLE authenticated; SELECT returns only expected rows
264
+ - [ ] Test: a 500 returns only `error` and `requestId` — no relation or column names
250
265
 
251
266
  ### Handler
252
267
  - [ ] `exposedTables` whitelist (404 for unlisted tables)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@everystack/mcp",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "Governance layer that governs how any agent builds everystack — grounding, cheat gates, and Model-aware tooling over MCP",
5
5
  "license": "AGPL-3.0-only",
6
6
  "author": "Scalable Technology, Inc. <licensing@scalable.technology>",
@@ -40,9 +40,9 @@
40
40
  "tsx": "4.21.0",
41
41
  "typescript": "5.9.3",
42
42
  "zod": "3.25.67",
43
- "@everystack/cli": "0.4.38",
44
- "@everystack/model": "0.4.5",
45
- "@everystack/server": "0.4.15"
43
+ "@everystack/cli": "0.4.48",
44
+ "@everystack/server": "0.4.18",
45
+ "@everystack/model": "0.4.12"
46
46
  },
47
47
  "scripts": {
48
48
  "test": "jest",
@@ -41,7 +41,9 @@ export function registerDesignSchemaPrompt(server: McpServer): void {
41
41
  'Declare each table with `defineModel`, following these conventions:',
42
42
  '- UUID primary keys: `id: field.uuid().primaryKey().defaultRandom()`',
43
43
  '- Timestamps: `createdAt: field.timestamptz().defaultNow().notNull()`',
44
- '- Soft delete: a `deletedAt: field.timestamptz()` field opts the table into soft-delete',
44
+ '- Soft delete: a `deletedAt: field.timestamptz()` field PLUS `softDelete: true` — the flag is what',
45
+ ' excludes soft-deleted rows from public reads and the data API. The field alone does nothing:',
46
+ ' visibility is declared, never inferred from a column name',
45
47
  '- Foreign keys via relations: `field.uuid().references(() => Author)` / `belongsTo`/`hasMany`',
46
48
  '- Sensitive columns: `.private()` (hidden from the API); write-guarded: `.readonly()`',
47
49
  '- Named exports (PascalCase model var, e.g. `export const Post = defineModel(\'posts\', …)`)',
@@ -179,7 +179,7 @@ const RESOURCES: ResourceDef[] = [
179
179
  uri: 'everystack://logging',
180
180
  name: 'Logging & Analytics',
181
181
  description:
182
- 'Structured logging: log levels, crash reports, analytics events, S3 log storage, CloudWatch ingestion trigger, client SDK, admin dashboard integration.',
182
+ 'Structured logging: log levels, crash reports, analytics events, S3 log storage, CloudWatch ingestion trigger, client SDK, admin dashboard integration. Includes how to debug a 500 from its requestId, since error responses never carry the error text.',
183
183
  filename: 'logging.md',
184
184
  },
185
185
  {
@@ -76,6 +76,30 @@ everystack logs:query --stage dev --level error --source api
76
76
  everystack logs:tail --stage dev # Raw CloudWatch output
77
77
  ```
78
78
 
79
+ ## Debugging a 500
80
+
81
+ An error response carries the id that finds the error, never the error itself:
82
+
83
+ ```json
84
+ { "error": "Internal Server Error", "requestId": "kBQF3n8s…" }
85
+ ```
86
+
87
+ Same id as the `x-request-id` header, and the handler logs the full error against it before
88
+ responding. Resolve it with:
89
+
90
+ ```bash
91
+ everystack logs:query --stage production --traceId kBQF3n8s…
92
+ ```
93
+
94
+ It is the CloudFront edge request id, so it also joins to the CDN access logs
95
+ (`x-edge-request-id`). Locally the same log line goes to stdout — no lookup needed.
96
+
97
+ **Never add error text to a response to make debugging easier.** Relation and column names handed
98
+ to an unauthenticated caller are schema disclosure. In particular do not gate it on
99
+ `ENVIRONMENT === 'dev'`: `ENVIRONMENT` is set from `$app.stage`, so that gate asks what someone
100
+ named their stage, not whether the caller is trusted. A test in `@everystack/server` fails the
101
+ build if such a gate is reintroduced. The request id is the debugging path.
102
+
79
103
  ## Plugin
80
104
 
81
105
  ```typescript
@@ -212,6 +212,20 @@ Effect: PATCH and DELETE auto-append `WHERE authorId = user.sub`. Returns 404 if
212
212
 
213
213
  Use both. rowOwnership catches IDOR at HTTP level with clear 404. RLS catches it at SQL level as a safety net.
214
214
 
215
+ ## Error responses never carry internals
216
+
217
+ A `500` returns `{ "error": "Internal Server Error", "requestId": "…" }` and nothing else. A
218
+ database error stringifies to `relation "games" does not exist` — schema disclosure to whoever
219
+ made the request.
220
+
221
+ **Never gate disclosure on the stage name.** `ENVIRONMENT` comes from `$app.stage`, so
222
+ `ENVIRONMENT === 'dev'` asks what someone named their stage, not whether the caller is trusted.
223
+ A publicly reachable stage named `dev` is a public stage. A test in `@everystack/server` fails the
224
+ build if such a gate appears in `src/`.
225
+
226
+ Debug from the id instead: `everystack logs:query --traceId <requestId>`. The full error is
227
+ already logged against it.
228
+
215
229
  ## Testing Checklist
216
230
 
217
231
  Before deploying RLS:
@@ -247,6 +261,7 @@ RESET ROLE;
247
261
  - [ ] Write RLS policies per table x role
248
262
  - [ ] Connect as `authenticator` (never use RDS master/superuser in production)
249
263
  - [ ] Test: SET ROLE authenticated; SELECT returns only expected rows
264
+ - [ ] Test: a 500 returns only `error` and `requestId` — no relation or column names
250
265
 
251
266
  ### Handler
252
267
  - [ ] `exposedTables` whitelist (404 for unlisted tables)