Skip to content
Merged
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
36 changes: 25 additions & 11 deletions apps/portal/src/app/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,17 @@ const apisLinks = [
},
];

const aiLinks = [
{
href: "/ai/mcp",
name: "MCP",
},
{
href: "/ai/llm-txt",
name: "LLMs.txt",
},
];

const sdkLinks = [
{
href: "/references/typescript/v5",
Expand Down Expand Up @@ -288,16 +299,7 @@ export function Header() {
<div className="px-1">
<DropdownLinks
category="AI"
links={[
{
href: "/ai/mcp",
name: "MCP",
},
{
href: "/ai/llms-txt",
name: "LLMs.txt",
},
]}
links={aiLinks}
onLinkClick={() => setShowBurgerMenu(false)}
/>
</div>
Expand Down Expand Up @@ -358,13 +360,25 @@ export function Header() {
))}
</div>

<div className="flex flex-col gap-4">
<h3 className="font-semibold text-lg">AI</h3>
{aiLinks.map((link) => (
<NavLink
href={link.href}
key={link.name}
name={link.name}
onClick={() => setShowBurgerMenu(false)}
/>
))}
</div>

<div className="flex flex-col gap-4">
<h3 className="font-semibold text-lg">SDKs</h3>
{sdkLinks.map((link) => (
<NavLink
href={link.href}
icon={link.icon}
key={link.name}
icon={link.icon}
name={link.name}
onClick={() => setShowBurgerMenu(false)}
/>
Expand Down
30 changes: 26 additions & 4 deletions apps/portal/src/app/ai/llm-txt/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,42 @@

Use these llms.txt files to instruct your LLM on how to use the thirdweb API.

### thirdweb API reference
## How to use

Download the llms.txt file you want to use and add it to your project files or ruleset.

Reference them in your prompts when asking to build a feature, or alternatively inject the url directly in your prompt.

Example:

```txt
Add a login screen that lets the user enter the email and confirm a verification code.
then display their email and wallet address in the header.
Docs: https://api.thirdweb.com/llms.txt
```

## thirdweb API reference

The [thirdweb HTTP API reference](https://api.thirdweb.com/reference) as markdown.

Available at: https://api.thirdweb.com/llms.txt

### Typescript SDK quick reference
**Recommended for:** Web and native applications, servers, agents using the HTTP thirdweb API.


## Typescript SDK quick reference

Contains a table of contents for the thirdweb Typescript SDK documentation.

Available at: https://portal.thirdweb.com/llms.txt

### Typescript SDK full documentation
**Recommended for:** Typescript, react or react native applications that deal with external wallets and advanced blockchain features.


## Typescript SDK full documentation

Contains the entire thirdweb Typescript SDK documentation as markdown. Requires large context windows.

Available at: https://portal.thirdweb.com/llms-full.txt
Available at: https://portal.thirdweb.com/llms-full.txt

**Recommended for:** Typescript, react or react native applications that deal with external wallets and advanced blockchain features.
114 changes: 96 additions & 18 deletions apps/portal/src/app/ai/mcp/page.mdx
Original file line number Diff line number Diff line change
@@ -1,42 +1,93 @@
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";

# MCP server

You can use the thirdweb MCP server to interact with the thirdweb API from your agents or LLM client.

### Remote MCP endpoint
## Remote MCP endpoint

You can access the MCP server at the following url, with your project secret key.

```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>
```
Comment on lines 11 to 13
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

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.


### Usage with LLM clients
Make sure to keep your secret key safe and never share it with anyone.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

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.


## Usage with LLM clients

You can also use the MCP server on your own LLM client, like cursor, claude code and more. Refer to your LLM client's documentation for more information.

#### Example usage with Cursor:
<Tabs defaultValue="cursor">

<TabsList>
<TabsTrigger value="cursor">Cursor</TabsTrigger>
<TabsTrigger value="windsurf">WindSurf</TabsTrigger>
<TabsTrigger value="vscode">VS Code</TabsTrigger>
<TabsTrigger value="claudecode">Claude Code</TabsTrigger>
</TabsList>

<TabsContent value="cursor">

Add the following to your `.cursor/mcp.json` file:

```json
{
"mcpServers": {
"thirdweb-api": {
"url": "https://api.thirdweb.com/mcp",
"headers": {
"x-secret-key": "<your-project-secret-key>"
}
"url": "https://api.thirdweb.com/mcp?secretKey=<your-project-secret-key>",
}
}
}
```

</TabsContent>

<TabsContent value="windsurf">

Add the following to your `~/.codeium/windsurf/mcp_config.json` file:

```json
{
"mcpServers": {
"thirdweb-api": {
"url": "https://api.thirdweb.com/mcp?secretKey=<your-project-secret-key>",
}
}
}
```

</TabsContent>

<TabsContent value="vscode">

Add the following to your VS Code `.vscode/mcp.json` file:

```json
{
"mcp.servers": {
"thirdweb-api": {
"url": "https://api.thirdweb.com/mcp?secretKey=<your-project-secret-key>",
}
}
}
```

### Usage with agents
</TabsContent>

<TabsContent value="claudecode">

Run the following command to add the MCP server to your Claude Code configuration:

```bash
claude mcp add --transport http "thirdweb-api" "https://api.thirdweb.com/mcp?secretKey=<your-project-secret-key>"
```

</TabsContent>

</Tabs>

## Usage with agents

Use your favorite agent framework to plug in the MCP server as a collection of tools for your agent. Refer to your agent framework's documentation for more information.

Expand All @@ -50,10 +101,7 @@ client = MultiServerMCPClient(
{
"thirdweb-api": {
"transport": "streamable_http",
"url": "https://api.thirdweb.com/mcp",
"headers": {
"x-secret-key": "<your-project-secret-key>"
},
"url": "https://api.thirdweb.com/mcp?secretKey=<your-project-secret-key>",
}
}
)
Expand All @@ -62,3 +110,33 @@ agent = create_react_agent("openai:gpt-4.1", tools)
response = await agent.ainvoke({"messages": "create a server wallet called 'my-wallet'"})
```

Once installed, you can use the entire thirdweb API with natural language.

## Example prompts

#### Managing server wallets

```
List my server wallets
```

```
Create a server wallet called treasury
```

```
What's the balance of treasury wallet?
```

#### Managing contracts

```
List my contracts
```

#### Executing transactions

```
approve 100 USDC from treasury wallet to executor wallet
```

32 changes: 23 additions & 9 deletions apps/portal/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MessageCircleIcon, WebhookIcon } from "lucide-react";
import { BotIcon, MessageCircleIcon, WebhookIcon, ZapIcon } from "lucide-react";
import Image from "next/image";
import Link from "next/link";
import { Heading } from "@/components/Document";
Expand Down Expand Up @@ -66,14 +66,28 @@ function Hero() {
function PlaygroundSection() {
return (
<section>
<SectionTitle anchorId="playground" title="Live Demos" />
<ArticleCardIndex
description="Try out our interactive playground to get started"
external
href="https://playground.thirdweb.com"
icon={PlaygroundIcon}
title="Playground"
/>
<SectionTitle anchorId="playground" title="Quick Starts" />
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
<ArticleCardIndex
description="Try out our interactive playground to get started"
external
href="https://playground.thirdweb.com"
icon={PlaygroundIcon}
title="Playground"
/>
<ArticleCardIndex
description="For agents and humans: use the thirdweb API with natural language"
href="/ai/mcp"
icon={BotIcon}
title="MCP"
/>
<ArticleCardIndex
description="Inject the thirdweb API reference in your prompts"
href="/ai/llm-txt"
icon={ZapIcon}
title="LLMs.txt"
/>
</div>
</section>
);
}
Expand Down
Loading