-
Notifications
You must be signed in to change notification settings - Fork 588
[Docs] Update MCP authentication from headers to query parameters #7726
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Docs] Update MCP authentication from headers to query parameters #7726
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
""" WalkthroughThe documentation for accessing the thirdweb MCP server was updated to use a query parameter ( Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
apps/portal/src/app/ai/mcp/page.mdx (1)
41-46
: Agent client should keep secrets out of source controlHard-coding the secret in the URL inside application code will inevitably land in VCS.
Use env vars and pass via headers to keep secrets ephemeral:import os client = MultiServerMCPClient( { "thirdweb-api": { "transport": "streamable_http", "url": "https://api.thirdweb.com/mcp", "headers": {"x-secret-key": os.environ["TW_SECRET_KEY"]}, } } )
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/portal/src/app/ai/mcp/page.mdx
(3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Surface breaking changes prominently in PR descriptions
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Size
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
```http | ||
# endpoint | ||
POST /mcp | ||
Host: api.thirdweb.com | ||
# auth header (required) | ||
x-secret-key <your-project-secret-key> | ||
POST https://api.thirdweb.com/mcp?secretKey=<your-project-secret-key> | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Secret key in query string is highly leak-prone
Putting secretKey
in the URL means it is persisted in:
• browser history
• server/access logs
• proxy caches and analytics tools
• the Referer
header of any subsequent navigation
This dramatically increases the blast-radius of credential leakage.
Strongly prefer sending the key in an HTTP header or request body instead.
🤖 Prompt for AI Agents
In apps/portal/src/app/ai/mcp/page.mdx around lines 9 to 11, the secretKey is
included in the URL query string, which risks leaking the key through browser
history, logs, caches, and referer headers. To fix this, remove the secretKey
from the URL and instead send it securely in an HTTP header or in the request
body of the POST request.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7726 +/- ##
=======================================
Coverage ? 56.18%
=======================================
Files ? 908
Lines ? 58236
Branches ? 4200
=======================================
Hits ? 32718
Misses ? 25410
Partials ? 108
*This pull request uses carry forward flags. Click here to find out more. 🚀 New features to boost your workflow:
|
size-limit report 📦
|
df3a523
to
97ae4e5
Compare
97ae4e5
to
748ded9
Compare
748ded9
to
6ebc1a0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (3)
apps/portal/src/app/ai/mcp/page.mdx (3)
11-13
: Secret key in query string is highly leak-pronePutting
secretKey
in the URL means it is persisted in:
• browser history
• server/access logs
• proxy caches and analytics tools
• theReferer
header of any subsequent navigationThis dramatically increases the blast-radius of credential leakage.
Strongly prefer sending the key in an HTTP header or request body instead.
38-83
: All client configurations propagate the security vulnerabilityEvery configuration example (Cursor, WindSurf, VS Code, Claude Code) embeds the secret key in the URL, perpetuating the same security risk across all client integrations. This means any user following these instructions will implement insecure authentication.
Consider using headers instead:
{ "mcpServers": { "thirdweb-api": { "url": "https://api.thirdweb.com/mcp", "headers": { "x-secret-key": "${TW_SECRET_KEY}" } } } }
104-104
: Agent framework example also uses insecure authenticationThe langchain example perpetuates the same security vulnerability by embedding the secret key in the URL. Programmatic usage should especially avoid URL-based secrets as they may be logged or persisted by frameworks.
🧹 Nitpick comments (1)
apps/portal/src/app/Header.tsx (1)
363-374
: Mobile AI section is well-implemented but has icon prop issueThe new AI section follows the established mobile menu pattern correctly. However, line 368 passes an
icon
prop that doesn't exist in theaiLinks
definition, which could cause issues.Remove the unnecessary icon prop:
<NavLink href={link.href} - icon={link.icon} key={link.name} name={link.name} onClick={() => setShowBurgerMenu(false)} />
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
apps/portal/src/app/Header.tsx
(3 hunks)apps/portal/src/app/ai/llm-txt/page.mdx
(1 hunks)apps/portal/src/app/ai/mcp/page.mdx
(3 hunks)
✅ Files skipped from review due to trivial changes (1)
- apps/portal/src/app/ai/llm-txt/page.mdx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*.{ts,tsx}
: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from@/types
or localtypes.ts
barrels
Prefer type aliases over interface except for nominal shapes
Avoidany
andunknown
unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial
,Pick
, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
Files:
apps/portal/src/app/Header.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
apps/portal/src/app/Header.tsx
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Surface breaking changes prominently in PR descriptions
apps/portal/src/app/ai/mcp/page.mdx (9)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Prefer API routes or server actions to keep tokens secret; the browser only sees relative paths.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Keep tokens secret via internal API routes or server actions
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard//api//*.{ts,tsx} : Pass the token in the Authorization: Bearer
header – never embed it in the URL.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use Authorization: Bearer
header – never embed tokens in URLs
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Keep queryKey
stable and descriptive for cache hits.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use descriptive, stable queryKeys
for React Query cache hits
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Always call getAuthToken()
to retrieve JWT from cookies on server side
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{ts,tsx} : Accessing server-only environment variables or secrets.
Learnt from: MananTank
PR: #7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts:41-44
Timestamp: 2025-05-27T19:56:16.920Z
Learning: When reviewing hooks that use environment variables like NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID for API calls, MananTank prefers not to add explicit validation checks for these variables, trusting they will be set in the deployment environment.
apps/portal/src/app/Header.tsx (12)
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use NavLink
for internal navigation with automatic active states in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Use NavLink
(@/components/ui/NavLink
) for internal navigation so active states are handled automatically.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/*
(Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard//api//*.{ts,tsx} : Co-locate data helpers under @/api/**
and mark them with "server-only".
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use cn()
from @/lib/utils
for conditional class logic
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to src/exports/react.native.ts : React Native specific exports are in src/exports/react.native.ts
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button
, Input
, Select
, Tabs
, Card
, Sidebar
, Separator
, Badge
.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn
from @/lib/utils
to keep conditional logic readable.
Learnt from: arcoraven
PR: #7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like aria-label
and role
in its TypeScript interface, causing compilation errors when added.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Icons come from lucide-react
or the project-specific …/icons
exports – never embed raw SVG.
Learnt from: jnsdls
PR: #7365
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectFTUX/ProjectFTUX.tsx:16-17
Timestamp: 2025-06-18T04:30:04.326Z
Learning: Next.js Link component fully supports both internal and external URLs and works appropriately with all standard anchor attributes including target="_blank", rel="noopener noreferrer", etc. Using Link for external URLs is completely appropriate and recommended.
Learnt from: jnsdls
PR: #7365
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectFTUX/ProjectFTUX.tsx:16-17
Timestamp: 2025-06-18T04:27:16.172Z
Learning: Next.js Link component supports external URLs without throwing errors. When used with absolute URLs (like https://...), it behaves like a regular anchor tag without client-side routing, but does not cause runtime crashes or errors as previously believed.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: Size
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Lint Packages
- GitHub Check: Unit Tests
- GitHub Check: Analyze (javascript)
🔇 Additional comments (3)
apps/portal/src/app/ai/mcp/page.mdx (1)
115-142
: Good addition of example promptsThe example prompts provide clear, practical guidance for users on how to interact with the MCP server using natural language. This enhances the documentation's usability.
apps/portal/src/app/Header.tsx (2)
144-153
: Good refactoring to consolidate AI navigation linksCreating the
aiLinks
constant improves maintainability by centralizing AI-related navigation links and follows the established pattern used by other link arrays in the file.
302-302
: Correct usage of the new aiLinks constantThe dropdown now properly references the centralized
aiLinks
constant, completing the refactoring consistently.
``` | ||
|
||
### Usage with LLM clients | ||
Make sure to keep your secret key safe and never share it with anyone. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Security note is insufficient given the insecure implementation
While adding a security reminder is good practice, advising users to "keep your secret key safe" while instructing them to embed it in URLs is contradictory. URLs are inherently unsafe for secrets due to logging, caching, and history persistence.
🤖 Prompt for AI Agents
In apps/portal/src/app/ai/mcp/page.mdx at line 15, the security note advises
keeping the secret key safe but contradicts this by instructing users to embed
it in URLs, which is insecure. Update the instructions to remove any guidance
that involves placing secret keys in URLs and instead recommend safer methods
such as using environment variables or secure storage mechanisms to handle
secret keys without exposing them in URLs.
6ebc1a0
to
75f3a01
Compare
75f3a01
to
124b92a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
apps/portal/src/app/ai/mcp/page.mdx (1)
12-13
: Secret key in plaintext URLs is a high-severity credential-leak vectorPlacing
secretKey
in the query string means it will be recorded in browser history, proxies, load-balancer logs, analytics tools andReferer
headers, effectively nullifying the “keep it safe” advice on L15.
Pass the secret in anAuthorization
/x-secret-key
header or, if unavoidable, via POST body parameters that never hit logs.This concern has already been raised in earlier reviews and remains unresolved.
Also applies to: 38-41, 54-57, 70-71, 83-84, 104-105
🧹 Nitpick comments (1)
apps/portal/src/app/ai/mcp/page.mdx (1)
100-110
: Top-levelawait
won’t run in a normal Python scriptRegular Python files don’t support bare
await
; readers will copy-paste and hit aSyntaxError
. Either:
- Note that the snippet is for a REPL / Jupyter context, or
- Wrap it in an async function and call
asyncio.run
.Example adjustment:
-tools = await client.get_tools() -agent = create_react_agent("openai:gpt-4.1", tools) -response = await agent.ainvoke({"messages": "create a server wallet called 'my-wallet'"}) +import asyncio + +async def main(): + tools = await client.get_tools() + agent = create_react_agent("openai:gpt-4.1", tools) + response = await agent.ainvoke( + {"messages": "create a server wallet called 'my-wallet'"} + ) + print(response) + +asyncio.run(main())
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/portal/src/app/Header.tsx
(3 hunks)apps/portal/src/app/ai/llm-txt/page.mdx
(1 hunks)apps/portal/src/app/ai/mcp/page.mdx
(3 hunks)apps/portal/src/app/page.tsx
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/portal/src/app/ai/llm-txt/page.mdx
- apps/portal/src/app/Header.tsx
- apps/portal/src/app/page.tsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Surface breaking changes prominently in PR descriptions
apps/portal/src/app/ai/mcp/page.mdx (9)
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Prefer API routes or server actions to keep tokens secret; the browser only sees relative paths.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Keep tokens secret via internal API routes or server actions
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard//api//*.{ts,tsx} : Pass the token in the Authorization: Bearer
header – never embed it in the URL.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use Authorization: Bearer
header – never embed tokens in URLs
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Keep queryKey
stable and descriptive for cache hits.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use descriptive, stable queryKeys
for React Query cache hits
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Always call getAuthToken()
to retrieve JWT from cookies on server side
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{ts,tsx} : Accessing server-only environment variables or secrets.
Learnt from: MananTank
PR: #7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenTransfers.ts:41-44
Timestamp: 2025-05-27T19:56:16.920Z
Learning: When reviewing hooks that use environment variables like NEXT_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID for API calls, MananTank prefers not to add explicit validation checks for these variables, trusting they will be set in the deployment environment.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: E2E Tests (pnpm, esbuild)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: Size
- GitHub Check: Unit Tests
- GitHub Check: Lint Packages
- GitHub Check: Build Packages
- GitHub Check: Analyze (javascript)
PR-Codex overview
This PR focuses on enhancing the
Header
component by adding AI-related links and updating the content of theMCP
andLLMs.txt
pages to provide clearer usage instructions and examples for interacting with the thirdweb API.Detailed summary
aiLinks
array inHeader.tsx
for AI-related navigation.Header
component to useaiLinks
instead of hardcoded links.Hero
section inpage.tsx
to change title and layout for quick starts.llm-txt/page.mdx
with clearer instructions and examples.mcp/page.mdx
with new usage examples and configurations for various clients.Summary by CodeRabbit