Conversation
Represent expected name conflicts as serializable kernel outcomes so Cloudflare RPC does not discard conflict metadata. Create initial relations in the same kernel command to avoid partial workspace mutations.
Verify access tokens through the typed Better Auth API, preserve JWKS infrastructure failures, and centralize MCP paths, scopes, and audience configuration. Reject consent requests that do not name any permissions.
Type provider-specific reasoning options at their source and use the generated Browser binding directly. This keeps provider configuration checked without changing the tool surface.
Translate only expected domain errors and surface infrastructure failures. Record cleanup and purge failures with structured operational events.
Remove redundant manual memoization from compiler-compatible components. Use effect events for file-drop callbacks and hoist stable render values.
Force the patched DOMPurify release across transitive consumers. Document the single-audience constraint mitigating Better Auth 1.6 resource widening.
|
Warning Review limit reached
Next review available in: 16 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (10)
📝 WalkthroughWalkthroughAdds a remote OAuth-protected MCP server with database schema, authentication, scoped workspace operations, OpenAPI metadata, consent UI, and routing. Refactors workspace kernel mutations to structured outcomes, adds reliability telemetry and invite status handling, and removes selected React memoization. ChangesMCP OAuth Server
Workspace Kernel Mutation Outcomes
Workspace Tool Access/Effects Model
Workspace Reliability and Invite Flow
React and Utility Updates
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant routeMcpRequest
participant authenticateMcpRequest
participant BetterAuth
participant executeMcpOperation
Client->>routeMcpRequest: POST MCP operation with Bearer token
routeMcpRequest->>authenticateMcpRequest: Verify request token
authenticateMcpRequest->>BetterAuth: Load JWKS
BetterAuth-->>authenticateMcpRequest: Token payload
authenticateMcpRequest-->>routeMcpRequest: Principal or 401 response
routeMcpRequest->>executeMcpOperation: Dispatch operation and principal
executeMcpOperation-->>routeMcpRequest: Scoped operation result
routeMcpRequest-->>Client: MCP response with CORS headers
sequenceDiagram
participant Operation
participant WorkspaceKernel
participant WorkspaceKernelStore
Operation->>WorkspaceKernel: Execute mutation
WorkspaceKernel->>WorkspaceKernelStore: Resolve item name
WorkspaceKernelStore-->>WorkspaceKernel: Resolved or conflict outcome
WorkspaceKernel-->>Operation: Applied command or conflict outcome
Operation-->>Operation: Map conflict to path_already_exists
Possibly related issues
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
React Doctor found 2 new issues in 2 files · 2 warnings · score 77 / 100 (Needs work) · 21 fixed · vs 2 warnings
Reviewed by React Doctor for commit |
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
Greptile SummaryThis PR adds an authenticated MCP workspace surface. The main changes are:
Confidence Score: 5/5This PR appears safe to merge with low risk. The MCP authentication path verifies issuer and audience locally, operation execution checks OAuth scopes, and workspace operations re-check live membership and role permissions. No files require special attention.
What T-Rex did
Important Files Changed
Reviews (1): Last reviewed commit: "fix(security): pin sanitizer and MCP aud..." | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/features/mcp/mcp-cors.ts`:
- Line 1: Add mcp-session-id to mcpCorsRequestHeaders in
src/features/mcp/mcp-cors.ts. Update the preflight assertion in
src/features/mcp/mcp-cors.test.ts lines 12-19 to verify the response allows
mcp-session-id.
In `@src/features/workspaces/kernel/workspace-kernel-item-commands.ts`:
- Around line 176-184: Update the item-creation command containing
relations.createRelations and events.commit so item insertion, initial relation
creation, and event persistence execute in one database transaction. Ensure
transaction failure compensates by removing the created shell file (or otherwise
cleans up the item) while preserving the existing idempotency behavior, so
retries can complete or return the original mutation.
In `@src/routes/oauth.consent.tsx`:
- Around line 31-59: Update decide so the authClient.oauth2.consent call is
covered by try/finally, ensuring setPendingDecision(null) always runs when the
request rejects or completes. Preserve the existing validation, result-error
handling, and redirect behavior while preventing rejected requests from leaving
the consent buttons disabled.
- Around line 17-20: Update the consent action around
authClient.oauth2.consent(...) to use try/catch, ensuring pendingDecision is
cleared in the error path so the consent buttons become enabled again when the
request rejects. Preserve the existing success behavior and decision handling.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5d9baf30-6c6c-464c-a374-8493e978dce1
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (59)
drizzle/0002_lyrical_lorna_dane.sqldrizzle/0003_aberrant_nitro.sqldrizzle/meta/0002_snapshot.jsondrizzle/meta/0003_snapshot.jsondrizzle/meta/_journal.jsonpackage.jsonpnpm-workspace.yamlsrc/components/landing/gravity.tsxsrc/components/ui/command.tsxsrc/db/schema.tssrc/features/mcp/mcp-auth.tssrc/features/mcp/mcp-config.tssrc/features/mcp/mcp-cors.test.tssrc/features/mcp/mcp-cors.tssrc/features/mcp/mcp-openapi.tssrc/features/mcp/mcp-operation-catalog.tssrc/features/mcp/mcp-operation-catalog.worker.test.tssrc/features/mcp/mcp-route.tssrc/features/workspaces/ai/ai-thread-prompt-scope.tssrc/features/workspaces/ai/ai-thread-runtime.tssrc/features/workspaces/ai/ai-thread.tssrc/features/workspaces/ai/user-ai-agents.tssrc/features/workspaces/ai/web-tools.tssrc/features/workspaces/ai/workspace-tools.tssrc/features/workspaces/components/WorkspaceFileIntakeProvider.tsxsrc/features/workspaces/components/WorkspaceFileUploadProvider.tsxsrc/features/workspaces/components/WorkspaceShareEmailInviteField.tsxsrc/features/workspaces/components/ai-chat/AiChatModelPicker.tsxsrc/features/workspaces/components/use-auto-hide-overlay.tssrc/features/workspaces/contracts.tssrc/features/workspaces/documents/document-session.tssrc/features/workspaces/durable-object-lifecycle.tssrc/features/workspaces/extraction/liteparse-projection.tssrc/features/workspaces/extraction/workspace-page-projection.tssrc/features/workspaces/invites/workspace-invite-email.tssrc/features/workspaces/invites/workspace-invite-functions.tssrc/features/workspaces/kernel/workspace-kernel-access.tssrc/features/workspaces/kernel/workspace-kernel-file-commands.tssrc/features/workspaces/kernel/workspace-kernel-item-commands.tssrc/features/workspaces/kernel/workspace-kernel-store.tssrc/features/workspaces/kernel/workspace-kernel-types.tssrc/features/workspaces/kernel/workspace-kernel.tssrc/features/workspaces/operations/create-items.tssrc/features/workspaces/operations/move-items.tssrc/features/workspaces/operations/rename-item.tssrc/features/workspaces/operations/workspace-tool-definitions.tssrc/features/workspaces/read-page-selection.tssrc/features/workspaces/realtime/use-workspace-presence.tssrc/lib/app-origin.tssrc/lib/auth-client.tssrc/lib/auth.server.tssrc/lib/blog.tssrc/lib/use-native-file-drop-target.tssrc/routeTree.gen.tssrc/routes/api/auth/$.tssrc/routes/api/v1/workspaces.$workspaceId.file-upload.tssrc/routes/invite.$token.tsxsrc/routes/oauth.consent.tsxsrc/server.ts
| @@ -0,0 +1,31 @@ | |||
| const mcpCorsRequestHeaders = "authorization, content-type, mcp-protocol-version"; | |||
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== Files ==\n'
git ls-files src/features/mcp/mcp-cors.ts src/features/mcp/mcp-cors.test.ts
printf '\n== Outline: src/features/mcp/mcp-cors.ts ==\n'
ast-grep outline src/features/mcp/mcp-cors.ts --view expanded || true
printf '\n== Outline: src/features/mcp/mcp-cors.test.ts ==\n'
ast-grep outline src/features/mcp/mcp-cors.test.ts --view expanded || true
printf '\n== Relevant lines: src/features/mcp/mcp-cors.ts ==\n'
cat -n src/features/mcp/mcp-cors.ts
printf '\n== Relevant lines: src/features/mcp/mcp-cors.test.ts ==\n'
cat -n src/features/mcp/mcp-cors.test.tsRepository: ThinkEx-OSS/thinkex
Length of output: 3604
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== Search for MCP CORS and session header references ==\n'
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' \
'mcp-session-id|mcpCorsRequestHeaders|mcpCorsPreflightResponse|Mcp-Session-Id' src
printf '\n== Show any MCP-related transport code ==\n'
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' \
'MCP|mcp' src/features src | head -n 200Repository: ThinkEx-OSS/thinkex
Length of output: 15192
🌐 Web query:
MCP transport spec Mcp-Session-Id request header CORS preflight browser clients
💡 Result:
In the Model Context Protocol (MCP) Streamable HTTP transport specification, the Mcp-Session-Id header is used to maintain stateful sessions between a client and a server [1][2][3]. When an MCP server is accessed by browser-based clients, proper Cross-Origin Resource Sharing (CORS) configuration is required to ensure that this header is accessible and that browser-enforced security policies do not block the communication [4][5][6]. Key considerations for CORS and the Mcp-Session-Id header include: 1. Exposing the Header: Browsers restrict access to response headers by default. For a browser-based client to read the Mcp-Session-Id header returned by the server during the initialization phase (and persist it for subsequent requests), the server must explicitly include it in the Access-Control-Expose-Headers list in its CORS policy [4][5][6][7]. Failing to do this is a common cause of session management failures in browser environments, as the client library cannot access the session ID to include it in future requests [4][5]. 2. Preflight Requests: When a browser client makes requests that include custom headers (such as Mcp-Session-Id), it triggers a CORS preflight (OPTIONS) request [8][7][9]. The server must respond to this preflight request with appropriate Access-Control-Allow-Headers that include Mcp-Session-Id, as well as any other headers used by the protocol (e.g., Mcp-Protocol-Version, Content-Type) [4][5][10]. 3. Security Recommendations: - Avoid overly permissive configurations like Access-Control-Allow-Origin: * when credentials are involved [11][12][13]. - Ensure the server adheres to restrictive CORS policies, specifically listing allowed origins, methods (GET, POST, DELETE, OPTIONS), and required headers [12][7]. - Implement Access-Control-Max-Age to cache preflight responses, reducing the overhead of repeated preflight requests [8][12][13]. - Consider mandatory security headers, such as Strict-Transport-Security (HSTS), to protect the transport [12]. In summary, for browser clients to successfully manage sessions, your server's CORS middleware must be configured to both allow the Mcp-Session-Id header in requests (via Access-Control-Allow-Headers) and expose it in responses (via Access-Control-Expose-Headers) [4][5][13][7].
Citations:
- 1: https://modelcontextprotocol.io/specification/2025-11-25/basic/transports?referrer=wordpress.com
- 2: https://modelcontextprotocol.io/specification/2025-03-26/basic/transports
- 3: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/ff960c9e/docs/specification/2025-06-18/basic/transports.mdx
- 4: MCP Python SDK sessionId not maintained in browser with TypeScript SDK client modelcontextprotocol/typescript-sdk#764
- 5: Missing session reuse in browser: client.connect ignores mcp-session-id modelcontextprotocol/typescript-sdk#852
- 6: gspencergoog/mcp-python-sdk@09e3a05
- 7: https://mcpcat.io/guides/implementing-cors-policies-web-based-mcp-servers/
- 8: https://www.mcp-framework.com/docs/transports/http-stream
- 9: https://agentgateway-agentgateway.mintlify.app/reference/policies/cors
- 10: CORS fail, current versions of MCP protocol send "Mcp-Protocol-Version" header too PrefectHQ/fastmcp#3122
- 11: https://github.com/modelcontextprotocol/servers/blob/main/src/everything/transports/streamableHttp.ts
- 12: SEP: Mandatory Security Headers for MCP HTTP Transport modelcontextprotocol/modelcontextprotocol#1961
- 13: https://github.com/apollographql/apollo-mcp-server/blob/main/docs/source/cors.mdx
Allow Mcp-Session-Id in CORS preflight headers.
Browser clients need to send the MCP session ID on follow-up requests, but mcpCorsRequestHeaders omits mcp-session-id from Access-Control-Allow-Headers.
src/features/mcp/mcp-cors.ts: addmcp-session-idtomcpCorsRequestHeaders.src/features/mcp/mcp-cors.test.ts: assert the preflight response allowsmcp-session-id.
📍 Affects 2 files
src/features/mcp/mcp-cors.ts#L1-L1(this comment)src/features/mcp/mcp-cors.test.ts#L12-L19
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/features/mcp/mcp-cors.ts` at line 1, Add mcp-session-id to
mcpCorsRequestHeaders in src/features/mcp/mcp-cors.ts. Update the preflight
assertion in src/features/mcp/mcp-cors.test.ts lines 12-19 to verify the
response allows mcp-session-id.
There was a problem hiding this comment.
All reported issues were addressed across 60 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
|
Capy auto-review is paused for this organization because the usage-cycle auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews. |
There was a problem hiding this comment.
0 issues found across 6 files (changes from recent commits).
Requires human review: Auto-approval blocked by 1 unresolved issue from previous reviews.
Re-trigger cubic
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Requires human review: Auto-approval blocked by 1 unresolved issue from previous reviews.
Re-trigger cubic
There was a problem hiding this comment.
0 issues found across 7 files (changes from recent commits).
Requires human review: Auto-approval blocked by 1 unresolved issue from previous reviews.
Re-trigger cubic
| initialContent: initialContent.content, | ||
| actorUserId: accessContext.actor.userId, | ||
| clientMutationId: accessContext.operationId, | ||
| const outcome = await workspaceContext.kernel.createItem({ |
There was a problem hiding this comment.
React Doctor · react-doctor/async-await-in-loop (warning)
This makes the for…of loop slow because each await runs one after another, so collect the independent calls & run them together with await Promise.all(items.map(...))
Fix → Collect the items, then use await Promise.all(items.map(...)) so independent work runs at the same time
There was a problem hiding this comment.
0 issues found across 1 file (changes from recent commits).
Requires human review: Introduces database migrations, OAuth authentication, and new public MCP API endpoints; these require human review for security, schema, and operational tradeoffs.
Re-trigger cubic
Summary
Why
ThinkEx needs an MCP surface that remains useful as the operation catalog grows without loading a large tool schema into every client context. The implementation uses a compact executor-style interface while retaining the existing workspace service and permission boundaries as the source of truth.
The earlier MCP pull request was old and coupled a large amount of code to outdated assumptions. This branch rebuilds the feature on the current workspace architecture and keeps authentication, protocol routing, operation metadata, and workspace execution behind separate boundaries.
Changes
Testing
pnpm checkpnpm test— 72 tests passedpnpm test:workers— 4 tests passedpnpm knipReview Notes
src/features/mcp/mcp-route.ts,src/features/mcp/mcp-auth.ts, andsrc/features/mcp/mcp-operation-catalog.tsfor the protocol and execution boundaries.src/lib/auth.server.tsand the two new Drizzle migrations together; the OAuth signing-key persistence is required before deployment.Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Summary by CodeRabbit