@everystack/mcp 0.2.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 (40) hide show
  1. package/README.md +100 -0
  2. package/package.json +39 -0
  3. package/src/index.ts +58 -0
  4. package/src/prompts/add-feature.ts +163 -0
  5. package/src/prompts/debug.ts +136 -0
  6. package/src/prompts/deploy.ts +131 -0
  7. package/src/prompts/design-schema.ts +104 -0
  8. package/src/prompts/index.ts +16 -0
  9. package/src/prompts/new-app.ts +211 -0
  10. package/src/prompts/secure.ts +231 -0
  11. package/src/resources/adding-database.md +169 -0
  12. package/src/resources/admin.md +81 -0
  13. package/src/resources/auth.md +115 -0
  14. package/src/resources/aws-setup.md +173 -0
  15. package/src/resources/cli.md +108 -0
  16. package/src/resources/client-api.md +145 -0
  17. package/src/resources/core.md +196 -0
  18. package/src/resources/deployment.md +146 -0
  19. package/src/resources/events.md +87 -0
  20. package/src/resources/first-run.md +100 -0
  21. package/src/resources/getting-started.md +75 -0
  22. package/src/resources/handler-options.md +114 -0
  23. package/src/resources/images.md +73 -0
  24. package/src/resources/index.ts +224 -0
  25. package/src/resources/jobs.md +97 -0
  26. package/src/resources/logging.md +91 -0
  27. package/src/resources/plugins.md +68 -0
  28. package/src/resources/project-claude-md.md +127 -0
  29. package/src/resources/query-protocol.md +129 -0
  30. package/src/resources/schema-patterns.md +167 -0
  31. package/src/resources/security-device.md +99 -0
  32. package/src/resources/security.md +270 -0
  33. package/src/resources/ssr.md +82 -0
  34. package/src/resources/storage.md +63 -0
  35. package/src/resources/testing.md +118 -0
  36. package/src/tools/check-environment.ts +319 -0
  37. package/src/tools/index.ts +58 -0
  38. package/src/tools/project-status.ts +183 -0
  39. package/src/tools/project-validate.ts +369 -0
  40. package/src/tools/schema-analyze.ts +410 -0
@@ -0,0 +1,75 @@
1
+ # What is everystack?
2
+
3
+ everystack helps you build apps. Real apps that work on iPhones, Android phones, tablets, computers, and the web — all from the same code.
4
+
5
+ You describe what you want. Claude helps you build it. everystack provides the building blocks.
6
+
7
+ **A note about difficulty:** Building software is hard. Professional engineers are paid well to do this, and projects often take months or years. Claude and everystack make it much more accessible, but you are still building real software with real infrastructure. Things will break. You will hit errors you don't understand. That's normal. The key is to keep going, ask questions, and learn as you go.
8
+
9
+ ## How it works
10
+
11
+ You start simple: a running app on your screen. Then you build from there.
12
+
13
+ Every app starts the same way — a basic Expo app that works on phones, tablets, and the web. You build the screens, the navigation, the look and feel. Everything is visual and immediate.
14
+
15
+ When your app needs more — user accounts, saved data, file uploads — you add those capabilities one at a time. You never throw away what you already built. Your app grows with you.
16
+
17
+ ## What you need to get started
18
+
19
+ These are tools that run on your computer. Claude will help you install each one.
20
+
21
+ **Node.js** — Runs your code. Your app is written in TypeScript (a programming language). Node.js is the engine that makes it work, like how a car needs an engine to drive.
22
+ - Without it: Nothing runs.
23
+
24
+ **git** — Tracks every change you make to your code. Like an unlimited undo button for your entire project. You can always go back to any previous version.
25
+ - Without it: You cannot track changes or undo mistakes.
26
+
27
+ **pnpm** (recommended) — A faster way to install code libraries your app depends on. Recommended but Claude can work without it.
28
+
29
+ That's it. Those three tools are all you need to create an app and see it running on your computer.
30
+
31
+ ### When your app needs a database (later)
32
+
33
+ If your app needs user accounts or saved data, you'll add a database. This is not needed to start — only when a feature demands it.
34
+
35
+ **PostgreSQL** — A database that stores your app's data: users, posts, recipes, or whatever your app needs. Like a spreadsheet that your app reads and writes automatically. Read everystack://adding-database when you're ready for this step.
36
+
37
+ ### To deploy to the internet (later)
38
+
39
+ You don't need these right away. Install them when you're ready to put your app online so other people can use it.
40
+
41
+ **AWS account + AWS CLI** — AWS (Amazon Web Services) is where your app lives on the internet. Other people's computers run your app so anyone can use it. The AWS CLI is a tool that lets Claude talk to AWS from your computer.
42
+ - Without it: Your app only works on your computer. Nobody else can use it.
43
+ - Setting up AWS requires a credit card for verification. AWS has a free tier for the first 12 months. You control all costs and can delete everything at any time.
44
+
45
+ **AWS credentials** — A password file that proves your computer is allowed to deploy to your AWS account. You create this once during setup.
46
+ - Without them: AWS will reject all deploy commands.
47
+ - New to AWS? Read everystack://aws-setup for a complete walkthrough of creating an account and setting up credentials.
48
+
49
+ ## The path from idea to running app
50
+
51
+ 1. **You describe your idea.** "I want to build a recipe sharing app."
52
+ 2. **Claude checks your computer.** Runs a tool to see what's installed and what's missing.
53
+ 3. **Claude helps you install anything missing.** Step by step, one tool at a time. Each one explained before you install it.
54
+ 4. **Claude creates your app.** A stock Expo app with the everystack building blocks installed.
55
+ 5. **You see it running on your computer.** Your app opens in a browser. You can change things and see updates instantly. Read everystack://first-run for details on this step.
56
+ 6. **You build together.** Describe what you want — screens, buttons, colors, layout. Claude builds it. You see changes in real time. This is where most of the work happens.
57
+ 7. **Your app grows when it needs to.** When a feature needs user accounts or saved data, Claude helps you add a database. When you need file uploads, you add that too. One thing at a time.
58
+ 8. **When you're ready, you deploy.** Your app gets a real URL that anyone can visit. This is a separate step — there's no rush.
59
+
60
+ ## Common questions
61
+
62
+ **Do I need to know how to code?**
63
+ Not to start. Claude writes the code and explains what it's doing. But you're building real software — the same kind that teams of engineers get paid to build. Things will break. You'll need to learn as you go. The more you understand, the better your app will be.
64
+
65
+ **How much does AWS cost?**
66
+ For a small app with low traffic, typically under $5/month for a static site and around $20/month once you add a database (the database is the main cost). AWS has a free tier for the first 12 months that covers most of what everystack uses. You can build and run locally for free with no AWS account at all.
67
+
68
+ **Can I change things later?**
69
+ Yes. everystack is built for this. Start with a simple app, add user accounts when you need them, add file uploads when you need them. You never throw away what you already built.
70
+
71
+ **What if something goes wrong?**
72
+ Claude can debug it. everystack has built-in tools that check your project for common mistakes and security issues. And git tracks every change, so you can always go back. Expect things to go wrong — that's part of building software. The tools are here to help you recover.
73
+
74
+ **Do I need a Mac?**
75
+ For now, yes. everystack's setup tools are designed for macOS. Windows and Linux support may come later.
@@ -0,0 +1,114 @@
1
+ # Handler Options Reference
2
+
3
+ > Complete reference for `createHandler(db, schema, options)` from `@everystack/api/handler`.
4
+
5
+ ## When to Use
6
+ Read this when configuring the PostgREST handler for a V2+ app. Every option is optional -- start minimal and add as needed.
7
+
8
+ ## Setup
9
+
10
+ ```typescript
11
+ import { createHandler } from '@everystack/api/handler';
12
+ import * as schema from '../db/schema';
13
+
14
+ const handler = createHandler(db, schema, {
15
+ basePath: '/api', // Strip this prefix from incoming URLs
16
+ // ... options below
17
+ });
18
+ ```
19
+
20
+ Returns `(request: Request) => Promise<Response>`.
21
+
22
+ ## Options
23
+
24
+ ### auth
25
+ ```typescript
26
+ auth: {
27
+ verifyToken: async (token: string) => payload | null, // Required for auth
28
+ publicRoutes: ['GET'], // Methods that skip token verification
29
+ publicRpc: ['health'], // RPC functions that skip all auth (token + client)
30
+ roleHierarchy: ['public', 'authenticated', 'admin'], // For RPC role gates
31
+ roleField: 'role', // JWT field containing user's role
32
+ onAuthenticated: (user) => {}, // Callback after successful auth
33
+ // Client credentials (two-tier auth)
34
+ verifyClient: async (clientId, clientSecret, referer?) => client | null,
35
+ clientHeaders: { id: 'X-Client-Id', secret: 'X-Client-Secret' },
36
+ onClientAuthenticated: (client) => {},
37
+ }
38
+ ```
39
+
40
+ ### pgSettings (RLS)
41
+ ```typescript
42
+ pgSettings: (user, client) => ({
43
+ role: user?.role === 'admin' ? 'admin' : user ? 'authenticated' : 'anon',
44
+ 'request.jwt.claims': JSON.stringify(user || { role: 'anon' }),
45
+ 'app.user_id': String(user?.sub || ''),
46
+ })
47
+ ```
48
+ The `role` key triggers `SET LOCAL ROLE`. All other keys use `set_config(key, value, true)`. Everything is LOCAL scope (resets when transaction ends).
49
+
50
+ ### relations
51
+ ```typescript
52
+ relations: {
53
+ posts: {
54
+ author: { table: 'users', from: 'authorId', to: 'id' }, // many-to-one
55
+ comments: { table: 'comments', from: 'id', to: 'postId', many: true }, // one-to-many
56
+ },
57
+ }
58
+ ```
59
+ Enables `?select=*,author(*)` embedding. Resolved via batched `WHERE IN` (no N+1).
60
+
61
+ ### rpc
62
+ ```typescript
63
+ rpc: {
64
+ health: async (body) => ({ status: 'ok' }), // Function syntax
65
+ timeline: { fn: async (body, user) => {}, role: 'authenticated' }, // Object + role
66
+ admin_stats: { fn: async (body, user) => {}, role: 'admin' },
67
+ }
68
+ ```
69
+ Function syntax uses publicRpc/publicRoutes rules. Object syntax enforces role requirement.
70
+
71
+ ### hooks
72
+ ```typescript
73
+ hooks: {
74
+ posts: {
75
+ beforeCreate: async (body, user, client) => ({ ...body, authorId: user?.sub }),
76
+ afterCreate: async (row, user, client) => {},
77
+ beforeUpdate: async (body, user, client) => body,
78
+ afterUpdate: async (rows, user, client) => {},
79
+ beforeDelete: async (user, client) => {},
80
+ afterDelete: async (rows, user, client) => {},
81
+ },
82
+ }
83
+ ```
84
+ `beforeCreate`/`beforeUpdate` can modify the body by returning a new object.
85
+
86
+ ### Access Control
87
+ ```typescript
88
+ exposedTables: ['posts', 'profiles'], // 404 for unlisted tables
89
+ hiddenColumns: { users: ['passwordHash'] }, // Strip from all responses
90
+ protectedFields: { profiles: ['role'] }, // Strip from incoming writes
91
+ rowOwnership: { posts: { column: 'authorId', userField: 'sub' } }, // Scope writes to owner
92
+ ```
93
+
94
+ ### Safety Limits
95
+ ```typescript
96
+ maxEmbedDepth: 3, // Max relation nesting depth (default: 3)
97
+ maxLimit: 1000, // Max ?limit= value (default: 10000)
98
+ ```
99
+
100
+ ### Other
101
+ ```typescript
102
+ softDelete: { column: 'deletedAt', tables: ['posts'] }, // DELETE -> UPDATE SET deletedAt
103
+ naming: 'snake_case', // Response key format ('camelCase' default)
104
+ ```
105
+
106
+ ## Gotchas
107
+
108
+ - `pgSettings` wraps every query in a transaction. Without it, queries execute directly (no RLS).
109
+ - `hiddenColumns` strips AFTER query execution. Columns are still in the SQL result, just removed from JSON.
110
+ - `protectedFields` strips BEFORE hooks run. Hooks never see protected fields.
111
+ - `exposedTables` doesn't affect RPC endpoints.
112
+ - `rowOwnership` only affects PATCH and DELETE. Reads are governed by RLS.
113
+ - The `role` value in pgSettings is validated against `^[a-zA-Z_][a-zA-Z0-9_]*$`.
114
+ - DELETE without filters returns 400 (safety). Always include at least one filter.
@@ -0,0 +1,73 @@
1
+ # Image Processing
2
+
3
+ > On-demand Sharp image processing on Lambda. Import from `@everystack/images`.
4
+
5
+ ## When to Use
6
+ Read this when adding image resizing, format conversion, or variant generation (V3).
7
+
8
+ ## Setup
9
+
10
+ ```typescript
11
+ // server/image.ts
12
+ import { createImageHandler } from '@everystack/server/image';
13
+
14
+ export const handler = createImageHandler({
15
+ bucket: Resource.Media.name,
16
+ pathPrefix: '/media/',
17
+ });
18
+ ```
19
+
20
+ ## URL-based Processing
21
+
22
+ Images are processed on-the-fly via query parameters:
23
+
24
+ ```
25
+ /media/photo.jpg?w=400&h=300&fit=cover&fm=webp&q=80
26
+ ```
27
+
28
+ | Parameter | Description | Values |
29
+ |-----------|-------------|--------|
30
+ | `w` | Width | pixels |
31
+ | `h` | Height | pixels |
32
+ | `fit` | Resize mode | `cover`, `contain`, `fill`, `inside`, `outside` |
33
+ | `fm` | Output format | `webp`, `avif`, `jpeg`, `png` |
34
+ | `q` | Quality | 1-100 |
35
+
36
+ ## Variant Generation
37
+
38
+ Pre-generate variants via background jobs:
39
+
40
+ ```typescript
41
+ import { generateVariants } from '@everystack/images/jobs';
42
+
43
+ await publishJob('image:process', {
44
+ key: 'uploads/photo.jpg',
45
+ variants: [
46
+ { name: 'thumb', width: 150, height: 150, fit: 'cover' },
47
+ { name: 'large', width: 1200, format: 'webp', quality: 85 },
48
+ ],
49
+ });
50
+ ```
51
+
52
+ ## EXIF Extraction
53
+
54
+ ```typescript
55
+ import { extractExif } from '@everystack/images';
56
+
57
+ const exif = await extractExif(buffer);
58
+ // { width, height, orientation, gps, camera, ... }
59
+ ```
60
+
61
+ ## Schema
62
+
63
+ ```typescript
64
+ import { imagesSchema } from '@everystack/images/schema';
65
+ // Adds: image_variants table tracking generated variants
66
+ ```
67
+
68
+ ## Gotchas
69
+
70
+ - Sharp runs on Lambda ARM64 (uses Lambda layer or bundled binary)
71
+ - First request for a variant is slow (processing), subsequent are cached
72
+ - CloudFront caches processed images (set appropriate Cache-Control)
73
+ - AVIF encoding is slower than WebP but produces smaller files
@@ -0,0 +1,224 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join, dirname } from 'node:path';
3
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
+
5
+ // Resolve the directory containing resource files.
6
+ // tsx (our runtime) polyfills __dirname in ESM. ts-jest uses CJS where __dirname is native.
7
+ // We use a dynamic eval to avoid import.meta.url appearing in CJS output (which would throw).
8
+ function getResourcesDir(): string {
9
+ // In CJS (ts-jest), __dirname is a global
10
+ try {
11
+ return (globalThis as Record<string, unknown>).__dirname as string
12
+ || eval('__dirname') as string;
13
+ } catch {
14
+ // In pure ESM, fall back to import.meta.url
15
+ const { fileURLToPath } = require('node:url');
16
+ return dirname(fileURLToPath(eval('import.meta.url')));
17
+ }
18
+ }
19
+
20
+ const RESOURCES_DIR = getResourcesDir();
21
+
22
+ function loadResource(filename: string): string {
23
+ return readFileSync(join(RESOURCES_DIR, filename), 'utf-8');
24
+ }
25
+
26
+ interface ResourceDef {
27
+ uri: string;
28
+ name: string;
29
+ description: string;
30
+ filename: string;
31
+ }
32
+
33
+ const RESOURCES: ResourceDef[] = [
34
+ // Beginner — plain English intro, read first for new users
35
+ {
36
+ uri: 'everystack://getting-started',
37
+ name: 'Getting Started (Beginners)',
38
+ description:
39
+ 'Plain English intro for complete beginners. What everystack is, what the tiers mean, what each prerequisite is and why. Read this FIRST for users with no programming experience or no existing project.',
40
+ filename: 'getting-started.md',
41
+ },
42
+
43
+ // Beginner — AWS account and credential setup
44
+ {
45
+ uri: 'everystack://aws-setup',
46
+ name: 'AWS Setup (Beginners)',
47
+ description:
48
+ 'Step-by-step AWS account creation and IAM credential setup for beginners. Read when check_environment reports missing AWS credentials.',
49
+ filename: 'aws-setup.md',
50
+ },
51
+
52
+ // Beginner — first local run walkthrough
53
+ {
54
+ uri: 'everystack://first-run',
55
+ name: 'First Run (Beginners)',
56
+ description:
57
+ 'What happens when you run your app locally for the first time. Explains Metro bundler, hot reload, opening in browser or phone, and common first-run errors. Read after scaffolding a new project.',
58
+ filename: 'first-run.md',
59
+ },
60
+
61
+ // Beginner — V2 transition guide (adding database to existing app)
62
+ {
63
+ uri: 'everystack://adding-database',
64
+ name: 'Adding a Database (V2 Transition)',
65
+ description:
66
+ 'Guide for adding PostgreSQL, API handler, and authentication to an existing Expo app. Read this when a feature needs data persistence or user accounts. Covers PostgreSQL setup, V2 package installation, schema creation, handler config, auth flow, migrations, and RLS security.',
67
+ filename: 'adding-database.md',
68
+ },
69
+
70
+ // Core — read these first (for developers)
71
+ {
72
+ uri: 'everystack://core',
73
+ name: 'everystack Core Architecture',
74
+ description:
75
+ 'Architecture, package map, V1-V2-V3 tiers, key patterns, project conventions, handler overview, CLI commands. Read this first.',
76
+ filename: 'core.md',
77
+ },
78
+ {
79
+ uri: 'everystack://security',
80
+ name: 'everystack Security',
81
+ description:
82
+ 'Three-layer security model (Edge/API/Database), AWS IAM profiles (Create/Manage/Deploy), RLS guide with copy-paste policies, deployment checklist. Read before any auth or deployment guidance.',
83
+ filename: 'security.md',
84
+ },
85
+
86
+ // Detail — load on demand
87
+ {
88
+ uri: 'everystack://handler-options',
89
+ name: 'Handler Options Reference',
90
+ description:
91
+ 'Complete createHandler() options: auth, relations, rpc, hooks, pgSettings, softDelete, naming, exposedTables, hiddenColumns, protectedFields, rowOwnership, cache.',
92
+ filename: 'handler-options.md',
93
+ },
94
+ {
95
+ uri: 'everystack://query-protocol',
96
+ name: 'Query Protocol',
97
+ description:
98
+ 'PostgREST query protocol: filters (eq, neq, gt, lt, like, ilike, is, in), negation, logical groups (or, and), column selection, relation embedding, ordering, pagination, aggregates, JSON path filtering.',
99
+ filename: 'query-protocol.md',
100
+ },
101
+ {
102
+ uri: 'everystack://client-api',
103
+ name: 'Client API',
104
+ description:
105
+ 'Typed client: createClient(), query builder (.from, .eq, .select, .order, .limit), mutations (.insert, .update, .delete), token refresh, error handling.',
106
+ filename: 'client-api.md',
107
+ },
108
+ {
109
+ uri: 'everystack://auth',
110
+ name: 'Authentication',
111
+ description:
112
+ 'JWT auth: createAuthHandlers(), signup/signin/refresh flows, HS256 edge verification, OAuth, password hashing, token lifecycle, AuthProvider React context.',
113
+ filename: 'auth.md',
114
+ },
115
+ {
116
+ uri: 'everystack://schema-patterns',
117
+ name: 'Schema Design Patterns',
118
+ description:
119
+ 'Drizzle schema design: pgTable, column types, relations, indexes, timestamps, soft delete, UUID vs serial, migration workflow, drizzle-kit commands.',
120
+ filename: 'schema-patterns.md',
121
+ },
122
+ {
123
+ uri: 'everystack://deployment',
124
+ name: 'Deployment Guide',
125
+ description:
126
+ 'SST deployment: sst.config.ts setup, secrets, stages (dev/production), CloudFront, Lambda configuration, VPC, RDS Aurora Serverless, resource linking.',
127
+ filename: 'deployment.md',
128
+ },
129
+ {
130
+ uri: 'everystack://admin',
131
+ name: 'Admin Dashboard',
132
+ description:
133
+ 'Declarative admin: AdminRoot, AdminLayout, resource config, field types, EverystackAdapter, presets, custom widgets, navigation.',
134
+ filename: 'admin.md',
135
+ },
136
+ {
137
+ uri: 'everystack://jobs',
138
+ name: 'Background Jobs',
139
+ description:
140
+ 'SQS background workers: createWorkerHandler, publishJob, job types, dead letter queue, cron scheduling, Postgres materialization adapter.',
141
+ filename: 'jobs.md',
142
+ },
143
+ {
144
+ uri: 'everystack://storage',
145
+ name: 'File Storage',
146
+ description:
147
+ 'S3 file storage: createStorageHandler, presigned uploads, MIME validation, CDN delivery, ownership enforcement, client upload flow.',
148
+ filename: 'storage.md',
149
+ },
150
+ {
151
+ uri: 'everystack://logging',
152
+ name: 'Logging & Analytics',
153
+ description:
154
+ 'Structured logging: log levels, crash reports, analytics events, S3 log storage, CloudWatch ingestion trigger, client SDK, admin dashboard integration.',
155
+ filename: 'logging.md',
156
+ },
157
+ {
158
+ uri: 'everystack://security-device',
159
+ name: 'Device Security',
160
+ description:
161
+ 'Device attestation: Apple App Attest, Google Play Integrity, RS256 device keys, biometric auth, certificate pinning.',
162
+ filename: 'security-device.md',
163
+ },
164
+ {
165
+ uri: 'everystack://testing',
166
+ name: 'Testing Patterns',
167
+ description:
168
+ 'Testing conventions: Jest setup, TDD workflow, test file structure, mocking patterns (ESM, sharp, AWS SDK), template database isolation, integration tests.',
169
+ filename: 'testing.md',
170
+ },
171
+ {
172
+ uri: 'everystack://plugins',
173
+ name: 'Plugin Architecture',
174
+ description:
175
+ 'Plugin system: createPluginLambdaHandler, Plugin type, PluginContext, composing handlers from multiple packages, plugin registration order.',
176
+ filename: 'plugins.md',
177
+ },
178
+ {
179
+ uri: 'everystack://ssr',
180
+ name: 'Server-Side Rendering',
181
+ description:
182
+ 'SSR: getWebHandler, direct Drizzle queries in loaders, JSON-LD structured data, OG meta tags, cache headers, hydration debugging.',
183
+ filename: 'ssr.md',
184
+ },
185
+ {
186
+ uri: 'everystack://images',
187
+ name: 'Image Processing',
188
+ description:
189
+ 'Sharp image processing: createImageHandler, on-demand resizing, format conversion, EXIF extraction, variant generation, CDN delivery.',
190
+ filename: 'images.md',
191
+ },
192
+ {
193
+ uri: 'everystack://events',
194
+ name: 'Events & WebSocket',
195
+ description:
196
+ 'Real-time events: PostgreSQL LISTEN/NOTIFY, WebSocket fan-out, Lambda event bridge, client useSignal hook, table change notifications.',
197
+ filename: 'events.md',
198
+ },
199
+ {
200
+ uri: 'everystack://cli',
201
+ name: 'CLI Reference',
202
+ description:
203
+ 'Full CLI command reference: update, db:migrate, db:seed, db:psql, console, logs:errors, logs:tail, logs:query, cache:purge, certs, channels, diag, analyze:ssr.',
204
+ filename: 'cli.md',
205
+ },
206
+ {
207
+ uri: 'everystack://project-claude-md',
208
+ name: 'Project CLAUDE.md Template',
209
+ description:
210
+ 'Template for a project-level CLAUDE.md file. Read this and adapt it when scaffolding a new everystack app. Replace placeholders ({PROJECT_NAME}, {ONE_LINE_DESCRIPTION}, {ANNOTATED_DIRECTORY_TREE}) with actual project details.',
211
+ filename: 'project-claude-md.md',
212
+ },
213
+ ];
214
+
215
+ export function registerResources(server: McpServer): void {
216
+ for (const r of RESOURCES) {
217
+ const content = loadResource(r.filename);
218
+ server.resource(r.name, r.uri, { mimeType: 'text/markdown' }, async () => ({
219
+ contents: [{ uri: r.uri, mimeType: 'text/markdown' as const, text: content }],
220
+ }));
221
+ }
222
+ }
223
+
224
+ export { RESOURCES, loadResource };
@@ -0,0 +1,97 @@
1
+ # Background Jobs
2
+
3
+ > SQS background workers for everystack apps. Import from `@everystack/jobs`.
4
+
5
+ ## When to Use
6
+ Read this when adding background processing (V3): email sending, image processing, analytics aggregation, etc.
7
+
8
+ ## Setup
9
+
10
+ ### Infrastructure
11
+ ```typescript
12
+ // sst.config.ts
13
+ const dlq = new sst.aws.Queue('DeadLetterQueue');
14
+ const jobs = new sst.aws.Queue('Jobs', { dlq: dlq.arn });
15
+
16
+ const worker = new sst.aws.Function('Worker', {
17
+ handler: 'server/worker.handler',
18
+ link: [database, jobs, media],
19
+ vpc,
20
+ });
21
+
22
+ jobs.subscribe(worker.arn);
23
+ ```
24
+
25
+ ### Worker Handler
26
+ ```typescript
27
+ // server/worker.ts
28
+ import { createWorkerHandler } from '@everystack/server/worker';
29
+
30
+ export const handler = createWorkerHandler(async () => ({
31
+ 'image:process': async (payload) => {
32
+ // payload: { imageId, variants: ['thumb', 'large'] }
33
+ },
34
+ 'email:send': async (payload) => {
35
+ // payload: { to, subject, body }
36
+ },
37
+ 'analytics:aggregate': async (payload) => {
38
+ // payload: { date, metrics: ['pageviews', 'signups'] }
39
+ },
40
+ }));
41
+ ```
42
+
43
+ ### Dispatching Jobs
44
+ ```typescript
45
+ import { publishJob } from '@everystack/jobs';
46
+
47
+ await publishJob('image:process', {
48
+ imageId: 'abc-123',
49
+ variants: ['thumb', 'large'],
50
+ });
51
+ ```
52
+
53
+ ## Client SDK
54
+
55
+ ```typescript
56
+ import { createJobClient } from '@everystack/jobs/client';
57
+
58
+ const jobs = createJobClient({ baseUrl: '/api' });
59
+ await jobs.submit('email:send', { to: 'user@example.com', subject: 'Welcome' });
60
+ ```
61
+
62
+ ## SQS Adapter
63
+
64
+ ```typescript
65
+ import { createSqsAdapter } from '@everystack/jobs';
66
+
67
+ const adapter = createSqsAdapter({
68
+ queueUrl: Resource.Jobs.url,
69
+ region: 'us-east-1',
70
+ });
71
+ ```
72
+
73
+ Progressive dispatch: starts with direct function calls, moves to SQS when you need async processing.
74
+
75
+ ## Postgres Materialization
76
+
77
+ Optional: materialize job state to PostgreSQL for dashboard visibility:
78
+
79
+ ```typescript
80
+ import { jobsSchema } from '@everystack/jobs/schema';
81
+ // Adds: jobs table with status, type, payload, result, timestamps
82
+ ```
83
+
84
+ ## Plugin
85
+
86
+ ```typescript
87
+ import { jobsPlugin } from '@everystack/jobs/plugin';
88
+ // Adds job dispatch routes to the handler
89
+ ```
90
+
91
+ ## Gotchas
92
+
93
+ - Workers run in a separate Lambda (not the API Lambda)
94
+ - Dead letter queue catches failed jobs after max retries
95
+ - Job payloads must be JSON-serializable
96
+ - SQS has a 256KB message size limit
97
+ - Workers should be idempotent (SQS delivers at-least-once)
@@ -0,0 +1,91 @@
1
+ # Logging & Analytics
2
+
3
+ > Structured logging, crash reports, and analytics. Import from `@everystack/logging`.
4
+
5
+ ## When to Use
6
+ Read this when adding observability to a V2+ app.
7
+
8
+ ## Setup
9
+
10
+ ### Server-side Logging
11
+ ```typescript
12
+ import { createLogSink } from '@everystack/logging';
13
+
14
+ const logSink = createLogSink({
15
+ storage: 's3',
16
+ bucket: Resource.LogsBucket.name,
17
+ });
18
+
19
+ // Pass to Lambda handler
20
+ createLambdaHandler({ logSink, /* ... */ });
21
+ ```
22
+
23
+ ### Client-side SDK
24
+ ```typescript
25
+ import { createLogClient } from '@everystack/logging/client';
26
+
27
+ const logger = createLogClient({
28
+ baseUrl: '/api/logs',
29
+ batchSize: 10,
30
+ flushInterval: 30000,
31
+ });
32
+
33
+ logger.info('Page viewed', { page: '/home' });
34
+ logger.error('Payment failed', { error, userId });
35
+ logger.event('button_click', { button: 'signup' });
36
+ ```
37
+
38
+ ## Log Levels
39
+
40
+ | Level | Use case |
41
+ |-------|----------|
42
+ | `debug` | Development-only, verbose details |
43
+ | `info` | Normal operations, user actions |
44
+ | `warn` | Degraded state, retries, fallbacks |
45
+ | `error` | Failed operations, caught exceptions |
46
+ | `fatal` | Unrecoverable errors, crash reports |
47
+
48
+ ## Schema
49
+
50
+ ```typescript
51
+ import { loggingSchema } from '@everystack/logging/schema';
52
+ // Adds: logs table with level, source, message, data, traceId, userId, deviceId, etc.
53
+ ```
54
+
55
+ Include in your handler's schema for database-backed log querying.
56
+
57
+ ## CloudWatch Trigger
58
+
59
+ ```typescript
60
+ import { createLogIngestionHandler } from '@everystack/logging/trigger';
61
+ // Processes CloudWatch log events, extracts structured data, stores in S3/DB
62
+ ```
63
+
64
+ ## Admin Integration
65
+
66
+ ```typescript
67
+ import { loggingAdminConfig } from '@everystack/logging/admin';
68
+ // Adds log viewer widget to admin dashboard
69
+ ```
70
+
71
+ ## CLI Integration
72
+
73
+ ```bash
74
+ everystack logs:errors --stage dev # Recent errors (DB -> S3 fallback)
75
+ everystack logs:query --stage dev --level error --source api
76
+ everystack logs:tail --stage dev # Raw CloudWatch output
77
+ ```
78
+
79
+ ## Plugin
80
+
81
+ ```typescript
82
+ import { loggingPlugin } from '@everystack/logging/plugin';
83
+ // Adds log ingestion routes and log query RPC
84
+ ```
85
+
86
+ ## Gotchas
87
+
88
+ - Logs are stored in S3 (cheap, durable) with optional DB materialization
89
+ - Client SDK batches logs and flushes periodically (not per-event)
90
+ - `logs:errors` queries DB first, falls back to S3 if logs table doesn't exist
91
+ - `logs:tail` reads CloudWatch (Lambda container output), not application logs