Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 41 additions & 6 deletions docs/DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,12 @@ cd /Users/nick/git/metacortex
firebase deploy --only firestore:indexes,functions
```

> **Important:** always use `firebase deploy` with the `prod` alias active (confirmed in step 1),
> not `firebase deploy --project my-brain-88870`. Firebase loads `functions/.env.prod` based on
> the **alias** name, not the project ID. Passing the raw project ID silently skips `functions/.env.prod`
> and omits `MCP_CLIENT_PROFILES_JSON` from the deployment, causing all client endpoints to 404.
> Use `firebase deploy --project prod` if you need to pass the project explicitly.

Capture the deployed base URL for `metaCortexMcp`.

The useful production routes are:
Expand Down Expand Up @@ -347,7 +353,36 @@ Expected:

- HTTP `401`

### 3. Browser CORS preflight
### 3. Client profile deployment check

Verify that `MCP_CLIENT_PROFILES_JSON` was bundled into the deployed function by checking
that client endpoints resolve (not 404). A `404` here means the env file was not picked up —
the most common cause is deploying with the raw project ID instead of the `prod` alias.

```bash
curl -s -o /dev/null -w "%{http_code}\n" \
-X OPTIONS "<FUNCTION_BASE_URL>/clients/chatgpt-web/mcp" \
-H "Origin: https://chatgpt.com"
# Expected: 204
```

```bash
curl -s -o /dev/null -w "%{http_code}\n" \
-X OPTIONS "<FUNCTION_BASE_URL>/clients/claude-web/mcp" \
-H "Origin: https://claude.ai"
# Expected: 204
```

If either returns `404`, the client profiles were not deployed. Fix:

```bash
firebase use prod
firebase deploy --only functions
```

### 4. Browser CORS preflight details

Confirm the correct origin headers are returned:

```bash
curl -i \
Expand All @@ -368,7 +403,7 @@ curl -i \
-H "Origin: https://claude.ai"
```

### 4. Authenticated admin MCP smoke test
### 5. Authenticated admin MCP smoke test

```bash
cd /Users/nick/git/metacortex/functions
Expand All @@ -391,7 +426,7 @@ This is the first proof that:
- Firestore writes work
- Firestore vector search works

### 5. Authenticated browser MCP smoke test
### 6. Authenticated browser MCP smoke test

```bash
cd /Users/nick/git/metacortex/functions
Expand All @@ -411,7 +446,7 @@ Repeat the same smoke test against `/clients/claude-web/mcp` with `<CLAUDE_WEB_T

This is the first proof that the 3-tool client-facing browser contract is usable end to end.

### 6. Verify observability events
### 7. Verify observability events

Open Firestore and inspect `memory_events`.

Expand All @@ -426,7 +461,7 @@ Confirm:

Cloud Logging should also contain structured `metaCortexMcp tool event` and `metaCortexMcp request event` entries for the same calls.

### 7. Verify the written document
### 8. Verify the written document

Open Firestore and inspect `memory_vectors`.

Expand All @@ -438,7 +473,7 @@ Confirm:
- `metadata.created_at` and `metadata.updated_at` are present
- the stored content is searchable through `search_context`

### 8. Optional multimodal browser smoke test
### 9. Optional multimodal browser smoke test

```bash
cd /Users/nick/git/metacortex/functions
Expand Down
31 changes: 30 additions & 1 deletion scripts/deploy-session-preflight.sh
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,36 @@ fi
echo
echo "== Firebase project =="
if command -v firebase >/dev/null 2>&1; then
firebase use || true
ACTIVE_PROJECT="$(firebase use 2>/dev/null)"
echo "Active project: ${ACTIVE_PROJECT}"

# Firebase CLI v14+ displays the resolved project ID even when an alias is active, so
# "firebase use" output is ambiguous — it looks identical whether you set the project via
# "firebase use prod" (alias, picks up functions/.env.prod) or "firebase use my-brain-88870"
# (raw project ID, skips functions/.env.prod). Read the configstore directly to check which
# value is actually stored for this directory.
EXPECTED_ALIAS="prod"
STORED_ALIAS="$(node -e "
try {
const os = require('os');
const path = require('path');
const configPath = path.join(os.homedir(), '.config', 'configstore', 'firebase-tools.json');
const data = JSON.parse(require('fs').readFileSync(configPath, 'utf8'));
process.stdout.write(data.activeProjects?.[process.cwd()] ?? '');
} catch { process.stdout.write(''); }
" 2>/dev/null)"

if [[ -z "$STORED_ALIAS" ]]; then
echo "warning: could not read active project alias from Firebase configstore — skipping alias check"
elif [[ "$STORED_ALIAS" != "$EXPECTED_ALIAS" ]]; then
echo "ERROR: active project is set to '${STORED_ALIAS}', not the '${EXPECTED_ALIAS}' alias." >&2
echo " Deploying with the raw project ID skips functions/.env.prod and omits MCP_CLIENT_PROFILES_JSON," >&2
echo " causing all client endpoints to return 404." >&2
echo " Fix: firebase use ${EXPECTED_ALIAS}" >&2
exit 1
else
echo "Alias '${EXPECTED_ALIAS}' confirmed (stored: '${STORED_ALIAS}' → ${ACTIVE_PROJECT})"
fi
else
echo "warning: firebase CLI not installed"
fi
Expand Down
Loading