Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
3a89e42
Add email-capture auth to the MCP server
JakeSCahill Jun 15, 2026
14e57d0
chore: bump server.json version to 2026.06.15+pr181-8d11b9b (PR #181)
github-actions[bot] Jun 15, 2026
64dff55
chore: bump server.json version to 2026.06.15+pr181-ff0868b (PR #181)
github-actions[bot] Jun 15, 2026
2ff8bc5
Harden token-email dev bypass to NETLIFY_DEV only
JakeSCahill Jun 15, 2026
e71d339
chore: bump server.json version to 2026.06.15+pr181-75928f7 (PR #181)
github-actions[bot] Jun 15, 2026
c0475db
Switch MCP auth to OAuth 2.1 via Redpanda Cloud IdP
JakeSCahill Jun 15, 2026
a669b2c
chore: bump server.json version to 2026.06.15+pr181-852c563 (PR #181)
github-actions[bot] Jun 15, 2026
3e0d7ca
chore: trigger preview redeploy to pick up REQUIRE_AUTH
JakeSCahill Jun 15, 2026
dc655b1
chore: trigger preview redeploy to pick up REQUIRE_AUTH
JakeSCahill Jun 15, 2026
e751010
chore: bump server.json version to 2026.06.15+pr181-a59f207 (PR #181)
github-actions[bot] Jun 15, 2026
c0b9280
Apply suggestion from @JakeSCahill
JakeSCahill Jun 15, 2026
70623c0
chore: bump server.json version to 2026.06.15+pr181-27a3294 (PR #181)
github-actions[bot] Jun 15, 2026
e8aac4c
Remove unused exports from MCP auth modules
JakeSCahill Jun 15, 2026
a5cf8b9
chore: bump server.json version to 2026.06.15+pr181-20381aa (PR #181)
github-actions[bot] Jun 15, 2026
59be719
TEMP: add CIMD probe client metadata document (to be removed)
JakeSCahill Jun 15, 2026
b3927cd
chore: bump server.json version to 2026.06.15+pr181-00193c2 (PR #181)
github-actions[bot] Jun 15, 2026
b2def9e
Remove temporary CIMD probe client doc
JakeSCahill Jun 15, 2026
f3212e0
chore: bump server.json version to 2026.06.15+pr181-1fe3d6c (PR #181)
github-actions[bot] Jun 15, 2026
fcee882
Start production AS scaffold: jose + storage layer, federate to Auth0…
JakeSCahill Jun 16, 2026
c81d44f
Make dev-mock upstream fail-closed
JakeSCahill Jun 16, 2026
2819de6
Fix mcp-oauth bundling: config.path must be literal strings
JakeSCahill Jun 17, 2026
e22fca0
Use strong consistency for the OAuth Blobs stores
JakeSCahill Jun 17, 2026
dc8895b
M2: client registration (DCR + CIMD) + redirect_uri validation
JakeSCahill Jun 17, 2026
4cdd956
M3: refresh-token grant with rotation + reuse detection
JakeSCahill Jun 17, 2026
f76519e
Add login interstitial at /authorize with a Cloud sign-up link (Optio…
JakeSCahill Jun 17, 2026
e966f28
Add /register rate-limit + refine auth docs
JakeSCahill Jun 17, 2026
ecf38df
Default REQUIRE_WORK_EMAIL to false now that login is via Cloud
JakeSCahill Jun 18, 2026
ce4da11
Merge remote-tracking branch 'origin/main' into feature/mcp-email-auth
JakeSCahill Jun 18, 2026
ed4ff41
chore: bump server.json version to 2026.06.18+pr181-ad5c910 (PR #181)
github-actions[bot] Jun 18, 2026
e49fd4f
Add CORS preflight (OPTIONS) handling to the OAuth discovery + token …
JakeSCahill Jun 18, 2026
1bffb1a
chore: bump server.json version to 2026.06.18+pr181-bea985c (PR #181)
github-actions[bot] Jun 18, 2026
beffc37
Address review: IPv6 SSRF guard, require client_id in token requests,…
JakeSCahill Jun 18, 2026
19e26af
chore: bump server.json version to 2026.06.18+pr181-0812fe6 (PR #181)
github-actions[bot] Jun 18, 2026
45c68bb
Address second CodeRabbit review batch
JakeSCahill Jun 18, 2026
ae24998
chore: bump server.json version to 2026.06.18+pr181-3d173f0 (PR #181)
github-actions[bot] Jun 18, 2026
4fb1e37
Link the privacy policy at login
JakeSCahill Jun 18, 2026
30e3efe
chore: bump server.json version to 2026.06.18+pr181-b3666e7 (PR #181)
github-actions[bot] Jun 18, 2026
37a315f
Drop the 'we don't store your queries' claim
JakeSCahill Jun 18, 2026
6e3bf8b
chore: bump server.json version to 2026.06.18+pr181-272b4d1 (PR #181)
github-actions[bot] Jun 18, 2026
b95f868
Point sign-up links at cloud.redpanda.com/sign-up
JakeSCahill Jun 18, 2026
081ff22
chore: bump server.json version to 2026.06.18+pr181-93bf858 (PR #181)
github-actions[bot] Jun 18, 2026
8f70a70
Document how token refresh works in plain English
JakeSCahill Jun 18, 2026
82cac4f
chore: bump server.json version to 2026.06.18+pr181-4b6920d (PR #181)
github-actions[bot] Jun 18, 2026
c7a016f
Add submit_documentation_feedback MCP tool
JakeSCahill Jun 22, 2026
7becb83
chore: bump server.json version to 2026.06.22+pr181-ac52b6c (PR #181)
github-actions[bot] Jun 22, 2026
7bb60d2
Surface feedback capability in server card and server.json
JakeSCahill Jun 22, 2026
95d50fd
chore: bump server.json version to 2026.06.22+pr181-748cb39 (PR #181)
github-actions[bot] Jun 22, 2026
425d2c9
Fix feedback tool: POST to a non-redirecting page
JakeSCahill Jun 22, 2026
8115fe4
chore: bump server.json version to 2026.06.22+pr181-30a95eb (PR #181)
github-actions[bot] Jun 22, 2026
98217de
Restyle login interstitial to match Redpanda branding
JakeSCahill Jun 22, 2026
0eed4e9
chore: bump server.json version to 2026.06.22+pr181-7df642a (PR #181)
github-actions[bot] Jun 22, 2026
3d76b12
Move OAuth state to Neon Postgres (atomic one-time-use) behind STORE_…
JakeSCahill Jun 22, 2026
f9b49fb
chore: bump server.json version to 2026.06.22+pr181-d76fb89 (PR #181)
github-actions[bot] Jun 22, 2026
174ec6e
Apply suggestions from code review
JakeSCahill Jun 22, 2026
064c8dc
Trim MCP feedback form to the fields that matter
JakeSCahill Jun 22, 2026
00c2108
chore: bump server.json version to 2026.06.22+pr181-15a4023 (PR #181)
github-actions[bot] Jun 22, 2026
1dfc686
Forward authenticated identity to MCPcat analytics
JakeSCahill Jun 22, 2026
4cafeb1
chore: bump server.json version to 2026.06.22+pr181-279799e (PR #181)
github-actions[bot] Jun 22, 2026
85a966e
Fix MCPcat 'no user intent': initialize track() after tools
JakeSCahill Jun 22, 2026
5f59c9d
chore: bump server.json version to 2026.06.22+pr181-fb8ddf9 (PR #181)
github-actions[bot] Jun 22, 2026
5c07ee8
Add customContextDescription to MCPcat tool-call context
JakeSCahill Jun 22, 2026
9836c7d
chore: bump server.json version to 2026.06.22+pr181-b375857 (PR #181)
github-actions[bot] Jun 22, 2026
7e47e01
Merge remote-tracking branch 'origin/main' into feature/mcp-email-auth
JakeSCahill Jun 22, 2026
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
15 changes: 9 additions & 6 deletions home/modules/ROOT/attachments/api-feedback-registration.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@
<meta name="robots" content="noindex">
</head>
<body>
<!-- Hidden form to register API feedback endpoint with Netlify Forms -->
<!-- This form is never displayed but allows API submissions to be stored -->
<!-- Hidden form to register the MCP feedback endpoint with Netlify Forms. -->
<!-- Submitted only by the MCP server's submit_documentation_feedback tool -->
<!-- (never rendered to users). Keep fields in sync with the submitFeedback -->
<!-- call in netlify/functions/mcp.mjs. Netlify auto-records created_at + the -->
<!-- request user-agent, so we don't declare a timestamp/user-agent field. -->
<form name="api-feedback" netlify netlify-honeypot="bot-field" hidden>
<input type="text" name="page-path" />
<input type="text" name="feedback" />
<input type="text" name="referer" />
<input type="text" name="user-agent" />
<input type="text" name="timestamp" />
<input type="text" name="category" />
<input type="text" name="page-path" />
<input type="text" name="user-email" />
<input type="text" name="user-domain" />
<input type="text" name="bot-field" />
</form>
<p>This page registers the API feedback form with Netlify. It should not be visible to users.</p>
Expand Down
65 changes: 58 additions & 7 deletions home/modules/ROOT/pages/how-to-use-these-docs.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,33 @@ Redpanda provides a remote link:https://modelcontextprotocol.io[Model Context Pr
The MCP server is hosted at: `https://docs.redpanda.com/mcp`.
You can add this endpoint to any AI agent that supports MCP.

[#authentication]
==== Authentication

The MCP server uses OAuth. The first time you connect, your MCP client opens a browser and prompts you to sign in with your link:https://cloud.redpanda.com[Redpanda Cloud account^] (free to create). Your client then obtains an access token automatically and reuses it on future requests, so you only sign in once.

There's no token to copy or paste. Any MCP client that supports the standard MCP OAuth flow (including ChatGPT, Claude, Cursor, and VS Code) handles sign-in for you.

If you don't have a Redpanda Cloud account yet, you can link:https://cloud.redpanda.com/sign-up[create one for free^].

[NOTE]
====
*What we collect and why.* When you sign in, we receive your verified email address (and your organization, when available) from Redpanda Cloud, which we use to track documentation usage and attribute it to your organization. This may be shared with our customer and analytics systems and passed to our documentation search provider (Kapa) for usage attribution. For details, see our link:https://www.redpanda.com/legal/privacy-policy[Privacy Policy^].
====



You sign in once, and your MCP client keeps you signed in from then on. You don't need to manage, copy, or refresh anything yourself.

Here's what happens behind the scenes:

* When you sign in, your client receives a short-lived access token (valid for one hour) that it sends with each request.
* Before that hour is up, your client quietly swaps it for a fresh one in the background. This happens automatically, without opening a browser or asking you to sign in again, so you won't notice it.
* As long as you use the server at least once every 30 days, this renewal keeps going indefinitely and you stay signed in.
* If you don't use the server for 30 days, the renewal lapses. The next time you connect, your client prompts you to sign in again, which is usually a quick browser redirect because you're often still signed in to Redpanda Cloud.

In short: active users rarely, if ever, sign in again, and there's nothing to do manually. Token renewal is handled entirely by your MCP client.

[tabs]
====
Claude Code::
Expand All @@ -103,6 +130,8 @@ Run the following command to add the Redpanda MCP server to Claude Code:
claude mcp add --scope user --transport http redpanda https://docs.redpanda.com/mcp
----

The first time you use the server, Claude Code prompts you to authenticate with your Redpanda Cloud account in the browser.

This command:

* Adds the MCP server with the name `redpanda`.
Expand Down Expand Up @@ -138,6 +167,8 @@ Add the following to your `.cursor/mcp.json` file:
}
----

The first time you use the server, Cursor prompts you to sign in with your Redpanda Cloud account.

For more information about MCP in Cursor, see the https://docs.cursor.com/context/model-context-protocol[Cursor documentation^].
--
VS Code::
Expand All @@ -160,6 +191,8 @@ Create an `mcp.json` file in your workspace `.vscode` folder:
}
----

The first time you use the server, VS Code prompts you to sign in with your Redpanda Cloud account.

To configure globally for all workspaces:

. Open Command Palette (kbd:[Cmd+Shift+P] / kbd:[Ctrl+Shift+P])
Expand Down Expand Up @@ -188,7 +221,9 @@ ChatGPT Desktop supports MCP servers in developer mode. To enable:
+
- *Name*: `redpanda`
- *URL*: `https://docs.redpanda.com/mcp`
- *Authentication*: *OAuth*

ChatGPT discovers the OAuth flow automatically and prompts you to sign in with your Redpanda Cloud account.

For more information, see the https://platform.openai.com/docs/guides/developer-mode[ChatGPT Desktop MCP documentation^].
--
Expand All @@ -205,7 +240,7 @@ This method is available for Pro, Max, Team, or Enterprise plans and works acros
. Navigate to Settings > Connectors.
. Click *Add custom connector*.
. Enter the URL: `https://docs.redpanda.com/mcp`
. Follow any authentication prompts if required.
. When prompted, sign in with your Redpanda Cloud account. The connector completes the OAuth flow automatically.

NOTE: When using Connectors, Claude connects to your remote MCP server from Anthropic's cloud infrastructure.

Expand All @@ -232,7 +267,7 @@ Add the following configuration to your `claude_desktop_config.json` file:
}
----

This configuration uses the `mcp-remote` bridge to connect to Redpanda's remote MCP server. Claude Desktop supports only `stdio` and `sse` transports, so `mcp-remote` converts the HTTP endpoint to a compatible format.
This configuration uses the `mcp-remote` bridge to connect to Redpanda's remote MCP server. On first use, `mcp-remote` opens a browser for you to sign in with your Redpanda Cloud account. Claude Desktop supports only `stdio` and `sse` transports, so `mcp-remote` converts the HTTP endpoint to a compatible format.

Restart Claude Desktop for changes to take effect.

Expand All @@ -244,14 +279,14 @@ For more details, see the https://support.anthropic.com/en/articles/9487310-desk

==== Other AI tools

Any tool that supports MCP servers can connect using the following URL:
Any tool that supports the MCP OAuth flow can connect using the following URL and will prompt you to sign in with your Redpanda Cloud account on first use:

[source,text]
----
https://docs.redpanda.com/mcp
----

NOTE: MCP support varies by tool and version. Check the specific tool's documentation for MCP setup instructions.
NOTE: MCP support varies by tool and version. Check the specific tool's documentation for MCP setup instructions. See <<authentication>> for details on sign-in.

==== What you can do

Expand All @@ -264,13 +299,17 @@ Once connected, you can ask context-aware questions about Redpanda from within y
* "How do I monitor Redpanda cluster performance?"
* "What's the difference between Redpanda Cloud and self-hosted deployment?"

You can also *send feedback to the Redpanda team* through your AI client. If you hit a bug, a documentation gap, or anything unclear, tell your assistant something like "send feedback that this page is missing X" and it can submit it for us to review. If you're signed in, we can follow up with you.

==== Usage limits

To ensure fair use and performance for all users, the public MCP endpoint enforces the following rate limits per user:
To ensure fair use and performance for all users, the MCP endpoint enforces the following rate limits:

* *60 requests per 15 minutes*

As well as this global limit, the `ask_redpanda_question` tool proxies to an MCP server hosted by Kapa.ai, which enforces its own limits. See the link:https://docs.kapa.ai/integrations/mcp/overview#authentication[Kapa documentation^] for details.
When you're signed in, this limit is applied per user. Unauthenticated requests (during the rollout period) are limited per IP address.

As well as this limit, the `ask_redpanda_question` tool proxies to an MCP server hosted by Kapa.ai, which enforces its own limits. See the link:https://docs.kapa.ai/integrations/mcp/overview#authentication[Kapa documentation^] for details.

These limits are suitable for:

Expand All @@ -284,13 +323,25 @@ If you exceed the limit, you receive an HTTP 429 response with rate limit header
[source,text]
----
HTTP 429 Too Many Requests
RateLimit-Limit: 40
RateLimit-Limit: 60
RateLimit-Remaining: 0
RateLimit-Reset: <timestamp>
----

==== Troubleshooting

===== Authentication required (HTTP 401)

If you receive an `HTTP 401` response with an `authentication_required` error:

* Your MCP client should open a browser to sign in with your Redpanda Cloud account. If it doesn't, check that your client supports the MCP OAuth flow (most recent versions do).
* If you don't have a Redpanda Cloud account, link:https://cloud.redpanda.com/sign-up[create a free one^].
* If sign-in succeeded previously but you now see `401`, your client's token may have expired. Reconnect or restart the client to trigger a fresh sign-in.

===== Work account required (HTTP 403)

Any verified Redpanda Cloud account works by default, including personal email providers. If your organization has opted to restrict access to work email domains and you receive an `HTTP 403` with a `work_email_required` error, sign in with your work account instead.

===== Server not connecting

* Verify the URL is exactly: `https://docs.redpanda.com/mcp`.
Expand Down
52 changes: 52 additions & 0 deletions netlify/database/migrations/20260622110000_oauth_state.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-- OAuth transactional state for the docs MCP authorization server.
-- Applied to the Neon (Netlify DB) database used when STORE_BACKEND=neon.
-- Idempotent: safe to run repeatedly.
--
-- Scope: the one-time-use / transactional tables only. DCR-registered clients
-- stay on Netlify Blobs (plain persistence, not one-time-use).

-- In-flight authorization requests (consumed by DELETE … RETURNING).
CREATE TABLE IF NOT EXISTS auth_requests (
id uuid PRIMARY KEY,
client_id text NOT NULL,
client_redirect_uri text NOT NULL,
client_state text,
client_code_challenge text,
upstream_verifier text,
expires_at timestamptz NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_auth_requests_expires ON auth_requests (expires_at);

-- Authorization codes (one-time; consumed by atomic UPDATE … WHERE used=false).
CREATE TABLE IF NOT EXISTS auth_codes (
code text PRIMARY KEY,
client_id text NOT NULL,
client_redirect_uri text NOT NULL,
client_code_challenge text,
user_data jsonb NOT NULL,
used boolean NOT NULL DEFAULT false,
expires_at timestamptz NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_auth_codes_expires ON auth_codes (expires_at);

-- Refresh tokens, stored by hash (one-time; rotated via atomic UPDATE).
CREATE TABLE IF NOT EXISTS refresh_tokens (
hash text PRIMARY KEY,
family_id uuid NOT NULL,
client_id text NOT NULL,
user_data jsonb NOT NULL,
scope text,
used boolean NOT NULL DEFAULT false,
expires_at timestamptz NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_expires ON refresh_tokens (expires_at);
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_family ON refresh_tokens (family_id);

-- Refresh-token families (rotation lineage; revoked on reuse detection).
CREATE TABLE IF NOT EXISTS refresh_families (
id uuid PRIMARY KEY,
client_id text,
revoked boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
revoked_at timestamptz
);
42 changes: 42 additions & 0 deletions netlify/edge-functions/mcp-oauth-metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// OAuth 2.0 Protected Resource Metadata (RFC 9728) for the MCP server.
// MCP clients (ChatGPT, Claude, Cursor, …) fetch this to discover the
// authorization server. That AS is OUR OWN service (which federates the human
// login to the Redpanda Cloud IdP), so authorization_servers points back at
// this origin, where /.well-known/oauth-authorization-server lives.
// https://datatracker.ietf.org/doc/html/rfc9728

const CORS = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
};

export default async (request: Request) => {
// CORS preflight for browser-based MCP clients fetching the metadata.
if (request.method === "OPTIONS") {
return new Response(null, { status: 204, headers: { ...CORS, "Access-Control-Max-Age": "86400" } });
}

const origin = new URL(request.url).origin;

const metadata = {
resource: `${origin}/mcp`,
authorization_servers: [origin],
bearer_methods_supported: ["header"],
scopes_supported: ["openid", "email", "profile"],
resource_documentation: `${origin}/data-platform/how-to-use-these-docs#authentication`,
};

return new Response(JSON.stringify(metadata, null, 2), {
status: 200,
headers: {
"Content-Type": "application/json",
"Cache-Control": "public, max-age=3600",
...CORS,
},
});
};

export const config = {
path: "/.well-known/oauth-protected-resource",
};
12 changes: 10 additions & 2 deletions netlify/edge-functions/mcp-server-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export default async (request: Request) => {
$schema: "https://modelcontextprotocol.io/schemas/server-card.json",
serverInfo: {
name: "redpanda-doc-tools-assistant",
version: "1.0.0",
description: "MCP server for searching Redpanda documentation and querying API references"
version: "1.3.0",
description: "MCP server for searching Redpanda documentation, querying API references, and sending feedback to the Redpanda team"
},
transport: {
type: "http",
Expand All @@ -19,9 +19,17 @@ export default async (request: Request) => {
tools: true,
prompts: false
},
authentication: {
type: "oauth2",
required: false,
protected_resource_metadata: `${siteUrl}/.well-known/oauth-protected-resource`,
authorization_servers: [siteUrl],
description: "Sign in with your Redpanda Cloud account. MCP clients discover the OAuth flow via the protected-resource metadata and obtain a token automatically (this site is the authorization server; it federates login to Redpanda Cloud)."
},
metadata: {
homepage: `${siteUrl}`,
documentation: `${siteUrl}/current/home/`,
authDocumentation: `${siteUrl}/data-platform/how-to-use-these-docs#authentication`,
repository: "https://github.com/redpanda-data/docs-site",
support: "https://support.redpanda.com",
tags: ["documentation", "redpanda", "kafka", "streaming", "agentic data plane"]
Expand Down
Loading
Loading