diff --git a/local-antora-playbook.yml b/local-antora-playbook.yml index ac31ad1..bf4c453 100644 --- a/local-antora-playbook.yml +++ b/local-antora-playbook.yml @@ -11,13 +11,13 @@ urls: output: clean: true content: - sources: - - url: https://github.com/redpanda-data/adp-docs - branches: main + sources: + - url: . + branches: HEAD - url: https://github.com/redpanda-data/docs - branches: [main, v/*, api, shared, site-search,'!v-end-of-life/*'] + branches: [main, v/*, shared, site-search,'!v-end-of-life/*'] - url: https://github.com/redpanda-data/cloud-docs - branches: feature/remove-ai-agents + branches: main - url: https://github.com/redpanda-data/redpanda-labs branches: main start_paths: [docs,'*/docs'] diff --git a/modules/ROOT/nav.adoc b/modules/ROOT/nav.adoc index 21ac76a..ae2b7d5 100644 --- a/modules/ROOT/nav.adoc +++ b/modules/ROOT/nav.adoc @@ -23,24 +23,21 @@ **** xref:agents:tutorials/customer-support-agent.adoc[Customer support agent] **** xref:agents:tutorials/transaction-dispute-resolution.adoc[Transaction dispute resolution] * MCP Servers -** xref:mcp:overview.adoc[Overview] -*** Remote MCP -**** xref:mcp:remote/overview.adoc[Overview] -**** xref:mcp:remote/quickstart.adoc[Quickstart] -**** xref:mcp:remote/concepts.adoc[Concepts] -**** xref:mcp:remote/create-tool.adoc[Create tools] -**** xref:mcp:remote/register-external.adoc[Register a self-hosted server] -**** xref:mcp:remote/oauth-user-delegated.adoc[User-delegated OAuth] -**** xref:mcp:remote/patterns.adoc[Patterns] -**** xref:mcp:remote/best-practices.adoc[Best practices] -**** xref:mcp:remote/manage-servers.adoc[Manage servers] -**** xref:mcp:remote/monitor-mcp-servers.adoc[Monitor servers] -**** xref:mcp:remote/scale.adoc[Scaling] -**** xref:mcp:remote/troubleshooting.adoc[Troubleshooting] -*** Local MCP -**** xref:mcp:local/overview.adoc[Overview] -**** xref:mcp:local/quickstart.adoc[Quickstart] -**** xref:mcp:local/configuration.adoc[Configuration] +** xref:mcp:index.adoc[Overview] +** xref:mcp:create-server.adoc[Create a server] +** xref:mcp:register-remote.adoc[Register a self-managed server] +** xref:mcp:user-delegated-oauth.adoc[User-delegated OAuth] +** xref:mcp:test-tools.adoc[Test a server's tools] +** xref:mcp:managed-catalog.adoc[Managed catalog] +*** xref:mcp:managed/sql.adoc[SQL] +*** xref:mcp:managed/kafka.adoc[Kafka] +*** xref:mcp:managed/slack.adoc[Slack] +*** xref:mcp:managed/jira.adoc[Jira] +*** xref:mcp:managed/openapi.adoc[OpenAPI] +* Redpanda Cloud Management MCP Server +** xref:mcp:local/index.adoc[Overview] +** xref:mcp:local/quickstart.adoc[Quickstart] +** xref:mcp:local/configuration.adoc[Configuration] * AI Gateway ** xref:ai-gateway:overview.adoc[Overview] ** xref:ai-gateway:gateway-quickstart.adoc[Quickstart] diff --git a/modules/ROOT/pages/adp-overview.adoc b/modules/ROOT/pages/adp-overview.adoc index 3cb3a86..0d240ec 100644 --- a/modules/ROOT/pages/adp-overview.adoc +++ b/modules/ROOT/pages/adp-overview.adoc @@ -1,6 +1,6 @@ = Redpanda Agentic Data Plane Overview :description: Enterprise-grade infrastructure for building, deploying, and governing AI agents at scale with compliance-grade audit trails. -:page-aliases: redpanda-cloud:ai-agents:adp-overview.adoc +// TODO: Add 'redpanda-cloud:ai-agents:adp-overview.adoc' to page-aliases after ai-agents is removed from cloud-docs :page-topic-type: overview :page-categories: Agentic Data Plane :personas: evaluator, ai_agent_developer, platform_admin @@ -40,7 +40,7 @@ Under the hood, MCP servers wrap the same proven connectors that power some of t With over 300 connectors and real-time debugging capabilities, you reduce integration time while getting enterprise-grade security. You can reuse your existing infrastructure and data sources rather than building new integrations from scratch. -For more information, see xref:mcp:overview.adoc[MCP Servers Overview]. +For more information, see xref:mcp:index.adoc[MCP Servers Overview]. == Transcripts @@ -85,6 +85,6 @@ Some ways organizations can leverage Redpanda ADP include: == Next steps * xref:agents:overview.adoc[AI Agents Overview] -* xref:mcp:overview.adoc[MCP Server Overview] +* xref:mcp:index.adoc[MCP Server Overview] * xref:observability:concepts.adoc[Transcripts Overview] * xref:ai-gateway:overview.adoc[AI Gateway Overview] diff --git a/modules/agents/pages/architecture-patterns.adoc b/modules/agents/pages/architecture-patterns.adoc index 59aef91..a5b1571 100644 --- a/modules/agents/pages/architecture-patterns.adoc +++ b/modules/agents/pages/architecture-patterns.adoc @@ -167,7 +167,7 @@ This pattern fails because: * Tool descriptions compete for limited prompt space * The agent invokes wrong tools with similar names, wasting iteration budget on selection mistakes -Limit tools per agent to 10-15 for optimal performance. Agents with more than 20-25 tools often show degraded tool selection accuracy. Use subagents to partition tools by domain. For tool design patterns, see xref:mcp:remote/patterns.adoc[]. +Limit tools per agent to 10-15 for optimal performance. Agents with more than 20-25 tools often show degraded tool selection accuracy. Use subagents to partition tools by domain. For tool design patterns, see xref:mcp:index.adoc[]. === Premature A2A splitting @@ -259,6 +259,6 @@ Provide clear error messages to users. Log errors for debugging. * xref:integration-overview.adoc[] * xref:a2a-concepts.adoc[] -* xref:mcp:remote/patterns.adoc[] +* xref:mcp:index.adoc[] * xref:overview.adoc[] -* xref:mcp:remote/best-practices.adoc[] +* xref:mcp:index.adoc[] diff --git a/modules/agents/pages/concepts.adoc b/modules/agents/pages/concepts.adoc index 92c1e28..18605eb 100644 --- a/modules/agents/pages/concepts.adoc +++ b/modules/agents/pages/concepts.adoc @@ -132,7 +132,7 @@ Tool design affects agent behavior. Coarse-grained tools that do many things res Choose granularity based on how often you'll reuse tool logic across workflows, whether intermediate results help with debugging, and how much control you want over tool invocation order. -For tool design guidance, see xref:mcp:remote/best-practices.adoc[]. +For tool design guidance, see xref:mcp:index.adoc[]. == Context and state management @@ -159,4 +159,4 @@ include::ROOT:partial$service-account-authorization.adoc[] * xref:architecture-patterns.adoc[] * xref:quickstart.adoc[] * xref:system-prompts.adoc[] -* xref:mcp:remote/best-practices.adoc[] +* xref:mcp:index.adoc[] diff --git a/modules/agents/pages/create-agent.adoc b/modules/agents/pages/create-agent.adoc index 2c98757..9b701b0 100644 --- a/modules/agents/pages/create-agent.adoc +++ b/modules/agents/pages/create-agent.adoc @@ -20,7 +20,7 @@ After reading this page, you will be able to: * A xref:redpanda-cloud:get-started:cluster-types/byoc/index.adoc[BYOC cluster]. * xref:ai-gateway:gateway-quickstart.adoc[AI Gateway configured] with at least one LLM provider enabled. -* At least one xref:mcp:remote/overview.adoc[Remote MCP server] deployed with tools. +* At least one xref:mcp:index.adoc[Remote MCP server] deployed with tools. * System prompt prepared (see xref:system-prompts.adoc[System Prompt Best Practices]). == Access the agents UI @@ -276,6 +276,6 @@ Here are example configurations for different agent types: * xref:integration-overview.adoc[] * xref:system-prompts.adoc[] -* xref:mcp:remote/create-tool.adoc[] +* xref:mcp:create-server.adoc[] * xref:architecture-patterns.adoc[] * xref:troubleshoot.adoc[] diff --git a/modules/agents/pages/integration-overview.adoc b/modules/agents/pages/integration-overview.adoc index 4a44b7d..0897670 100644 --- a/modules/agents/pages/integration-overview.adoc +++ b/modules/agents/pages/integration-overview.adoc @@ -27,7 +27,7 @@ Redpanda Cloud supports three primary integration scenarios based on who initiat | Agent needs capabilities | Your agent invokes MCP tools to fetch data, call APIs, or access external systems on-demand | Agent-initiated, synchronous, interactive workflows -| xref:mcp:remote/patterns.adoc[] +| xref:mcp:index.adoc[] | Pipeline processes events | Your Redpanda Connect pipeline invokes agents for each event in a stream using the `a2a_message` processor @@ -55,7 +55,7 @@ This pattern works well for interactive workflows: customer support lookups, app Avoid MCP tools for high-volume stream processing or automated workflows without user interaction. Use pipeline-initiated integration instead. -For implementation details, see xref:mcp:remote/patterns.adoc[]. +For implementation details, see xref:mcp:index.adoc[]. [[pipeline-processes-events]] === Pipeline processes events (`a2a_message`) @@ -126,5 +126,5 @@ Access tokens grant full access to the agent. Anyone with a valid token can send == Next steps * xref:a2a-concepts.adoc[] -* xref:mcp:remote/patterns.adoc[] +* xref:mcp:index.adoc[] * xref:pipeline-integration-patterns.adoc[] diff --git a/modules/agents/pages/overview.adoc b/modules/agents/pages/overview.adoc index a45aa94..86bbc7c 100644 --- a/modules/agents/pages/overview.adoc +++ b/modules/agents/pages/overview.adoc @@ -27,7 +27,7 @@ When you create an agent, you configure the components through the Redpanda Clou * *System prompt*: Defines the agent's role, responsibilities, and constraints * *LLM*: Interprets user intent and decides which tools to invoke -* *Tools*: External capabilities exposed through the xref:mcp:remote/overview.adoc[Model Context Protocol (MCP)] +* *Tools*: External capabilities exposed through the xref:mcp:index.adoc[Model Context Protocol (MCP)] * *Context*: Conversation history, tool results, and real-time events from Redpanda topics Agents can invoke Redpanda Connect components as tools on-demand. Redpanda Connect pipelines can also invoke agents for event-driven processing. This bidirectional integration supports both interactive workflows and automated streaming. @@ -38,7 +38,7 @@ For a deeper understanding of how agents execute, manage context, and maintain s == Key benefits -A declarative approach means you configure agent behavior instead of coding it, with access to 300+ built-in Redpanda Connect connectors for data sources, APIs, and services. Real-time streaming data ensures agents access live events instead of batch snapshots. xref:mcp:remote/overview.adoc[Remote MCP] support enables standardized tool access. Managed infrastructure handles deployment, scaling, and security for you. Low-latency execution means tools run close to your data. Integrated secrets management securely stores API keys and credentials. +A declarative approach means you configure agent behavior instead of coding it, with access to 300+ built-in Redpanda Connect connectors for data sources, APIs, and services. Real-time streaming data ensures agents access live events instead of batch snapshots. xref:mcp:index.adoc[Remote MCP] support enables standardized tool access. Managed infrastructure handles deployment, scaling, and security for you. Low-latency execution means tools run close to your data. Integrated secrets management securely stores API keys and credentials. == Use cases diff --git a/modules/agents/pages/pipeline-integration-patterns.adoc b/modules/agents/pages/pipeline-integration-patterns.adoc index 8de16af..533eb69 100644 --- a/modules/agents/pages/pipeline-integration-patterns.adoc +++ b/modules/agents/pages/pipeline-integration-patterns.adoc @@ -139,7 +139,7 @@ This pipeline: == Next steps -* xref:mcp:remote/patterns.adoc[] +* xref:mcp:index.adoc[] * xref:integration-overview.adoc[] * xref:a2a-concepts.adoc[] * xref:redpanda-cloud:develop:connect/components/processors/about.adoc[] diff --git a/modules/agents/pages/quickstart.adoc b/modules/agents/pages/quickstart.adoc index 325f4b5..e144874 100644 --- a/modules/agents/pages/quickstart.adoc +++ b/modules/agents/pages/quickstart.adoc @@ -23,7 +23,7 @@ After completing this quickstart, you will be able to: * xref:ai-gateway:gateway-quickstart.adoc[AI Gateway configured] with at least one LLM provider enabled (OpenAI, Anthropic, or Google AI) -* Completed the xref:mcp:remote/quickstart.adoc[Remote MCP Quickstart] to create an MCP server with the following tools deployed: +* Completed the xref:mcp:create-server.adoc[Remote MCP Quickstart] to create an MCP server with the following tools deployed: + ** `generate_input`: Generates fake user event data ** `redpanda_output`: Publishes data to Redpanda topics @@ -185,4 +185,4 @@ You've created an agent that orchestrates MCP tools through natural language. Ex * xref:create-agent.adoc[] * xref:system-prompts.adoc[] * xref:architecture-patterns.adoc[] -* xref:mcp:remote/patterns.adoc[] +* xref:mcp:index.adoc[] diff --git a/modules/agents/pages/system-prompts.adoc b/modules/agents/pages/system-prompts.adoc index a4e81b2..8a67bf2 100644 --- a/modules/agents/pages/system-prompts.adoc +++ b/modules/agents/pages/system-prompts.adoc @@ -423,4 +423,4 @@ Decision criteria enable reliable tool selection based on request context. * xref:quickstart.adoc[] * xref:overview.adoc[] -* xref:mcp:remote/best-practices.adoc[] +* xref:mcp:index.adoc[] diff --git a/modules/agents/pages/troubleshoot.adoc b/modules/agents/pages/troubleshoot.adoc index adcc6b1..ad68c15 100644 --- a/modules/agents/pages/troubleshoot.adoc +++ b/modules/agents/pages/troubleshoot.adoc @@ -103,7 +103,7 @@ Use get_shipping_info when: **Prevention:** -* Follow tool design patterns in xref:mcp:remote/patterns.adoc[] +* Follow tool design patterns in xref:mcp:index.adoc[] * Limit each agent to 10-15 tools maximum * Test boundary cases where multiple tools might apply @@ -484,5 +484,5 @@ For comprehensive guidance on monitoring agent activity, analyzing conversation * xref:system-prompts.adoc[] * xref:concepts.adoc[] -* xref:mcp:remote/patterns.adoc[] +* xref:mcp:index.adoc[] * xref:architecture-patterns.adoc[] diff --git a/modules/agents/pages/tutorials/customer-support-agent.adoc b/modules/agents/pages/tutorials/customer-support-agent.adoc index a5d352a..fbaae16 100644 --- a/modules/agents/pages/tutorials/customer-support-agent.adoc +++ b/modules/agents/pages/tutorials/customer-support-agent.adoc @@ -269,7 +269,7 @@ Use these documented test IDs when testing the agent. If you replace the mock to == Next steps -* xref:mcp:remote/patterns.adoc#call-external-apis[Call external APIs] +* xref:mcp:index.adoc[Call external APIs] * xref:system-prompts.adoc[] * xref:architecture-patterns.adoc[] * xref:troubleshoot.adoc[] diff --git a/modules/agents/pages/tutorials/transaction-dispute-resolution.adoc b/modules/agents/pages/tutorials/transaction-dispute-resolution.adoc index c8e4d94..b15fc84 100644 --- a/modules/agents/pages/tutorials/transaction-dispute-resolution.adoc +++ b/modules/agents/pages/tutorials/transaction-dispute-resolution.adoc @@ -94,7 +94,7 @@ Wait for the server status to show *Running*. [NOTE] ==== -This tutorial uses XSmall resource tier for all MCP servers because the mock tools run lightweight Bloblang transformations. Production deployments with external API calls require larger tiers based on throughput needs. See xref:mcp:remote/scale.adoc[]. +This tutorial uses XSmall resource tier for all MCP servers because the mock tools run lightweight Bloblang transformations. Production deployments with external API calls require larger tiers based on throughput needs. See xref:mcp:index.adoc[]. ==== === Fraud tools @@ -662,4 +662,4 @@ For production deployments, replace the mock tools with API calls to your accoun * xref:integration-overview.adoc[] * xref:pipeline-integration-patterns.adoc[] * xref:monitor.adoc[] -* xref:mcp:remote/best-practices.adoc[] +* xref:mcp:index.adoc[] diff --git a/modules/ai-gateway/pages/overview.adoc b/modules/ai-gateway/pages/overview.adoc index fd67291..1711d88 100644 --- a/modules/ai-gateway/pages/overview.adoc +++ b/modules/ai-gateway/pages/overview.adoc @@ -2,7 +2,8 @@ :description: AI Gateway is Redpanda's managed proxy for LLM APIs. Create a provider for OpenAI, Anthropic, Google AI, AWS Bedrock, or an OpenAI-compatible endpoint, and point your applications at a Redpanda-hosted URL with managed secrets, authentication, and observability. :page-topic-type: overview :personas: platform_admin, app_developer, evaluator -:page-aliases: redpanda-cloud:ai-agents:ai-gateway/what-is-ai-gateway.adoc, redpanda-cloud:ai-agents:ai-gateway/gateway-architecture.adoc, redpanda-cloud:ai-agents:ai-gateway/cel-routing-cookbook.adoc, redpanda-cloud:ai-agents:ai-gateway/mcp-aggregation-guide.adoc, redpanda-cloud:ai-agents:ai-gateway/builders/discover-gateways.adoc +// TODO: Add 'redpanda-cloud:ai-agents:ai-gateway/what-is-ai-gateway.adoc' to page-aliases after ai-agents is removed from cloud-docs +:page-aliases: redpanda-cloud:ai-agents:ai-gateway/gateway-architecture.adoc, redpanda-cloud:ai-agents:ai-gateway/cel-routing-cookbook.adoc, redpanda-cloud:ai-agents:ai-gateway/mcp-aggregation-guide.adoc, redpanda-cloud:ai-agents:ai-gateway/builders/discover-gateways.adoc :learning-objective-1: Describe what AI Gateway is and how a managed proxy differs from direct upstream calls :learning-objective-2: Explain how LLM providers, secrets, and OIDC authentication fit together in AI Gateway :learning-objective-3: Identify use cases where AI Gateway fits, and use cases where it does not diff --git a/modules/mcp/doc-detective-create-server.json b/modules/mcp/doc-detective-create-server.json new file mode 100644 index 0000000..369fd9e --- /dev/null +++ b/modules/mcp/doc-detective-create-server.json @@ -0,0 +1,204 @@ +{ + "tests": [ + { + "testId": "create-managed-mcp-server", + "description": "Create a managed MCP server following the documented procedure", + "steps": [ + { + "description": "Navigate to ADP UI", + "goTo": "https://adp.redpanda.com" + }, + { + "description": "Verify user is on the ADP UI home page", + "find": "MCP Servers" + }, + { + "description": "Navigate to MCP Servers section", + "click": "MCP Servers" + }, + { + "description": "Verify MCP Servers page loaded", + "find": "Create Server" + }, + { + "description": "Click Create Server button to open marketplace picker", + "click": "Create Server" + }, + { + "description": "Verify marketplace picker opened", + "find": "Remote (Proxied)" + }, + { + "description": "Select a managed type card (SQL example)", + "click": "SQL" + }, + { + "description": "Verify server configuration form loaded", + "find": "Name" + }, + { + "description": "Enter server name (lowercase, hyphens, starts with letter)", + "type": { + "keys": "test-sql-server", + "selector": "input[name='name']" + } + }, + { + "description": "Enter server description", + "type": { + "keys": "Test SQL server for documentation testing", + "selector": "input[name='description']" + } + }, + { + "description": "Verify Enabled toggle is present", + "find": "Enabled" + }, + { + "description": "Configure authentication - select None mode", + "click": "None" + }, + { + "description": "Click Create button to save the server", + "click": "Create" + }, + { + "description": "Verify server was created and appears in list", + "find": "test-sql-server" + }, + { + "description": "Verify Type badge shows server type", + "find": "Managed" + } + ] + }, + { + "testId": "verify-mcp-server-details", + "description": "Verify server details and tool discovery after creation", + "steps": [ + { + "description": "Open the newly created server detail page", + "click": "test-sql-server" + }, + { + "description": "Verify Overview tab is shown", + "find": "Overview" + }, + { + "description": "Verify API URL is displayed", + "find": "API URL" + }, + { + "description": "Switch to Inspector tab", + "click": "Inspector" + }, + { + "description": "Verify Inspector tab loaded", + "find": "Tools" + }, + { + "description": "Verify tools list is populated (not empty)", + "find": "query" + } + ] + }, + { + "testId": "create-self-managed-mcp-server", + "description": "Create a self-managed (Remote/Proxied) MCP server", + "steps": [ + { + "description": "Navigate to MCP Servers section", + "goTo": "https://adp.redpanda.com/mcp-servers" + }, + { + "description": "Click Create Server button", + "click": "Create Server" + }, + { + "description": "Select Remote (Proxied) option for self-managed server", + "click": "Remote (Proxied)" + }, + { + "description": "Verify self-managed configuration form loaded", + "find": "URL" + }, + { + "description": "Enter server name", + "type": { + "keys": "test-remote-server", + "selector": "input[name='name']" + } + }, + { + "description": "Enter server URL (must start with http:// or https://)", + "type": { + "keys": "https://mcp-server.example.com", + "selector": "input[name='url']" + } + }, + { + "description": "Verify Transport field is present", + "find": "Transport" + }, + { + "description": "Select SSE transport", + "click": "SSE" + }, + { + "description": "Configure authentication - select None mode", + "click": "None" + }, + { + "description": "Click Create button", + "click": "Create" + }, + { + "description": "Verify self-managed server was created", + "find": "test-remote-server" + }, + { + "description": "Verify Type badge shows Self-managed", + "find": "Self-managed" + } + ] + }, + { + "testId": "verify-authentication-modes", + "description": "Verify all five authentication modes are available", + "steps": [ + { + "description": "Navigate to create server flow", + "goTo": "https://adp.redpanda.com/mcp-servers" + }, + { + "description": "Click Create Server", + "click": "Create Server" + }, + { + "description": "Select a managed type", + "click": "SQL" + }, + { + "description": "Verify None auth mode is available", + "find": "None" + }, + { + "description": "Verify Static key auth mode is available", + "find": "Static key" + }, + { + "description": "Verify Token passthrough auth mode is available", + "find": "Token passthrough" + }, + { + "description": "Verify Service-account OAuth auth mode is available", + "find": "Service-account OAuth" + }, + { + "description": "Verify User-delegated OAuth auth mode is available", + "find": "User-delegated OAuth" + } + ] + } + ] +} diff --git a/modules/mcp/doc-detective-test-tools.json b/modules/mcp/doc-detective-test-tools.json new file mode 100644 index 0000000..b0ad45f --- /dev/null +++ b/modules/mcp/doc-detective-test-tools.json @@ -0,0 +1,224 @@ +{ + "tests": [ + { + "testId": "use-inspector-test-tool", + "description": "Test an MCP server's tools using the Inspector following the documented procedure", + "steps": [ + { + "description": "Navigate to MCP Servers section", + "goTo": "https://adp.redpanda.com/mcp-servers" + }, + { + "description": "Verify MCP Servers page loaded", + "find": "MCP Servers" + }, + { + "description": "Click into an existing server (assumes test-sql-server from previous test)", + "click": "test-sql-server" + }, + { + "description": "Verify server detail page loaded", + "find": "Overview" + }, + { + "description": "Switch to Inspector tab", + "click": "Inspector" + }, + { + "description": "Verify Inspector tab loaded with four panels", + "find": "Tools" + }, + { + "description": "Verify Resources panel exists", + "find": "Resources" + }, + { + "description": "Verify Prompts panel exists", + "find": "Prompts" + }, + { + "description": "Verify Session panel exists", + "find": "Session" + } + ] + }, + { + "testId": "inspector-tools-panel-run-tool", + "description": "Select a tool, fill in parameters, and run it from the Tools panel", + "steps": [ + { + "description": "Navigate to Inspector tab (assumes already on server detail page)", + "click": "Inspector" + }, + { + "description": "Verify Tools panel is visible", + "find": "Tools" + }, + { + "description": "Select a tool from the list (example: query tool)", + "click": "query" + }, + { + "description": "Verify tool form rendered on right-hand pane", + "find": "Run" + }, + { + "description": "Fill in a tool parameter (example SQL query field)", + "type": { + "keys": "SELECT 1", + "selector": "textarea[name='query']" + } + }, + { + "description": "Click Run button to execute the tool", + "click": "Run" + }, + { + "description": "Verify response appears below the form", + "wait": 2000 + } + ] + }, + { + "testId": "inspector-verify-code-mode-tools", + "description": "Verify code-mode helper tools appear when code mode is enabled", + "steps": [ + { + "description": "Navigate to a server with code mode enabled", + "goTo": "https://adp.redpanda.com/mcp-servers/test-sql-server" + }, + { + "description": "Open Inspector tab", + "click": "Inspector" + }, + { + "description": "Verify _search helper tool exists", + "find": "_search" + }, + { + "description": "Verify _execute helper tool exists", + "find": "_execute" + } + ] + }, + { + "testId": "inspector-resources-panel", + "description": "Navigate and inspect resources in the Resources panel", + "steps": [ + { + "description": "Navigate to Inspector tab", + "click": "Inspector" + }, + { + "description": "Switch to Resources panel", + "click": "Resources" + }, + { + "description": "Verify Resources panel loaded", + "find": { + "selector": "[data-panel='resources']", + "timeout": 3000 + } + }, + { + "description": "Click a resource to load its content (if available)", + "wait": 1000 + } + ] + }, + { + "testId": "inspector-prompts-panel", + "description": "Navigate and test prompt templates in the Prompts panel", + "steps": [ + { + "description": "Navigate to Inspector tab", + "click": "Inspector" + }, + { + "description": "Switch to Prompts panel", + "click": "Prompts" + }, + { + "description": "Verify Prompts panel loaded", + "find": { + "selector": "[data-panel='prompts']", + "timeout": 3000 + } + }, + { + "description": "Click a prompt template (if available)", + "wait": 1000 + }, + { + "description": "Verify prompt form renders", + "find": "Run" + } + ] + }, + { + "testId": "inspector-session-history", + "description": "Verify session history panel tracks calls", + "steps": [ + { + "description": "Navigate to Inspector tab", + "click": "Inspector" + }, + { + "description": "Run a tool to generate session history", + "click": "query" + }, + { + "description": "Click Run button", + "click": "Run" + }, + { + "description": "Switch to Session panel", + "click": "Session" + }, + { + "description": "Verify session history shows the recent call", + "find": { + "selector": "[data-panel='session']", + "timeout": 3000 + } + }, + { + "description": "Verify request and response are logged", + "find": "request" + } + ] + }, + { + "testId": "inspector-oauth-connection-required-error", + "description": "Verify OAuthConnectionRequired error displays authorize_url", + "steps": [ + { + "description": "Navigate to a server with user-delegated OAuth (no stored token)", + "goTo": "https://adp.redpanda.com/mcp-servers/oauth-test-server" + }, + { + "description": "Open Inspector and run a tool", + "click": "Inspector" + }, + { + "description": "Select a tool", + "click": { + "selector": "[data-tool]:first-child" + } + }, + { + "description": "Click Run", + "click": "Run" + }, + { + "description": "Verify OAuthConnectionRequired error appears", + "find": "OAuthConnectionRequired" + }, + { + "description": "Verify authorize_url is shown in error detail", + "find": "authorize_url" + } + ] + } + ] +} diff --git a/modules/mcp/examples/mcp-tools/caches/memory_cache.yaml b/modules/mcp/examples/mcp-tools/caches/memory_cache.yaml deleted file mode 100644 index bf67ab8..0000000 --- a/modules/mcp/examples/mcp-tools/caches/memory_cache.yaml +++ /dev/null @@ -1,14 +0,0 @@ -label: memory_cache -memory: - default_ttl: "5m" - init_values: - "user:1001": '{"name": "Alice", "role": "admin"}' - "user:1002": '{"name": "Bob", "role": "user"}' - "config:theme": "dark" - "config:language": "en" - shards: 4 - -meta: - mcp: - enabled: true - description: "In-memory cache for storing user data, configuration, and temporary values" diff --git a/modules/mcp/examples/mcp-tools/caches/redpanda_cache.yaml b/modules/mcp/examples/mcp-tools/caches/redpanda_cache.yaml deleted file mode 100644 index 49be191..0000000 --- a/modules/mcp/examples/mcp-tools/caches/redpanda_cache.yaml +++ /dev/null @@ -1,15 +0,0 @@ -label: redpanda_cache -redpanda: - seed_brokers: ["${REDPANDA_BROKERS}"] - topic: "mcp-cache-topic" - tls: - enabled: true - sasl: - - mechanism: "SCRAM-SHA-512" - username: "${secrets.MCP_REDPANDA_CREDENTIALS.username}" - password: "${secrets.MCP_REDPANDA_CREDENTIALS.password}" - -meta: - mcp: - enabled: true - description: "Redpanda-backed distributed cache using Kafka topics for persistence" diff --git a/modules/mcp/examples/mcp-tools/caches/session_cache.yaml b/modules/mcp/examples/mcp-tools/caches/session_cache.yaml deleted file mode 100644 index 851773d..0000000 --- a/modules/mcp/examples/mcp-tools/caches/session_cache.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# In-memory cache for session data -# Example of cache tool -# tag::complete[] -label: session-cache - -memory: - default_ttl: 300s - -meta: - mcp: - enabled: true - description: "In-memory cache for session data" -# end::complete[] diff --git a/modules/mcp/examples/mcp-tools/inputs/consume_redpanda.yaml b/modules/mcp/examples/mcp-tools/inputs/consume_redpanda.yaml deleted file mode 100644 index 841dd5a..0000000 --- a/modules/mcp/examples/mcp-tools/inputs/consume_redpanda.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# Consume events from Redpanda topics -# Use for event-driven AI agents, audit logs, or data change streams -label: consume-events - -# tag::component[] -redpanda: - seed_brokers: [ "${REDPANDA_BROKERS}" ] - topics: [ "user-events" ] - consumer_group: "mcp-event-processor" - start_from_oldest: true - tls: - enabled: true - sasl: - - mechanism: "${REDPANDA_SASL_MECHANISM}" - username: "${REDPANDA_SASL_USERNAME}" - password: "${REDPANDA_SASL_PASSWORD}" -# end::component[] - -meta: - mcp: - enabled: true - description: "Consume events from user-events topic" diff --git a/modules/mcp/examples/mcp-tools/inputs/event_driven_workflow.yaml b/modules/mcp/examples/mcp-tools/inputs/event_driven_workflow.yaml deleted file mode 100644 index f549f88..0000000 --- a/modules/mcp/examples/mcp-tools/inputs/event_driven_workflow.yaml +++ /dev/null @@ -1,39 +0,0 @@ -# Event-driven workflow orchestration -# Use for multi-step processes, saga patterns, microservice coordination -label: order-workflow - -# tag::component[] -redpanda: - seed_brokers: [ "${REDPANDA_BROKERS}" ] - topics: [ "order-events" ] - consumer_group: "workflow-orchestrator" - tls: - enabled: true - sasl: - - mechanism: "${REDPANDA_SASL_MECHANISM}" - username: "${REDPANDA_SASL_USERNAME}" - password: "${REDPANDA_SASL_PASSWORD}" - processors: - - switch: - - check: this.event_type == "order_created" - processors: - - http: - url: "${secrets.INVENTORY_API}/reserve" - verb: POST - headers: - Content-Type: application/json - body: '{"order_id": "${! this.order_id }", "items": ${! json("items") }}' - - check: this.event_type == "payment_confirmed" - processors: - - http: - url: "${secrets.FULFILLMENT_API}/ship" - verb: POST - headers: - Content-Type: application/json - body: '{"order_id": "${! this.order_id }"}' -# end::component[] - -meta: - mcp: - enabled: true - description: "Process order events and orchestrate fulfillment workflow" diff --git a/modules/mcp/examples/mcp-tools/inputs/generate_input.yaml b/modules/mcp/examples/mcp-tools/inputs/generate_input.yaml deleted file mode 100644 index 0c81061..0000000 --- a/modules/mcp/examples/mcp-tools/inputs/generate_input.yaml +++ /dev/null @@ -1,22 +0,0 @@ -label: generate_input -generate: - mapping: | - let event_type = ["login", "logout", "purchase", "view_page", "click_button"].index(random_int(max:4)) - root = { - "id": uuid_v4(), - "timestamp": now().ts_format("2006-01-02T15:04:05.000Z"), - "user_id": random_int(min:1, max:10000), - "event_type": $event_type, - "data": { - "session_id": ksuid(), - "ip_address": "192.168.%v.%v".format(random_int(max:255), random_int(min:1, max:254)), - "user_agent": ["Chrome", "Firefox", "Safari", "Edge"].index(random_int(max:3)), - "amount": if $event_type == "purchase" { random_int(min:10, max:500) } else { null } - } - } - -meta: - mcp: - enabled: true - description: "Generate an example user event message with realistic data" - properties: [] diff --git a/modules/mcp/examples/mcp-tools/inputs/read_events.yaml b/modules/mcp/examples/mcp-tools/inputs/read_events.yaml deleted file mode 100644 index 8627214..0000000 --- a/modules/mcp/examples/mcp-tools/inputs/read_events.yaml +++ /dev/null @@ -1,21 +0,0 @@ -# Read events from Redpanda -# Example of input tool -# tag::complete[] -label: read-events - -redpanda: # <1> - seed_brokers: ["${REDPANDA_BROKERS}"] - topics: ["events"] - consumer_group: "mcp-reader" - tls: - enabled: true - sasl: - - mechanism: SCRAM-SHA-256 - username: "${secrets.MCP_USERNAME}" - password: "${secrets.MCP_PASSWORD}" - -meta: - mcp: - enabled: true - description: "Read events from Redpanda" -# end::complete[] diff --git a/modules/mcp/examples/mcp-tools/inputs/stream_processing.yaml b/modules/mcp/examples/mcp-tools/inputs/stream_processing.yaml deleted file mode 100644 index 9eb5209..0000000 --- a/modules/mcp/examples/mcp-tools/inputs/stream_processing.yaml +++ /dev/null @@ -1,28 +0,0 @@ -# Process streaming data with aggregations -# Use for real-time analytics, windowed aggregations, computing metrics -label: process-sensor-data - -# tag::component[] -redpanda: - seed_brokers: [ "${REDPANDA_BROKERS}" ] - topics: [ "sensor-readings" ] - consumer_group: "analytics-processor" - tls: - enabled: true - sasl: - - mechanism: "${REDPANDA_SASL_MECHANISM}" - username: "${REDPANDA_SASL_USERNAME}" - password: "${REDPANDA_SASL_PASSWORD}" - processors: - - mapping: | - root.sensor_id = this.sensor_id - root.avg_temperature = this.readings.map_each(r -> r.temperature).sum() / this.readings.length() - root.max_temperature = this.readings.map_each(r -> r.temperature).max() - root.reading_count = this.readings.length() - root.window_end = now() -# end::component[] - -meta: - mcp: - enabled: true - description: "Process sensor readings and compute aggregations" diff --git a/modules/mcp/examples/mcp-tools/outputs/publish_event.yaml b/modules/mcp/examples/mcp-tools/outputs/publish_event.yaml deleted file mode 100644 index 748aea0..0000000 --- a/modules/mcp/examples/mcp-tools/outputs/publish_event.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# Publish event to Redpanda -# Example of output tool -# tag::complete[] -label: publish-event - -redpanda: - seed_brokers: ["${REDPANDA_BROKERS}"] - topic: "processed-events" - tls: - enabled: true - sasl: - - mechanism: SCRAM-SHA-256 - username: "${secrets.MCP_USERNAME}" - password: "${secrets.MCP_PASSWORD}" - -meta: - mcp: - enabled: true - description: "Publish event to Redpanda" -# end::complete[] diff --git a/modules/mcp/examples/mcp-tools/outputs/publish_with_timestamp.yaml b/modules/mcp/examples/mcp-tools/outputs/publish_with_timestamp.yaml deleted file mode 100644 index 93fcd82..0000000 --- a/modules/mcp/examples/mcp-tools/outputs/publish_with_timestamp.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# Publish event with timestamp -# Example of output tool with processors -# tag::complete[] -label: publish-with-timestamp - -processors: - - mutation: | - root = this - root.published_at = now() - -redpanda: - seed_brokers: ["${REDPANDA_BROKERS}"] - topic: "processed-events" - tls: - enabled: true - sasl: - - mechanism: SCRAM-SHA-256 - username: "${secrets.MCP_USERNAME}" - password: "${secrets.MCP_PASSWORD}" - -meta: - mcp: - enabled: true - description: "Add timestamp and publish to Redpanda" -# end::complete[] diff --git a/modules/mcp/examples/mcp-tools/outputs/redpanda_output.yaml b/modules/mcp/examples/mcp-tools/outputs/redpanda_output.yaml deleted file mode 100644 index 324b135..0000000 --- a/modules/mcp/examples/mcp-tools/outputs/redpanda_output.yaml +++ /dev/null @@ -1,25 +0,0 @@ -label: redpanda_output -redpanda: - seed_brokers: - - ${REDPANDA_BROKERS} - topic: ${! this.topic_name.string().catch("default-topic") } - timeout: 30s - tls: - enabled: true - sasl: - - mechanism: SCRAM-SHA-256 - username: ${secrets.REDPANDA_USERNAME} - password: ${secrets.REDPANDA_PASSWORD} -meta: - mcp: - enabled: true - description: Publishes a message to a specified Redpanda topic - properties: - - name: message - type: string - description: The message content to publish - required: true - - name: topic_name - type: string - description: The Redpanda topic to publish to - required: true diff --git a/modules/mcp/examples/mcp-tools/outputs/redpanda_output_with_processors.yaml b/modules/mcp/examples/mcp-tools/outputs/redpanda_output_with_processors.yaml deleted file mode 100644 index 30e4a38..0000000 --- a/modules/mcp/examples/mcp-tools/outputs/redpanda_output_with_processors.yaml +++ /dev/null @@ -1,31 +0,0 @@ -label: summarize_and_publish - -processors: - - openai_chat_completion: - api_key: "${secrets.OPENAI_API_KEY}" - model: "gpt-5.2" - prompt: ${! json("question") } - - mapping: | - root.question = this.question - root.answer = this.content - root.timestamp = now().ts_format("2006-01-02T15:04:05Z07:00") - -redpanda: - seed_brokers: [ "${REDPANDA_BROKERS}" ] - topic: "llm-responses" - tls: - enabled: true - sasl: - - mechanism: SCRAM-SHA-256 - username: "${secrets.MCP_USERNAME}" - password: "${secrets.MCP_PASSWORD}" - -meta: - mcp: - enabled: true - description: "Process a question through an LLM and publish the response to Redpanda" - properties: - - name: question - type: string - description: "The question to send to the LLM" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/calculate_fraud_score.yaml b/modules/mcp/examples/mcp-tools/processors/calculate_fraud_score.yaml deleted file mode 100644 index 280ddef..0000000 --- a/modules/mcp/examples/mcp-tools/processors/calculate_fraud_score.yaml +++ /dev/null @@ -1,108 +0,0 @@ -label: calculate_fraud_score -mapping: | - root = match { - this.transaction_id == "TXN-89012" && this.customer_id == "CUST-1001" => { - "transaction_id": "TXN-89012", - "customer_id": "CUST-1001", - "fraud_score": 95, - "risk_level": "critical", - "score_breakdown": { - "location_risk": 35, - "merchant_risk": 30, - "amount_risk": 25, - "velocity_risk": 0, - "category_risk": 20 - }, - "factors_detected": [ - "unusual_location", - "questionable_merchant", - "unusual_amount", - "unusual_category" - ], - "reasoning": "International transaction from Singapore with no customer history of international purchases. High-value jewelry purchase (14.5x customer average). Merchant has significant fraud indicators.", - "recommendation": "block_and_investigate" - }, - this.transaction_id == "TXN-89013" && this.customer_id == "CUST-1001" => { - "transaction_id": "TXN-89013", - "customer_id": "CUST-1001", - "fraud_score": 8, - "risk_level": "minimal", - "score_breakdown": { - "location_risk": 0, - "merchant_risk": 0, - "amount_risk": 0, - "velocity_risk": 0, - "category_risk": 0 - }, - "factors_detected": [], - "reasoning": "Local transaction from trusted merchant in customer's typical spending category and amount range.", - "recommendation": "approve" - }, - this.transaction_id == "TXN-89014" && this.customer_id == "CUST-1002" => { - "transaction_id": "TXN-89014", - "customer_id": "CUST-1002", - "fraud_score": 52, - "risk_level": "medium", - "score_breakdown": { - "location_risk": 0, - "merchant_risk": 15, - "amount_risk": 0, - "velocity_risk": 8, - "category_risk": 0 - }, - "factors_detected": [ - "questionable_merchant", - "high_velocity" - ], - "reasoning": "Recurring subscription service with known billing issues. Multiple charges detected from same merchant. Moderate merchant reputation score.", - "recommendation": "monitor_closely" - }, - this.transaction_id == "TXN-89015" && this.customer_id == "CUST-1003" => { - "transaction_id": "TXN-89015", - "customer_id": "CUST-1003", - "fraud_score": 12, - "risk_level": "minimal", - "score_breakdown": { - "location_risk": 0, - "merchant_risk": 0, - "amount_risk": 5, - "velocity_risk": 0, - "category_risk": 0 - }, - "factors_detected": [ - "slightly_elevated_amount" - ], - "reasoning": "International hotel charge consistent with customer's frequent travel patterns. Amount within expected range for lodging category.", - "recommendation": "approve" - }, - _ => { - "transaction_id": this.transaction_id, - "customer_id": this.customer_id, - "fraud_score": 50, - "risk_level": "medium", - "score_breakdown": { - "location_risk": 0, - "merchant_risk": 0, - "amount_risk": 0, - "velocity_risk": 0, - "category_risk": 0 - }, - "factors_detected": [], - "reasoning": "Insufficient data to calculate accurate fraud score for this transaction/customer combination.", - "recommendation": "monitor_closely" - } - } - -meta: - mcp: - enabled: true - description: "Calculate fraud risk score based on transaction patterns and risk indicators. Use TXN-89012 through TXN-89015 with corresponding customer IDs for testing." - properties: - - name: transaction_id - type: string - description: "Transaction identifier to analyze (format TXN-XXXXX)" - required: true - - name: customer_id - type: string - description: "Customer identifier for historical analysis (format CUST-XXXX)" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/check_regulatory_requirements.yaml b/modules/mcp/examples/mcp-tools/processors/check_regulatory_requirements.yaml deleted file mode 100644 index f8df06e..0000000 --- a/modules/mcp/examples/mcp-tools/processors/check_regulatory_requirements.yaml +++ /dev/null @@ -1,116 +0,0 @@ -label: check_regulatory_requirements -mapping: | - root = match { - this.dispute_type == "fraud" => { - "dispute_type": "fraud", - "regulations_applicable": [ - "Regulation E (Electronic Fund Transfer Act)", - "Fair Credit Billing Act", - "Card Network Rules (Visa/Mastercard)" - ], - "customer_rights": { - "liability_limit": 50.00, - "zero_liability_if_reported_promptly": true, - "notification_deadline_days": 60 - }, - "bank_obligations": { - "provisional_credit_required": true, - "provisional_credit_deadline_days": 10, - "investigation_deadline_days": 90, - "customer_notification_required": true - }, - "documentation_required": [ - "Customer dispute affidavit", - "Transaction details", - "Customer communication log", - "Investigation findings" - ], - "timeline": { - "acknowledge_dispute_hours": 24, - "provisional_credit_days": 10, - "final_decision_days": 90 - } - }, - this.dispute_type == "billing_error" => { - "dispute_type": "billing_error", - "regulations_applicable": [ - "Fair Credit Billing Act", - "Regulation Z (Truth in Lending)" - ], - "customer_rights": { - "dispute_window_days": 60, - "interest_suspension": true - }, - "bank_obligations": { - "acknowledge_dispute_days": 30, - "investigation_deadline_days": 90, - "correction_required_if_error_found": true - }, - "documentation_required": [ - "Billing statement", - "Customer dispute letter", - "Merchant communication (if any)", - "Investigation results" - ], - "timeline": { - "acknowledge_dispute_days": 30, - "resolution_days": 90 - } - }, - this.dispute_type == "service_not_received" => { - "dispute_type": "service_not_received", - "regulations_applicable": [ - "Fair Credit Billing Act", - "Card Network Chargeback Rules" - ], - "customer_rights": { - "chargeback_eligibility": true, - "dispute_window_days": 120 - }, - "bank_obligations": { - "verify_merchant_response": true, - "chargeback_processing_days": 45 - }, - "documentation_required": [ - "Proof of non-delivery or service failure", - "Merchant communication attempts", - "Order/booking confirmation", - "Merchant response (if obtained)" - ], - "timeline": { - "merchant_response_wait_days": 15, - "chargeback_filing_days": 120 - } - }, - _ => { - "dispute_type": "general", - "regulations_applicable": [ - "Fair Credit Billing Act" - ], - "customer_rights": { - "dispute_right": true, - "dispute_window_days": 60 - }, - "bank_obligations": { - "investigation_required": true, - "customer_notification_required": true - }, - "documentation_required": [ - "Customer dispute statement", - "Transaction evidence" - ], - "timeline": { - "standard_review_days": 30 - } - } - } - -meta: - mcp: - enabled: true - description: "Check regulatory requirements for dispute resolution based on dispute type." - properties: - - name: dispute_type - type: string - description: "Type of dispute (fraud, billing_error, service_not_received)" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/customer_enrichment.yaml b/modules/mcp/examples/mcp-tools/processors/customer_enrichment.yaml deleted file mode 100644 index 2096248..0000000 --- a/modules/mcp/examples/mcp-tools/processors/customer_enrichment.yaml +++ /dev/null @@ -1,39 +0,0 @@ -label: customer_enrichment -processors: - - label: fetch_customer_base - sql_select: - driver: "postgres" - dsn: "${secrets.POSTGRES_DSN}" - table: "customers" - where: "customer_id = ?" - args_mapping: 'root = [this.customer_id]' - - - label: enrich_with_orders - sql_select: - driver: "postgres" - dsn: "${secrets.POSTGRES_DSN}" - table: "orders" - where: "customer_id = ? AND created_at >= NOW() - INTERVAL '30 days'" - args_mapping: 'root = [this.customer_id]' - - - label: combine_data - mutation: | - root = { - "customer": this.customers.index(0), - "recent_orders": this.orders, - "metrics": { - "total_orders": this.orders.length(), - "total_spent": this.orders.map_each(o -> o.total).sum(), - "avg_order_value": this.orders.map_each(o -> o.total).mean() - } - } - -meta: - mcp: - enabled: true - description: "Get comprehensive customer profile with recent order history and metrics" - properties: - - name: customer_id - type: string - description: "Customer ID to analyze" - required: true \ No newline at end of file diff --git a/modules/mcp/examples/mcp-tools/processors/enrich_order.yaml b/modules/mcp/examples/mcp-tools/processors/enrich_order.yaml deleted file mode 100644 index 604f1da..0000000 --- a/modules/mcp/examples/mcp-tools/processors/enrich_order.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# Enrich order with customer data -# Example of processor tool with HTTP call -# tag::complete[] -label: enrich-order - -processors: - - http: - url: "https://api.example.com/lookup" - verb: GET - -meta: - mcp: - enabled: true - description: "Enrich order with customer data" -# end::complete[] diff --git a/modules/mcp/examples/mcp-tools/processors/gcp_bigquery_select_processor.yaml b/modules/mcp/examples/mcp-tools/processors/gcp_bigquery_select_processor.yaml deleted file mode 100644 index c662058..0000000 --- a/modules/mcp/examples/mcp-tools/processors/gcp_bigquery_select_processor.yaml +++ /dev/null @@ -1,45 +0,0 @@ -label: gcp_bigquery_select_processor -processors: - - label: prepare_parameters - mutation: | - meta customer_id = this.customer_id.string().catch("12345") - meta limit = this.limit.number().catch(10) - - label: query_bigquery - gcp_bigquery_select: - project: my-gcp-project - credentials_json: | - ${secrets.BIGQUERY_CREDENTIALS} - table: my_dataset.customer_orders - columns: - - "order_id" - - "customer_id" - - "order_date" - - "total_amount" - - "status" - where: customer_id = ? AND order_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY) - suffix: "ORDER BY order_date DESC LIMIT ?" - args_mapping: root = [ @customer_id, @limit ] - - label: format_response - mutation: | - root = { - "orders": this, - "metadata": { - "source": "BigQuery", - "customer_id": @customer_id, - "fetched_at": now().ts_format("2006-01-02T15:04:05.000Z") - } - } - -meta: - mcp: - enabled: true - description: "Query customer orders from BigQuery" - properties: - - name: customer_id - type: string - description: "Customer ID to filter orders" - required: true - - name: limit - type: number - description: "Maximum number of orders to return" - required: false diff --git a/modules/mcp/examples/mcp-tools/processors/get_customer_account.yaml b/modules/mcp/examples/mcp-tools/processors/get_customer_account.yaml deleted file mode 100644 index 9701bb2..0000000 --- a/modules/mcp/examples/mcp-tools/processors/get_customer_account.yaml +++ /dev/null @@ -1,51 +0,0 @@ -label: get_customer_account -mapping: | - root = match { - this.customer_id == "CUST-1001" => { - "customer_id": "CUST-1001", - "name": "Dana A.", - "email": "s****@example.com", - "account_type": "premium_checking", - "card_last_four": "4532", - "card_status": "active", - "member_since": "2019-03-15", - "location": "Seattle, WA, USA", - "phone_masked": "***-***-7890" - }, - this.customer_id == "CUST-1002" => { - "customer_id": "CUST-1002", - "name": "Alex T.", - "email": "m****@example.com", - "account_type": "standard_checking", - "card_last_four": "8821", - "card_status": "active", - "member_since": "2021-07-22", - "location": "San Francisco, CA, USA", - "phone_masked": "***-***-4521" - }, - this.customer_id == "CUST-1003" => { - "customer_id": "CUST-1003", - "name": "Quinn N.", - "email": "e****@example.com", - "account_type": "premium_credit", - "card_last_four": "2193", - "card_status": "active", - "member_since": "2020-11-08", - "location": "Austin, TX, USA", - "phone_masked": "***-***-3344" - }, - _ => { - "error": "customer_not_found", - "message": "No account found for customer ID: " + this.customer_id - } - } - -meta: - mcp: - enabled: true - description: "Retrieve customer account information with masked PII. Use CUST-1001, CUST-1002, or CUST-1003 for testing." - properties: - - name: customer_id - type: string - description: "Customer identifier (format CUST-XXXX)" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/get_customer_history.yaml b/modules/mcp/examples/mcp-tools/processors/get_customer_history.yaml deleted file mode 100644 index 183e4f8..0000000 --- a/modules/mcp/examples/mcp-tools/processors/get_customer_history.yaml +++ /dev/null @@ -1,38 +0,0 @@ -label: get_customer_history - -processors: - - mapping: | - let customer_id = this.customer_id - root = if $customer_id == "CUST-100" { - { - "customer_id": $customer_id, - "orders": [ - {"order_id": "ORD-12345", "status": "shipped", "total": 1299.99, "order_date": "2025-01-10"}, - {"order_id": "ORD-67890", "status": "processing", "total": 299.98, "order_date": "2025-01-14"}, - {"order_id": "ORD-11111", "status": "delivered", "total": 89.99, "order_date": "2024-12-20"} - ], - "total_orders": 3 - } - } else if $customer_id == "CUST-999" { - { - "customer_id": $customer_id, - "orders": [], - "total_orders": 0, - "message": "No orders found for this customer" - } - } else { - { - "error": true, - "message": "Customer not found" - } - } - -meta: - mcp: - enabled: true - description: "Retrieve order history. Use CUST-100 (has orders) or CUST-999 (no orders) for testing." - properties: - - name: customer_id - type: string - description: "The customer ID (format CUST-XXX)" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/get_merchant_category.yaml b/modules/mcp/examples/mcp-tools/processors/get_merchant_category.yaml deleted file mode 100644 index f8ac390..0000000 --- a/modules/mcp/examples/mcp-tools/processors/get_merchant_category.yaml +++ /dev/null @@ -1,90 +0,0 @@ -label: get_merchant_category -mapping: | - root = match { - this.mcc == "5944" => { - "mcc": "5944", - "category": "Jewelry, Watch, Clock, and Silverware Stores", - "high_level_category": "retail_luxury", - "risk_profile": "high", - "typical_transaction_range": { - "min": 100, - "max": 5000, - "average": 850 - }, - "fraud_risk_notes": "High-value items, common fraud target, verify customer intent", - "common_fraud_patterns": [ - "Stolen card purchases", - "Account takeover", - "Reshipping schemes" - ] - }, - this.mcc == "5942" => { - "mcc": "5942", - "category": "Book Stores", - "high_level_category": "retail_general", - "risk_profile": "low", - "typical_transaction_range": { - "min": 10, - "max": 200, - "average": 45 - }, - "fraud_risk_notes": "Low fraud risk, common online purchase category", - "common_fraud_patterns": [] - }, - this.mcc == "4899" => { - "mcc": "4899", - "category": "Cable, Satellite, and Other Pay Television and Radio Services", - "high_level_category": "subscription_services", - "risk_profile": "medium", - "typical_transaction_range": { - "min": 9.99, - "max": 99.99, - "average": 29.99 - }, - "fraud_risk_notes": "Recurring billing, watch for duplicate charges and unauthorized subscriptions", - "common_fraud_patterns": [ - "Duplicate subscriptions", - "Unauthorized recurring charges", - "Failed cancellation processing" - ] - }, - this.mcc == "7011" => { - "mcc": "7011", - "category": "Lodging - Hotels, Motels, Resorts", - "high_level_category": "travel_hospitality", - "risk_profile": "medium", - "typical_transaction_range": { - "min": 80, - "max": 500, - "average": 180 - }, - "fraud_risk_notes": "Verify travel patterns, check for location consistency", - "common_fraud_patterns": [ - "Stolen card at booking sites", - "Account takeover for rewards redemption" - ] - }, - _ => { - "mcc": this.mcc, - "category": "Unknown Category", - "high_level_category": "unclassified", - "risk_profile": "unknown", - "typical_transaction_range": { - "min": 0, - "max": 0, - "average": 0 - }, - "fraud_risk_notes": "MCC not recognized, manual review recommended", - "common_fraud_patterns": [] - } - } - -meta: - mcp: - enabled: true - description: "Retrieve merchant category information including fraud risk level and common patterns based on MCC code." - properties: - - name: mcc - type: string - description: "Merchant Category Code (5944 for jewelry, 5942 for books, 4899 for streaming, 7011 for hotels)" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/get_order_status.yaml b/modules/mcp/examples/mcp-tools/processors/get_order_status.yaml deleted file mode 100644 index 55c9627..0000000 --- a/modules/mcp/examples/mcp-tools/processors/get_order_status.yaml +++ /dev/null @@ -1,46 +0,0 @@ -label: get_order_status -mapping: | - let order_id = this.order_id - root = if $order_id == "ORD-12345" { - { - "order_id": $order_id, - "status": "shipped", - "items": [{"name": "Laptop", "quantity": 1, "price": 1299.99}], - "total": 1299.99, - "order_date": "2025-01-10", - "customer_id": "CUST-100" - } - } else if $order_id == "ORD-67890" { - { - "order_id": $order_id, - "status": "processing", - "items": [{"name": "Headphones", "quantity": 2, "price": 149.99}], - "total": 299.98, - "order_date": "2025-01-14", - "customer_id": "CUST-100" - } - } else if $order_id == "ORD-99999" { - { - "error": "order_not_found", - "message": "Order not found" - } - } else { - { - "order_id": $order_id, - "status": "pending", - "items": [{"name": "Generic Item", "quantity": 1, "price": 49.99}], - "total": 49.99, - "order_date": "2025-01-15", - "customer_id": "CUST-999" - } - } - -meta: - mcp: - enabled: true - description: "Retrieve order status and details. Use ORD-12345 (shipped), ORD-67890 (processing), or ORD-99999 (not found) for testing." - properties: - - name: order_id - type: string - description: "The order ID (format ORD-XXXXX)" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/get_risk_indicators.yaml b/modules/mcp/examples/mcp-tools/processors/get_risk_indicators.yaml deleted file mode 100644 index c4ccdf1..0000000 --- a/modules/mcp/examples/mcp-tools/processors/get_risk_indicators.yaml +++ /dev/null @@ -1,129 +0,0 @@ -label: get_risk_indicators -mapping: | - root = match { - this.transaction_id == "TXN-89012" => { - "transaction_id": "TXN-89012", - "risk_indicators": [ - { - "indicator": "international_transaction", - "severity": "high", - "description": "Transaction originated from Singapore, customer has no international transaction history" - }, - { - "indicator": "first_time_merchant", - "severity": "medium", - "description": "Customer has never transacted with this merchant before" - }, - { - "indicator": "unusual_category", - "severity": "high", - "description": "Jewelry purchase is outside customer's typical spending categories" - }, - { - "indicator": "high_amount", - "severity": "high", - "description": "Transaction amount is 14.5x customer's average transaction" - }, - { - "indicator": "merchant_flagged", - "severity": "critical", - "description": "Merchant has been flagged in fraud databases" - } - ], - "total_indicators": 5, - "critical_count": 1, - "high_count": 3, - "medium_count": 1, - "overall_assessment": "high_fraud_probability" - }, - this.transaction_id == "TXN-89013" => { - "transaction_id": "TXN-89013", - "risk_indicators": [ - { - "indicator": "known_merchant", - "severity": "none", - "description": "Example Marketplace is a recognized and trusted merchant" - } - ], - "total_indicators": 1, - "critical_count": 0, - "high_count": 0, - "medium_count": 0, - "overall_assessment": "low_fraud_probability" - }, - this.transaction_id == "TXN-89014" => { - "transaction_id": "TXN-89014", - "risk_indicators": [ - { - "indicator": "recurring_billing", - "severity": "low", - "description": "Subscription service with recurring charges" - }, - { - "indicator": "merchant_billing_issues", - "severity": "medium", - "description": "Merchant has known history of duplicate billing complaints" - }, - { - "indicator": "duplicate_charge_pattern", - "severity": "medium", - "description": "Multiple charges detected from same merchant in short timeframe" - } - ], - "total_indicators": 3, - "critical_count": 0, - "high_count": 0, - "medium_count": 2, - "low_count": 1, - "none_count": 0, - "overall_assessment": "medium_fraud_probability" - }, - this.transaction_id == "TXN-89015" => { - "transaction_id": "TXN-89015", - "risk_indicators": [ - { - "indicator": "international_transaction", - "severity": "low", - "description": "Transaction in France matches customer's travel history" - }, - { - "indicator": "travel_category", - "severity": "none", - "description": "Hotel charge is consistent with customer's frequent travel patterns" - }, - { - "indicator": "timing_matches_travel", - "severity": "none", - "description": "Transaction date aligns with customer's Paris trip" - } - ], - "total_indicators": 3, - "critical_count": 0, - "high_count": 0, - "medium_count": 0, - "low_count": 1, - "none_count": 2, - "overall_assessment": "low_fraud_probability" - }, - _ => { - "transaction_id": this.transaction_id, - "risk_indicators": [], - "total_indicators": 0, - "critical_count": 0, - "high_count": 0, - "medium_count": 0, - "low_count": 0, - "none_count": 0, - "overall_assessment": "insufficient_data" - } - } - -meta: - mcp: - enabled: true - description: "Retrieve fraud risk indicators for a transaction including severity levels and overall assessment. Use TXN-89012 through TXN-89015 for testing." - properties: - - name: transaction_id - type: string - description: "Transaction identifier to analyze (format TXN-XXXXX)" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/get_shipping_info.yaml b/modules/mcp/examples/mcp-tools/processors/get_shipping_info.yaml deleted file mode 100644 index b0a15b4..0000000 --- a/modules/mcp/examples/mcp-tools/processors/get_shipping_info.yaml +++ /dev/null @@ -1,38 +0,0 @@ -label: get_shipping_info - -processors: - - mapping: | - let order_id = this.order_id - root = if $order_id == "ORD-12345" { - { - "order_id": $order_id, - "tracking_number": "FX1234567890", - "carrier": "Example Shipping", - "status": "in_transit", - "estimated_delivery": "2025-01-17", - "last_location": "San Francisco Distribution Center", - "last_update": "2025-01-15T14:30:00Z" - } - } else if $order_id == "ORD-67890" { - { - "order_id": $order_id, - "error": true, - "message": "Order has not shipped yet" - } - } else { - { - "order_id": $order_id, - "error": true, - "message": "No shipping information available" - } - } - -meta: - mcp: - enabled: true - description: "Get tracking and shipping information. ORD-12345 has shipping info, ORD-67890 has not shipped yet." - properties: - - name: order_id - type: string - description: "The order ID to track" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/get_transaction_details.yaml b/modules/mcp/examples/mcp-tools/processors/get_transaction_details.yaml deleted file mode 100644 index 82b44ba..0000000 --- a/modules/mcp/examples/mcp-tools/processors/get_transaction_details.yaml +++ /dev/null @@ -1,99 +0,0 @@ -label: get_transaction_details -mapping: | - root = match { - this.transaction_id == "TXN-89012" => { - "transaction_id": "TXN-89012", - "customer_id": "CUST-1001", - "amount": 1847.99, - "currency": "USD", - "merchant": { - "name": "LUXURY WATCHES INT", - "category": "jewelry", - "country": "SG", - "mcc": "5944" - }, - "card_last_four": "4532", - "date": "2026-01-18T14:22:00Z", - "location": { - "city": "Singapore", - "country": "SG", - "coordinates": "1.3521,103.8198" - }, - "status": "posted" - }, - this.transaction_id == "TXN-89013" => { - "transaction_id": "TXN-89013", - "customer_id": "CUST-1001", - "amount": 47.83, - "currency": "USD", - "merchant": { - "name": "EXAMPLE MKTPLACE", - "category": "online_retail", - "country": "US", - "mcc": "5942" - }, - "card_last_four": "4532", - "date": "2026-01-15T10:15:00Z", - "location": { - "city": "Seattle", - "country": "US", - "coordinates": "47.6062,-122.3321" - }, - "status": "posted" - }, - this.transaction_id == "TXN-89014" => { - "transaction_id": "TXN-89014", - "customer_id": "CUST-1002", - "amount": 29.99, - "currency": "USD", - "merchant": { - "name": "EXAMPLE STREAMING", - "category": "subscription_service", - "country": "US", - "mcc": "4899" - }, - "card_last_four": "8821", - "date": "2025-12-15T00:00:01Z", - "location": { - "city": "San Francisco", - "country": "US", - "coordinates": "37.7749,-122.4194" - }, - "status": "posted", - "recurring": true - }, - this.transaction_id == "TXN-89015" => { - "transaction_id": "TXN-89015", - "customer_id": "CUST-1003", - "amount": 312.50, - "currency": "EUR", - "merchant": { - "name": "HOTEL PARIS", - "category": "lodging", - "country": "FR", - "mcc": "7011" - }, - "card_last_four": "2193", - "date": "2026-01-10T20:30:00Z", - "location": { - "city": "Paris", - "country": "FR", - "coordinates": "48.8566,2.3522" - }, - "status": "posted" - }, - _ => { - "error": "transaction_not_found", - "message": "No transaction found with ID: " + this.transaction_id - } - } - -meta: - mcp: - enabled: true - description: "Retrieve detailed transaction information including merchant, location, and amount. Use TXN-89012 through TXN-89015 for testing." - properties: - - name: transaction_id - type: string - description: "Transaction identifier (format TXN-XXXXX)" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/get_transaction_history.yaml b/modules/mcp/examples/mcp-tools/processors/get_transaction_history.yaml deleted file mode 100644 index 3c8107f..0000000 --- a/modules/mcp/examples/mcp-tools/processors/get_transaction_history.yaml +++ /dev/null @@ -1,108 +0,0 @@ -label: get_transaction_history -mapping: | - root = match { - this.customer_id == "CUST-1001" => { - "customer_id": "CUST-1001", - "analysis_period": "last_90_days", - "spending_patterns": { - "average_transaction": 127.45, - "median_transaction": 65.20, - "total_transactions": 87, - "total_amount": 11088.15 - }, - "category_breakdown": [ - {"category": "online_retail", "count": 42, "avg_amount": 78.50}, - {"category": "groceries", "count": 28, "avg_amount": 95.30}, - {"category": "restaurants", "count": 12, "avg_amount": 45.80}, - {"category": "gas_stations", "count": 5, "avg_amount": 62.00} - ], - "location_patterns": { - "primary_region": "US_West_Coast", - "international_transactions": 0, - "cities": ["Seattle", "Bellevue", "Tacoma"] - }, - "merchant_patterns": { - "recurring_merchants": ["EXAMPLE MKTPLACE", "EXAMPLE WHOLESALE", "EXAMPLE COFFEE"], - "first_time_merchants_this_period": 3 - }, - "risk_indicators": { - "unusual_activity": false, - "velocity_flags": 0, - "declined_transactions": 1 - } - }, - this.customer_id == "CUST-1002" => { - "customer_id": "CUST-1002", - "analysis_period": "last_90_days", - "spending_patterns": { - "average_transaction": 95.33, - "median_transaction": 52.10, - "total_transactions": 64, - "total_amount": 6101.12 - }, - "category_breakdown": [ - {"category": "subscription_service", "count": 15, "avg_amount": 29.99}, - {"category": "restaurants", "count": 25, "avg_amount": 68.40}, - {"category": "online_retail", "count": 18, "avg_amount": 110.20}, - {"category": "entertainment", "count": 6, "avg_amount": 45.00} - ], - "location_patterns": { - "primary_region": "US_West_Coast", - "international_transactions": 0, - "cities": ["San Francisco", "Oakland", "San Jose"] - }, - "merchant_patterns": { - "recurring_merchants": ["EXAMPLE STREAMING", "EXAMPLE MEDIA", "EXAMPLE AUDIO"], - "first_time_merchants_this_period": 7 - }, - "risk_indicators": { - "unusual_activity": false, - "velocity_flags": 0, - "declined_transactions": 0 - } - }, - this.customer_id == "CUST-1003" => { - "customer_id": "CUST-1003", - "analysis_period": "last_90_days", - "spending_patterns": { - "average_transaction": 215.67, - "median_transaction": 145.00, - "total_transactions": 52, - "total_amount": 11214.84 - }, - "category_breakdown": [ - {"category": "travel", "count": 8, "avg_amount": 650.00}, - {"category": "lodging", "count": 6, "avg_amount": 380.50}, - {"category": "restaurants", "count": 22, "avg_amount": 85.20}, - {"category": "online_retail", "count": 16, "avg_amount": 95.75} - ], - "location_patterns": { - "primary_region": "US_South", - "international_transactions": 3, - "cities": ["Austin", "Houston", "Dallas", "Paris", "London"] - }, - "merchant_patterns": { - "recurring_merchants": ["EXAMPLE AIRLINES", "EXAMPLE HOTEL", "EXAMPLE TRAVEL"], - "first_time_merchants_this_period": 12 - }, - "risk_indicators": { - "unusual_activity": false, - "velocity_flags": 0, - "declined_transactions": 0 - } - }, - _ => { - "error": "customer_not_found", - "message": "No transaction history found for customer ID: " + this.customer_id - } - } - -meta: - mcp: - enabled: true - description: "Retrieve customer transaction history with spending patterns, category breakdown, and risk indicators. Use CUST-1001, CUST-1002, or CUST-1003 for testing." - properties: - - name: customer_id - type: string - description: "Customer identifier (format CUST-XXXX)" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/get_weather_complete.yaml b/modules/mcp/examples/mcp-tools/processors/get_weather_complete.yaml deleted file mode 100644 index 42a1998..0000000 --- a/modules/mcp/examples/mcp-tools/processors/get_weather_complete.yaml +++ /dev/null @@ -1,55 +0,0 @@ -# Complete weather tool with validation, error handling, and response formatting -# tag::complete[] -label: get-weather - -processors: - # Validate and sanitize input - - label: validate_city - mutation: | - root.city = if this.city.or("").trim() == "" { - throw("city is required") - } else { - this.city.trim().lowercase().re_replace_all("[^a-z\\s\\-]", "") - } - root.units = this.units.or("metric") - - # Fetch weather data - - label: fetch_weather - try: - - http: - url: 'https://wttr.in/${! json("city") }?format=j1' - verb: GET - timeout: 10s - - - mutation: | - root.weather = { - "location": this.nearest_area.0.areaName.0.value, - "country": this.nearest_area.0.country.0.value, - "temperature_c": this.current_condition.0.temp_C, - "temperature_f": this.current_condition.0.temp_F, - "condition": this.current_condition.0.weatherDesc.0.value, - "humidity": this.current_condition.0.humidity, - "wind_kph": this.current_condition.0.windspeedKmph - } - - # Handle errors gracefully - - label: handle_errors - catch: - - mutation: | - root.error = true - root.message = "Failed to fetch weather: " + error() - -meta: - mcp: - enabled: true - description: "Get current weather for a city. Returns temperature, conditions, humidity, and wind speed." - properties: - - name: city - type: string - description: "City name (for example, 'London', 'New York', 'Tokyo')" - required: true - - name: units - type: string - description: "Temperature units: 'metric' or 'imperial' (default: metric)" - required: false -# end::complete[] diff --git a/modules/mcp/examples/mcp-tools/processors/get_weather_simple.yaml b/modules/mcp/examples/mcp-tools/processors/get_weather_simple.yaml deleted file mode 100644 index 445bf76..0000000 --- a/modules/mcp/examples/mcp-tools/processors/get_weather_simple.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# Simple weather tool - minimal example -# tag::complete[] -http: - url: "https://wttr.in/${! this.city }?format=j1" - verb: GET - -meta: - mcp: - enabled: true - name: get_weather - description: "Get current weather for a city" - properties: - - name: city - type: string - description: "City name" - required: true -# end::complete[] diff --git a/modules/mcp/examples/mcp-tools/processors/http_processor.yaml b/modules/mcp/examples/mcp-tools/processors/http_processor.yaml deleted file mode 100644 index 6e523a1..0000000 --- a/modules/mcp/examples/mcp-tools/processors/http_processor.yaml +++ /dev/null @@ -1,37 +0,0 @@ -label: fetch-weather -processors: - - label: prepare_parameters - mutation: | - meta city_name = this.city_name - - label: fetch_weather - http: - url: 'https://wttr.in/${! @city_name }?format=j1' - verb: GET - headers: - Accept: "application/json" - User-Agent: "redpanda-mcp-server/1.0" - - label: format_response - mutation: | - root = { - "city": @city_name, - "temperature": this.current_condition.0.temp_C.number(), - "feels_like": this.current_condition.0.FeelsLikeC.number(), - "humidity": this.current_condition.0.humidity.number(), - "pressure": this.current_condition.0.pressure.number(), - "description": this.current_condition.0.weatherDesc.0.value, - "wind_speed": this.current_condition.0.windspeedKmph.number(), - "metadata": { - "source": "wttr.in", - "fetched_at": now().ts_format("2006-01-02T15:04:05.000Z") - } - } - -meta: - mcp: - enabled: true - description: "Fetch current weather information for a specified city" - properties: - - name: city_name - type: string - description: "Name of the city to get weather information for" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/log_audit_event.yaml b/modules/mcp/examples/mcp-tools/processors/log_audit_event.yaml deleted file mode 100644 index 57b0a81..0000000 --- a/modules/mcp/examples/mcp-tools/processors/log_audit_event.yaml +++ /dev/null @@ -1,60 +0,0 @@ -label: log_audit_event -processors: - - mapping: | - root = { - "audit_id": uuid_v4(), - "timestamp": now(), - "event_type": "dispute_investigation", - "transaction_id": this.transaction_id, - "customer_id": this.customer_id, - "agent_decision": this.decision, - "risk_score": this.risk_score, - "evidence_reviewed": this.evidence, - "outcome": this.outcome, - "escalated": this.escalated, - "compliance_notes": this.notes, - "logged_by": "dispute-resolution-agent", - "status": "recorded" - } - - - log: - level: INFO - message: "Compliance audit event: ${!json()}" - -meta: - mcp: - enabled: true - description: "Log compliance audit events for dispute resolution. Records customer ID, transaction details, decision, and notes." - properties: - - name: customer_id - type: string - description: "Customer identifier (format CUST-XXXX)" - required: true - - name: transaction_id - type: string - description: "Transaction identifier (format TXN-XXXXX)" - required: true - - name: decision - type: string - description: "Dispute resolution decision (approve_refund, deny_claim, etc.)" - required: true - - name: risk_score - type: number - description: "Calculated fraud risk score (0-100)" - required: true - - name: evidence - type: object - description: "Evidence reviewed during investigation" - required: true - - name: outcome - type: string - description: "Final outcome of the dispute (approved, denied, escalated, pending)" - required: true - - name: escalated - type: boolean - description: "Whether case was escalated for manual review" - required: false - - name: notes - type: string - description: "Additional compliance notes" - required: false diff --git a/modules/mcp/examples/mcp-tools/processors/lookup_customer.yaml b/modules/mcp/examples/mcp-tools/processors/lookup_customer.yaml deleted file mode 100644 index 6fba9ed..0000000 --- a/modules/mcp/examples/mcp-tools/processors/lookup_customer.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# Look up customer by ID from PostgreSQL -# Example of sql_select processor tool -# tag::complete[] -label: lookup-customer # <1> - -sql_select: # <2> - driver: postgres - dsn: "${secrets.DATABASE_URL}" - table: customers - columns: ["id", "name", "email", "plan"] - where: id = ? - args_mapping: '[this.customer_id]' - -meta: # <3> - mcp: - enabled: true - description: "Look up a customer by ID and return their profile." - properties: - - name: customer_id - type: string - description: "The customer's unique identifier" - required: true -# end::complete[] diff --git a/modules/mcp/examples/mcp-tools/processors/observable_tool.yaml b/modules/mcp/examples/mcp-tools/processors/observable_tool.yaml deleted file mode 100644 index e2596a7..0000000 --- a/modules/mcp/examples/mcp-tools/processors/observable_tool.yaml +++ /dev/null @@ -1,60 +0,0 @@ -label: observable_tool -processors: - - label: init_tracing - mutation: | - # Generate correlation ID for request tracing - meta req_id = uuid_v7() - meta start_time = now() - - # Log request start with structured data - root.trace = { - "request_id": @req_id, - "timestamp": @start_time.ts_format("2006-01-02T15:04:05.000Z"), - "tool": "observable_tool", - "version": "1.0.0" - } - - - label: log_request_start - log: - message: "MCP tool request started" - fields: - request_id: "${! @req_id }" - tool_name: "observable_tool" - input_params: "${! this.without(\"trace\") }" - user_agent: "${! meta(\"User-Agent\").catch(\"unknown\") }" - level: "INFO" - - - label: finalize_response - mutation: | - # Calculate total execution time - meta duration = (now().ts_unix_nano() - @start_time.ts_unix_nano()) / 1000000 - - # Add trace information to response - root.metadata = { - "request_id": @req_id, - "execution_time_ms": @duration, - "timestamp": now().ts_format("2006-01-02T15:04:05.000Z"), - "tool": "observable_tool", - "success": !this.exists("error") - } - - - label: log_completion - log: - message: "MCP tool request completed" - fields: - request_id: "${! @req_id }" - duration_ms: "${! this.metadata.execution_time_ms }" - success: "${! this.metadata.success }" - result_size: "${! content().length() }" - level: "INFO" - -meta: - tags: [ example ] - mcp: - enabled: true - description: "Example tool with comprehensive observability and error handling" - properties: - - name: user_id - type: string - description: "User ID to fetch data for" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/openai_chat.yaml b/modules/mcp/examples/mcp-tools/processors/openai_chat.yaml deleted file mode 100644 index b8c202a..0000000 --- a/modules/mcp/examples/mcp-tools/processors/openai_chat.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# OpenAI chat completion for sentiment analysis -# Use for text generation, classification, summarization -label: analyze-feedback - -# tag::component[] -openai_chat_completion: - api_key: "${secrets.OPENAI_API_KEY}" - model: "gpt-5.2" - prompt: | - Analyze this customer feedback and provide: - 1. Sentiment (positive/negative/neutral) - 2. Key themes - 3. Actionable insights - - Feedback: ${! json(feedback_text) } - max_tokens: 500 -# end::component[] - -meta: - mcp: - enabled: true - description: "Analyze customer feedback for sentiment and themes" - properties: - - name: feedback_text - type: string - description: "The customer feedback text to analyze" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/openai_embeddings.yaml b/modules/mcp/examples/mcp-tools/processors/openai_embeddings.yaml deleted file mode 100644 index 0c7f15f..0000000 --- a/modules/mcp/examples/mcp-tools/processors/openai_embeddings.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# Generate embeddings with OpenAI -# Use for semantic search, RAG pipelines, similarity matching -label: generate-embeddings - -# tag::component[] -openai_embeddings: - api_key: "${secrets.OPENAI_API_KEY}" - model: "text-embedding-3-small" - text: ${! json("content") } -# end::component[] - -meta: - mcp: - enabled: true - description: "Generate vector embeddings for text content" - properties: - - name: content - type: string - description: "Text content to generate embeddings for" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/order_workflow.yaml b/modules/mcp/examples/mcp-tools/processors/order_workflow.yaml deleted file mode 100644 index aebaac8..0000000 --- a/modules/mcp/examples/mcp-tools/processors/order_workflow.yaml +++ /dev/null @@ -1,107 +0,0 @@ -label: order_workflow -processors: - - label: validate_order - mutation: | - # Validation logic - root = if this.total <= 0 { - throw("Invalid order total") - } else { this } - - - label: mock_inventory_check - mutation: | - # Mock inventory data for testing - let inventory = { - "widget-001": {"quantity": 100, "name": "Standard Widget"}, - "widget-premium": {"quantity": 25, "name": "Premium Widget"}, - "widget-limited": {"quantity": 2, "name": "Limited Edition Widget"} - } - - let product = $inventory.get(this.product_id) - root = if $product == null { - throw("Product not found: " + this.product_id) - } else if $product.quantity < this.quantity { - throw("Insufficient inventory. Available: " + $product.quantity.string()) - } else { - this.merge({ - "inventory_check": "passed", - "available_quantity": $product.quantity, - "product_name": $product.name - }) - } - - - label: route_by_priority - switch: - - check: 'this.total > 1000' - processors: - - label: mock_high_value_processing - mutation: | - # Mock premium processing - root = this.merge({ - "processing_tier": "premium", - "processing_time_estimate": "2-4 hours", - "assigned_rep": "premium-team@example.com", - "priority_score": 95 - }) - - - check: 'this.customer_tier == "vip"' - processors: - - label: mock_vip_processing - mutation: | - # Mock VIP processing - root = this.merge({ - "processing_tier": "vip", - "processing_time_estimate": "1-2 hours", - "assigned_rep": "vip-team@example.com", - "priority_score": 90, - "perks": ["expedited_shipping", "white_glove_service"] - }) - - - processors: - - label: mock_standard_processing - mutation: | - # Mock standard processing - root = this.merge({ - "processing_tier": "standard", - "processing_time_estimate": "24-48 hours", - "assigned_rep": "support@example.com", - "priority_score": 50 - }) - - - label: finalize_order - mutation: | - # Add final processing metadata - # Calculate estimated fulfillment by parsing processing time - let max_hours = this.processing_time_estimate.split("-").index(1).split(" ").index(0).number() - - root = this.merge({ - "order_status": "processed", - "processed_at": now().ts_format("2006-01-02T15:04:05.000Z"), - "estimated_fulfillment": "TBD - calculated based on processing tier", - "processing_time_hours": $max_hours - }) - -meta: - mcp: - enabled: true - description: "Process orders with validation, inventory check, and tiered routing (with mocks for testing)" - properties: - - name: order_id - type: string - description: "Unique order identifier" - required: true - - name: product_id - type: string - description: "Product ID (try: widget-001, widget-premium, widget-limited)" - required: true - - name: quantity - type: number - description: "Quantity to order" - required: true - - name: total - type: number - description: "Order total in dollars" - required: true - - name: customer_tier - type: string - description: "Customer tier (optional: vip, standard)" - required: false \ No newline at end of file diff --git a/modules/mcp/examples/mcp-tools/processors/search_jira.yaml b/modules/mcp/examples/mcp-tools/processors/search_jira.yaml deleted file mode 100644 index 331e29e..0000000 --- a/modules/mcp/examples/mcp-tools/processors/search_jira.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# Search Jira issues using JQL -# Requires Enterprise license -# tag::complete[] -label: search-jira - -processors: - - generate: - count: 1 - mapping: | - root.jql = this.jql - root.maxResults = this.max_results.or(50) - root.fields = ["key", "summary", "status", "assignee", "priority"] - - jira: - base_url: "${secrets.JIRA_BASE_URL}" - username: "${secrets.JIRA_USERNAME}" - api_token: "${secrets.JIRA_API_TOKEN}" - -meta: - mcp: - enabled: true - description: "Search Jira issues using JQL. Returns matching issues with key, summary, status, assignee, and priority." - properties: - - name: jql - type: string - description: "JQL query (for example, 'project = DOC AND status = Open')" - required: true - - name: max_results - type: number - description: "Maximum issues to return (default: 50)" - required: false -# end::complete[] diff --git a/modules/mcp/examples/mcp-tools/processors/transform_validate.yaml b/modules/mcp/examples/mcp-tools/processors/transform_validate.yaml deleted file mode 100644 index b05b619..0000000 --- a/modules/mcp/examples/mcp-tools/processors/transform_validate.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# Transform and validate data with Bloblang -# Use for parsing, validation, filtering, enrichment -label: transform-user-data - -processors: - # tag::mapping[] - - mapping: | - # Parse and validate incoming data - root.user_id = this.user_id.or(throw("user_id is required")) - root.timestamp = now().ts_format("2006-01-02T15:04:05Z07:00") - - # Transform and enrich - root.email_domain = this.email.split("@").index(1) - root.is_premium = this.subscription_tier == "premium" - - # Filter sensitive data - root.profile = this.profile.or({}).without("ssn", "credit_card") - # end::mapping[] - -meta: - mcp: - enabled: true - description: "Transform and validate user data" - properties: - - name: user_id - type: string - description: "User identifier" - required: true - - name: email - type: string - description: "User email address" - required: true - - name: subscription_tier - type: string - description: "Subscription level" - required: false - - name: profile - type: object - description: "User profile data" - required: false diff --git a/modules/mcp/examples/mcp-tools/processors/verify_merchant.yaml b/modules/mcp/examples/mcp-tools/processors/verify_merchant.yaml deleted file mode 100644 index e0ad877..0000000 --- a/modules/mcp/examples/mcp-tools/processors/verify_merchant.yaml +++ /dev/null @@ -1,126 +0,0 @@ -label: verify_merchant -mapping: | - root = match { - this.merchant_name == "LUXURY WATCHES INT" => { - "merchant_name": "LUXURY WATCHES INT", - "merchant_id": "MER-99912", - "reputation_score": 12, - "reputation_level": "high_risk", - "verification_status": "unverified", - "fraud_reports": { - "total_reports": 247, - "recent_reports_30d": 42, - "confirmed_fraud_cases": 89 - }, - "business_details": { - "country": "Singapore", - "years_in_operation": 1, - "registration_verified": false - }, - "red_flags": [ - "High volume of fraud reports", - "Recently established business", - "Unverified business registration", - "Operates in high-risk category", - "Pattern of chargebacks" - ], - "recommendation": "block_merchant" - }, - this.merchant_name == "EXAMPLE MKTPLACE" => { - "merchant_name": "EXAMPLE MKTPLACE", - "merchant_id": "MER-00001", - "reputation_score": 98, - "reputation_level": "excellent", - "verification_status": "verified", - "fraud_reports": { - "total_reports": 1203, - "recent_reports_30d": 15, - "confirmed_fraud_cases": 0 - }, - "business_details": { - "country": "USA", - "years_in_operation": 20, - "registration_verified": true, - "parent_company": "Example Organization" - }, - "red_flags": [], - "recommendation": "trusted_merchant" - }, - this.merchant_name == "EXAMPLE STREAMING" => { - "merchant_name": "EXAMPLE STREAMING", - "merchant_id": "MER-45678", - "reputation_score": 65, - "reputation_level": "moderate", - "verification_status": "verified", - "fraud_reports": { - "total_reports": 892, - "recent_reports_30d": 67, - "confirmed_fraud_cases": 12 - }, - "business_details": { - "country": "USA", - "years_in_operation": 5, - "registration_verified": true - }, - "red_flags": [ - "Known billing system issues", - "Frequent duplicate charge complaints", - "Difficult cancellation process" - ], - "common_issues": [ - "Duplicate subscriptions", - "Failed cancellation processing", - "Unclear billing descriptors" - ], - "recommendation": "verify_subscription_details" - }, - this.merchant_name == "HOTEL PARIS" => { - "merchant_name": "HOTEL PARIS", - "merchant_id": "MER-78234", - "reputation_score": 88, - "reputation_level": "trusted", - "verification_status": "verified", - "fraud_reports": { - "total_reports": 45, - "recent_reports_30d": 2, - "confirmed_fraud_cases": 0 - }, - "business_details": { - "country": "France", - "years_in_operation": 15, - "registration_verified": true, - "chain": "Independent Boutique Hotels" - }, - "red_flags": [], - "pricing": { - "average_room_rate_eur": 280, - "typical_range_eur": "220-350" - }, - "recommendation": "legitimate_merchant" - }, - _ => { - "merchant_name": this.merchant_name, - "reputation_score": 50, - "reputation_level": "unknown", - "verification_status": "not_found", - "fraud_reports": { - "total_reports": 0, - "recent_reports_30d": 0, - "confirmed_fraud_cases": 0 - }, - "business_details": {}, - "red_flags": [], - "message": "Merchant not found in verification database", - "recommendation": "manual_review_required" - } - } - -meta: - mcp: - enabled: true - description: "Verify merchant reputation and fraud history. Use LUXURY WATCHES INT (high risk), EXAMPLE MKTPLACE (trusted), EXAMPLE STREAMING (moderate), or HOTEL PARIS (trusted) for testing." - properties: - - name: merchant_name - type: string - description: "Merchant name as it appears on transaction" - required: true diff --git a/modules/mcp/examples/mcp-tools/processors/weather_service.yaml b/modules/mcp/examples/mcp-tools/processors/weather_service.yaml deleted file mode 100644 index 3ebe920..0000000 --- a/modules/mcp/examples/mcp-tools/processors/weather_service.yaml +++ /dev/null @@ -1,60 +0,0 @@ -label: weather-service -processors: - - label: validate_inputs # <1> - mutation: | - # Validate and sanitize city input - meta city = this.city.string(). - re_replace_all("[^a-zA-Z\\s\\-]", ""). - trim() - - # Check for empty input - root = if @city == "" { - throw("City name cannot be empty") - } else { "" } - - - label: fetch_weather_data # <2> - try: - - http: # <3> - url: "https://wttr.in/${! @city }?format=j1" - verb: GET - headers: - User-Agent: "redpanda-connect-mcp/1.0" - timeout: "10s" - - mutation: | # <4> - root = { - "city": @city, - "temperature_c": this.current_condition.0.temp_C.number(), - "temperature_f": this.current_condition.0.temp_F.number(), - "feels_like_c": this.current_condition.0.FeelsLikeC.number(), - "humidity": this.current_condition.0.humidity.number(), - "description": this.current_condition.0.weatherDesc.0.value, - "wind_speed_kmh": this.current_condition.0.windspeedKmph.number(), - "timestamp": now().format_timestamp("2006-01-02T15:04:05Z07:00") - } - - log: - message: "Weather data fetched for city: ${! @city }" - level: "INFO" - - - label: handle_weather_errors # <5> - catch: - - mutation: | - root = { - "error": "Failed to fetch weather data", - "city": @city, - "details": error(), - "timestamp": now().format_timestamp("2006-01-02T15:04:05Z07:00") - } - - log: - message: "Weather API error for city ${! @city }: ${! error() }" - level: "ERROR" - -meta: # <6> - tags: [ weather, example ] - mcp: - enabled: true - description: "Get current weather conditions for any city worldwide" - properties: - - name: city - type: string - description: "Name of the city (such as 'San Francisco', 'London')" - required: true diff --git a/modules/mcp/examples/mcp-tools/snippets/bloblang_this_context.yaml b/modules/mcp/examples/mcp-tools/snippets/bloblang_this_context.yaml deleted file mode 100644 index 18409d0..0000000 --- a/modules/mcp/examples/mcp-tools/snippets/bloblang_this_context.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# Bloblang 'this' context examples -# Use 'this' to access message fields in mutation, mapping, or args_mapping - -# tag::mutation[] -mutation: | - root.search_query = this.query.lowercase() - root.max_results = this.limit.or(10) -# end::mutation[] - -# tag::args_mapping[] -sql_select: - table: orders - where: customer_id = ? AND status = ? - args_mapping: '[this.customer_id, this.status.or("active")]' -# end::args_mapping[] diff --git a/modules/mcp/examples/mcp-tools/snippets/defaults.yaml b/modules/mcp/examples/mcp-tools/snippets/defaults.yaml deleted file mode 100644 index 844ea33..0000000 --- a/modules/mcp/examples/mcp-tools/snippets/defaults.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# Handling optional parameters with defaults - -# tag::mutation[] -mutation: | - root.city = this.city # Required - will error if missing - root.units = this.units.or("metric") # Optional with default - root.limit = this.limit.or(10).number() # Optional, converted to number -# end::mutation[] - -# tag::properties[] -properties: - - name: city - type: string - description: "City name to look up" - required: true - - name: units - type: string - description: "Temperature units: 'metric' or 'imperial' (default: metric)" - required: false - - name: limit - type: number - description: "Max results (default: 10)" - required: false -# end::properties[] diff --git a/modules/mcp/examples/mcp-tools/snippets/interpolation.yaml b/modules/mcp/examples/mcp-tools/snippets/interpolation.yaml deleted file mode 100644 index 90bd0d8..0000000 --- a/modules/mcp/examples/mcp-tools/snippets/interpolation.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# Bloblang interpolation in string fields -# Use ${! ... } to embed expressions in URLs, topics, headers - -# tag::http_url[] -http: - url: 'https://api.weather.com/v1/current?city=${! json("city") }&units=${! json("units").or("metric") }' -# end::http_url[] - -# tag::redpanda_topic[] -redpanda: - seed_brokers: ["${REDPANDA_BROKERS}"] # <1> - topic: '${! json("topic_name") }' # <2> -# end::redpanda_topic[] diff --git a/modules/mcp/examples/mcp-tools/snippets/secrets.yaml b/modules/mcp/examples/mcp-tools/snippets/secrets.yaml deleted file mode 100644 index 3ac6f98..0000000 --- a/modules/mcp/examples/mcp-tools/snippets/secrets.yaml +++ /dev/null @@ -1,14 +0,0 @@ -# Using secrets in tool configurations -# Reference secrets with ${secrets.SECRET_NAME} syntax - -# tag::example[] -http: - url: "https://api.example.com/data" - headers: - Authorization: "Bearer ${secrets.API_TOKEN}" - -sql_select: - driver: postgres - dsn: "${secrets.DATABASE_URL}" - table: customers -# end::example[] diff --git a/modules/mcp/examples/mcp-tools/test-mcp-tools.sh b/modules/mcp/examples/mcp-tools/test-mcp-tools.sh deleted file mode 100755 index f815a56..0000000 --- a/modules/mcp/examples/mcp-tools/test-mcp-tools.sh +++ /dev/null @@ -1,235 +0,0 @@ -#!/usr/bin/env bash -# -# Test script for Redpanda Cloud MCP examples -# -# This script tests: -# 1. MCP tool definitions using `rpk connect mcp-server lint` -# 2. MCP metadata validation (enabled, description, properties) -# -# Usage: -# ./test-mcp-tools.sh # Run all tests -# ./test-mcp-tools.sh --lint-only # Only lint, skip metadata validation -# -# Unlike rp-connect-docs, Cloud MCP tools cannot be tested with -# `rpk connect run` because they are standalone tool definitions, not -# full pipelines. End-to-end testing requires the Cloud Console. - -set -euo pipefail - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -CYAN='\033[0;36m' -NC='\033[0m' - -# Get script directory (script lives inside mcp-tools/) -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -cd "$SCRIPT_DIR" - -# Component type directories -COMPONENT_DIRS=("inputs" "outputs" "processors" "caches") - -# Counters -TOTAL_TOOLS=0 -PASSED_LINT=0 -PASSED_METADATA=0 -FAILED_LINT=0 -FAILED_METADATA=0 -SKIPPED=0 - -echo "🧪 Redpanda Cloud MCP Examples - Test Suite" -echo "============================================" -echo "" - -# Parse arguments -RUN_METADATA=true - -if [[ $# -gt 0 ]]; then - case "$1" in - --lint-only) - RUN_METADATA=false - ;; - esac -fi - -# ============================================================================ -# SECTION 1: MCP Tool Linting -# Validates YAML syntax and component schemas -# ============================================================================ - -echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -echo -e "📦 ${CYAN}SECTION 1: MCP Tool Linting${NC}" -echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -echo "" - -for dir in "${COMPONENT_DIRS[@]}"; do - if [[ -d "$dir" ]]; then - file_count=$(find "$dir" -maxdepth 1 -name "*.yaml" | wc -l | tr -d ' ') - if [[ $file_count -gt 0 ]]; then - TOTAL_TOOLS=$((TOTAL_TOOLS + file_count)) - echo -n -e "${BLUE}📁 $dir/${NC} ($file_count files)... " - - if output=$(rpk connect mcp-server lint --skip-env-var-check "$dir" 2>&1); then - echo -e "${GREEN}✓ PASSED${NC}" - PASSED_LINT=$((PASSED_LINT + file_count)) - else - echo -e "${RED}✗ FAILED${NC}" - echo "$output" | sed 's/^/ /' | head -20 - FAILED_LINT=$((FAILED_LINT + file_count)) - fi - fi - fi -done - -# ============================================================================ -# SECTION 2: MCP Metadata Validation -# Validates tool metadata (enabled, description, properties) -# ============================================================================ - -if $RUN_METADATA; then - echo "" - echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - echo -e "📝 ${CYAN}SECTION 2: MCP Metadata Validation${NC}" - echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - echo "" - - # Determine which YAML parser to use - use_yq=true - if ! command -v yq &> /dev/null; then - use_yq=false - if ! command -v python3 &> /dev/null; then - echo -e "${YELLOW}⚠ Neither yq nor python3 available - skipping metadata validation${NC}" - RUN_METADATA=false - fi - fi - - if $RUN_METADATA; then - for dir in "${COMPONENT_DIRS[@]}"; do - if [[ -d "$dir" ]]; then - for file in "$dir"/*.yaml; do - if [[ -f "$file" ]]; then - echo -n -e " ${BLUE}$file${NC}... " - - # Check if .meta.mcp exists - if $use_yq; then - mcp_exists=$(yq eval '.meta.mcp' "$file" 2>/dev/null) - enabled=$(yq eval '.meta.mcp.enabled' "$file" 2>/dev/null) - description=$(yq eval '.meta.mcp.description' "$file" 2>/dev/null) - else - mcp_exists=$(python3 -c " -import yaml -try: - with open('$file') as f: - doc = yaml.safe_load(f) - meta = doc.get('meta', {}) if doc else {} - mcp = meta.get('mcp') - print('null' if mcp is None else 'exists') -except: - print('null') -" 2>/dev/null) - enabled=$(python3 -c " -import yaml -try: - with open('$file') as f: - doc = yaml.safe_load(f) - enabled = doc.get('meta', {}).get('mcp', {}).get('enabled') - print('null' if enabled is None else str(enabled).lower()) -except: - print('null') -" 2>/dev/null) - description=$(python3 -c " -import yaml -try: - with open('$file') as f: - doc = yaml.safe_load(f) - desc = doc.get('meta', {}).get('mcp', {}).get('description') - print('null' if desc is None or desc == '' else str(desc)) -except: - print('null') -" 2>/dev/null) - fi - - # Validate - if [[ "$mcp_exists" == "null" || -z "$mcp_exists" ]]; then - echo -e "${YELLOW}SKIPPED${NC} (no MCP metadata)" - SKIPPED=$((SKIPPED + 1)) - elif [[ "$enabled" != "true" ]]; then - echo -e "${YELLOW}WARNING${NC} (mcp.enabled not true)" - SKIPPED=$((SKIPPED + 1)) - elif [[ "$description" == "null" || -z "$description" ]]; then - echo -e "${RED}FAILED${NC} (missing description)" - FAILED_METADATA=$((FAILED_METADATA + 1)) - else - echo -e "${GREEN}PASSED${NC}" - PASSED_METADATA=$((PASSED_METADATA + 1)) - fi - fi - done - fi - done - fi -fi - -# ============================================================================ -# SECTION 3: Cloud-Specific Validation -# Validates secrets use Cloud format (${secrets.X}) -# ============================================================================ - -echo "" -echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -echo -e "☁️ ${CYAN}SECTION 3: Cloud Secrets Format${NC}" -echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -echo "" - -secrets_issues=0 -for dir in "${COMPONENT_DIRS[@]}"; do - if [[ -d "$dir" ]]; then - for file in "$dir"/*.yaml; do - if [[ -f "$file" ]]; then - # Check for non-Cloud secrets patterns (${VAR} without secrets. prefix) - # Exclude: - # - ${! ... } which is Bloblang interpolation - # - ${REDPANDA_BROKERS} which is platform-injected - if grep -E '\$\{[A-Z_]+\}' "$file" | grep -v '\${secrets\.' | grep -v '\${!' | grep -v '\${REDPANDA_BROKERS}' > /dev/null 2>&1; then - echo -e " ${BLUE}$file${NC}... ${YELLOW}WARNING${NC} (uses env vars instead of \${secrets.X})" - secrets_issues=$((secrets_issues + 1)) - fi - fi - done - fi -done - -if [[ $secrets_issues -eq 0 ]]; then - echo -e " ${GREEN}✓ All files use Cloud secrets format${NC}" -fi - -# ============================================================================ -# SUMMARY -# ============================================================================ - -echo "" -echo "============================================" -echo "📊 Test Summary" -echo "============================================" - -echo -e "Lint: ${PASSED_LINT}/${TOTAL_TOOLS} passed" -if $RUN_METADATA; then - METADATA_TOTAL=$((PASSED_METADATA + FAILED_METADATA + SKIPPED)) - echo -e "Metadata: ${PASSED_METADATA}/${METADATA_TOTAL} passed (${SKIPPED} skipped)" -fi -if [[ $secrets_issues -gt 0 ]]; then - echo -e "Secrets: ${YELLOW}${secrets_issues} warnings${NC}" -fi -echo "──────────────────────────────────────────────────" - -TOTAL_FAILED=$((FAILED_LINT + FAILED_METADATA)) - -if [[ $TOTAL_FAILED -gt 0 ]]; then - echo -e "${RED}❌ Some tests failed ($TOTAL_FAILED failures)${NC}" - exit 1 -else - echo -e "${GREEN}✅ All tests passed!${NC}" - exit 0 -fi diff --git a/modules/mcp/pages/create-server.adoc b/modules/mcp/pages/create-server.adoc new file mode 100644 index 0000000..782a6f2 --- /dev/null +++ b/modules/mcp/pages/create-server.adoc @@ -0,0 +1,184 @@ += Create an MCP Server +:description: Create an MCP server in the Agentic Data Plane — pick a managed type from the marketplace or register a self-managed server you host yourself, then configure authentication, code mode, and access. +:page-topic-type: how-to +:personas: platform_admin, app_developer +:learning-objective-1: Create a managed or self-managed MCP server in the ADP UI +:learning-objective-2: Configure each authentication mode and pick the right one for your use case +:learning-objective-3: Save the server, verify the API URL, and confirm tools were discovered + +include::ROOT:partial$adp-la.adoc[] + +Create MCP servers to give agents structured access to your databases, queues, CRMs, and other business systems. Each server exposes glossterm:tool[,tools], glossterm:resource[,resources], and glossterm:prompt[,prompts] that an agent can discover and invoke. Choose managed types that Redpanda hosts for you, or register self-managed servers you host yourself. + +After completing this guide, you will be able to: + +* [ ] {learning-objective-1} +* [ ] {learning-objective-2} +* [ ] {learning-objective-3} + +== Prerequisites + +* Access to the Agentic Data Plane. ++ +// TODO: confirm sign-in URL and IAM/role requirements once the standalone ADP UI ships. +* For any auth mode that uses upstream credentials: the credentials in hand and a secret already created in the ADP secret store. Secret references must be `UPPER_SNAKE_CASE` (proto regex `^[A-Z][A-Z0-9_]*$`). For example: `MCP_API_KEY`, `OPENAI_API_KEY`. ++ +// TODO: xref the ADP secrets-management page once confirmed. +* For user-delegated OAuth: an OAuth Provider resource already configured. See xref:user-delegated-oauth.adoc[User-delegated OAuth]. + +== Open the MCP Servers page + +. Sign in to the ADP UI and open *MCP Servers*. ++ +// TODO: screenshot of the MCP Servers list page on `adp-production`. +. Click *Create Server*. The marketplace picker opens. + +== Pick a backend + +The marketplace picker lists every managed type as a card and includes a *Remote (Proxied)* option for self-managed servers. + +* *Managed* — pick a card. Redpanda hosts the server in-process. The configuration form is rendered from the type's protobuf schema; field labels and help text come straight from the proto. +* *Self-managed* — pick *Remote (Proxied)*. You provide a URL and a transport, and Redpanda proxies requests to your server. + +// TODO: screenshot of the marketplace picker, with both a managed card and the Remote (Proxied) option visible. + +For a tour of every managed type and which one fits your use case, see xref:managed-catalog.adoc[Managed catalog]. To go deep on the self-managed path (transport choices, TLS, multi-server aggregation), see xref:register-remote.adoc[Register a self-managed server]. + +== Name and basic fields + +Every server has the same identity fields. + +[cols="1,1,3"] +|=== +|Field |Required |Notes + +|Name +|Yes +|Lowercase letters, numbers, and hyphens only (proto regex `^[a-z][a-z0-9-]*$`); 1–63 characters; must start with a letter. *Immutable after create.* Used as the URL path segment. + +|Description +|No +|Up to 256 characters. Shown in list and detail views. + +|Enabled +|Yes (toggle) +|Disabled servers reject every tool call. +|=== + +// TODO: confirm whether the proto's `name` immutability is enforced server-side at edit time, and if not, what the UI does. + +== Configure the managed flow (managed types only) + +Each managed type ships its own configuration schema. The form on this page is rendered from the type's `_config.proto`, so field labels and help text come from the proto definition itself. There is no hand-written form code per type. + +// TODO: screenshot of the SQL configuration form as the exemplar (it covers the most common field shapes). + +For per-type fields, see xref:managed-catalog.adoc[Managed catalog] for one-line entries on every type, and the deep-dive pages for SQL, Kafka, Slack, Jira, and OpenAPI: + +* xref:managed/sql.adoc[SQL] +* xref:managed/kafka.adoc[Kafka] +* xref:managed/slack.adoc[Slack] +* xref:managed/jira.adoc[Jira] +* xref:managed/openapi.adoc[OpenAPI] + +== Configure the self-managed flow (Remote/Proxied only) + +Two fields on top of the identity fields: + +[cols="1,1,3"] +|=== +|Field |Required |Notes + +|URL +|Yes +|Endpoint URL of your server. Must start with `http://` or `https://`. *HTTPS is required if you choose user-delegated OAuth* (proto rule `remote_mcp.user_oauth_requires_https`). + +|Transport +|Yes +|`SSE` (server-sent events) or `Streamable HTTP` (newer bidirectional protocol). Pick whichever your server speaks. See xref:register-remote.adoc[Register a self-managed server] for how to test which transport your server uses. +|=== + +== Configure authentication + +Both managed and self-managed servers offer the same five authentication modes (managed types only show the modes that make sense for that type — for example, SQL never offers user-delegated OAuth): + +[cols="1,3"] +|=== +|Mode |Use when + +|*None* +|The upstream server doesn't need authentication, or the managed type wraps an in-process resource that needs no creds. + +|*Static key* +|Single shared API key. Provide a `key_ref` (secret reference, `UPPER_SNAKE_CASE`) and an optional `header_name` (defaults to `Authorization`). + +|*Token passthrough* +|Forward the caller's `Authorization` header to the upstream server as-is. Useful when the upstream already validates upstream tokens. + +|*Service-account OAuth* +|2-legged OAuth client credentials. One shared upstream identity for every caller. Provide `client_id`, `client_secret_ref`, `token_url`, and any required `scopes`. + +|*User-delegated OAuth* +|Each end-user authenticates against the upstream system with their own credentials, and Redpanda injects the user's token at call time. Pick the configured *OAuth Provider* and the required scopes. The first time a user calls a tool that needs this server, Redpanda surfaces a consent prompt; the resulting connection is stored in the token vault and shows up under *My Connections*. See xref:user-delegated-oauth.adoc[User-delegated OAuth] for the full flow. +|=== + +NOTE: Choosing between *Service-account OAuth* and *User-delegated OAuth* is the credential-mode decision. Service-account auth gives every caller the same identity at the upstream; user-delegated auth gives each caller their own. + +// TODO: confirm that the UI surfaces the token-injection options (`header_name`, `header_prefix` from `TokenInjection`) on the user-delegated flow and capture a screenshot. + +== Code mode (optional) + +Toggle *Code mode* to add `{name}_search` and `{name}_execute` tools alongside the server's own tools. Agents can use `_search` to discover available tools and `_execute` to run sandboxed Python or JavaScript that orchestrates them. This is useful when you'd rather have the agent generate a small program than call tools one at a time. + +When code mode is enabled, the server's detail page surfaces a second URL — the *code-mode MCP URL* — that clients can connect to instead of the standard one. + +// TODO: screenshot of the code-mode toggle and the resulting two URLs on the detail page. + +NOTE: Defer advanced code-mode patterns (sandboxing limits, runtime selection, dependency management) to follow-up content; this page covers only enabling it. + +== Save and verify + +. Click *Create*. The server appears in the list with a *Type* badge — *Managed* or *Self-managed*. +. Open the detail page. The *Overview* tab shows the *API URL* — this is the MCP URL agents connect to. Copy it for use later. +. Open the *Inspector* tab. Redpanda performs a live `tools/list` against the server and lists every tool it discovered. See xref:test-tools.adoc[Test a server's tools] for how to call them. + +A populated tools list confirms that the connection works and credentials resolve correctly. If the list is empty or the tab shows an error, see <>. + +== Edit, disable, and delete a server + +* *Edit:* most fields can change. The *name* and *type* are *immutable* after create. +* *Disable:* toggle *Enabled* off. The server stays in the list, but every tool call returns an error until you re-enable it. +* *Delete:* permanently removes the server. In-flight user OAuth connections for this server are also discarded; users will need to re-consent if you re-create a server with the same name. ++ +// TODO: confirm exact delete semantics with eng — does deletion drop tokens from the vault, or just unbind the server? + +[[troubleshooting]] +== Troubleshooting + +[cols="1,2"] +|=== +|Symptom |What to check + +|`Secret not found` +|The secret reference is case-sensitive and must be `UPPER_SNAKE_CASE` matching the proto regex `^[A-Z][A-Z0-9_]*$`. Confirm the secret exists in the ADP secret store and is spelled identically. + +|"HTTPS required" error on save (self-managed) +|You picked user-delegated OAuth on a server with an `http://` URL. Switch to `https://` (proto rule `remote_mcp.user_oauth_requires_https`). + +|Inspector / tools list empty after create +|The connection or auth might be failing. Check the *Connection* tab for upstream errors. For self-managed, confirm the transport (SSE vs. Streamable HTTP) matches what your server actually speaks. + +|Tool calls return errors after disable/enable +|Disabled servers reject all tool calls. Confirm the *Enabled* toggle is on. +|=== + +// TODO: add screenshots of common error toasts after walking the live cluster. + +== Out of scope + +The following capabilities are not configured on this page; see the linked content instead. + +* *User-delegated OAuth consent flow* — see xref:user-delegated-oauth.adoc[User-delegated OAuth]. +* *Inspector usage* — see xref:test-tools.adoc[Test a server's tools]. +* *Multi-server aggregation* — handled by AI Gateway. See xref:ai-gateway:aggregation.adoc[MCP aggregation]. +* *Per-type configuration depth* — see xref:managed-catalog.adoc[Managed catalog] and the deep-dive pages. diff --git a/modules/mcp/pages/index.adoc b/modules/mcp/pages/index.adoc index b590371..34c4e5c 100644 --- a/modules/mcp/pages/index.adoc +++ b/modules/mcp/pages/index.adoc @@ -1,10 +1,82 @@ -= Model Context Protocol (MCP) -:description: Give AI agents direct access to your databases, queues, CRMs, and other business systems without writing custom glue code. += MCP Servers +:description: Connect AI agents to your databases, queues, CRMs, and other business systems through MCP servers — fully managed types Redpanda hosts for you, or your own self-managed servers proxied through the Agentic Data Plane. :page-layout: index +:page-topic-type: overview +:personas: evaluator, app_developer, platform_admin -AI agents need context from your business systems. The Model Context Protocol (MCP) translates agent intent into real connections to databases, queues, CRMs, HRIS, and other systems of record, without you writing custom integration code. Redpanda's MCP servers are built on the same proven connectors that power the world's largest e-commerce, electric vehicle, energy, and AI companies. +include::ROOT:partial$adp-la.adoc[] -Redpanda Cloud offers two complementary MCP options: +The Model Context Protocol (MCP) is how AI agents talk to tools. In the Agentic Data Plane, you create *MCP Servers* that agents can connect to. Each MCP server exposes a set of glossterm:tool[,tools], glossterm:resource[,resources], and glossterm:prompt[,prompts] that an agent can discover at runtime through `tools/list` and invoke through structured JSON-RPC calls. Redpanda handles upstream credentials, authentication flows, observability, and aggregation, so you can focus on what your agents do, not on the plumbing. -* *Remote MCP*: Deploy MCP servers directly in Redpanda Cloud for scalable, managed AI agent integrations -* *Redpanda Cloud Management MCP Server*: Connect your local AI development environment to manage Redpanda Cloud resources +Redpanda offers two kinds of MCP server backends: + +[cols="1,3"] +|=== +|Backend |When to use + +|*Managed* +|Redpanda hosts the server in-process. You pick a type from the marketplace (SQL, Kafka, Slack, Jira, OpenAPI, and many more) and configure it with your credentials. No infrastructure to run. + +|*Self-managed* +|You already run an MCP server somewhere and want Redpanda to proxy it for authentication, observability, aggregation, and agent access. Redpanda fronts your server with a managed URL and resolves auth at the gateway. +|=== + +// TODO: confirm exact count of managed types at GA — currently 27 in the registry. + +== When to use each + +[cols="1,2,2"] +|=== +|Concern |Managed |Self-managed + +|Infrastructure ownership +|Redpanda hosts and operates +|You host and operate + +|Upstream credentials +|Redpanda secret store; per-type schema +|Redpanda secret store or token vault; you control the upstream auth + +|Custom tool logic +|Limited to what the type exposes +|Anything the MCP protocol supports + +|Startup latency +|In-process; effectively zero +|Network round-trip to your endpoint + +|Upgrade cadence +|Redpanda manages +|You manage +|=== + +== What's in the ADP UI + +The Agentic Data Plane UI has four top-level areas: + +* *LLM Providers* — OpenAI, Anthropic, Bedrock, Gemini, OpenAI-compatible endpoints. See xref:ai-gateway:configure-provider.adoc[Configure your LLM provider]. +* *MCP Servers* — you are here. Both managed and self-managed servers live in this list. +* *OAuth Providers* — reusable OAuth provider definitions used by user-delegated MCP auth (and elsewhere). See xref:user-delegated-oauth.adoc[User-delegated OAuth]. +* *My Connections* — per-user OAuth connections for user-delegated MCP servers. See xref:user-delegated-oauth.adoc[User-delegated OAuth]. + +// TODO: screenshot of the four-area sidebar on adp-production once standalone-ADP wording is final. + +== Key capabilities + +* *Tool discovery.* After you create or register a server, Redpanda performs a live `tools/list` against it and populates the server's detail page so you can see what tools agents will see. +* *Service-account and user-delegated auth.* Pick a single shared upstream identity for all callers, or have each end-user authenticate against the upstream system with their own credentials. +* *Code mode.* Optionally expose `{name}_search` and `{name}_execute` helpers so an agent can discover and orchestrate tools through generated Python or JavaScript instead of calling them one at a time. +* *Inspector.* Test each tool, resource, and prompt directly from the ADP UI before pointing an agent at the server. See xref:test-tools.adoc[Test a server's tools]. +* *Aggregation.* Connect your agent to a single MCP URL and have Redpanda fan out across multiple registered MCP servers. See xref:ai-gateway:aggregation.adoc[MCP aggregation]. + +== Where to go next + +. *Create your first MCP server.* xref:create-server.adoc[Create an MCP Server] walks through the marketplace picker, the managed and self-managed flows, every authentication mode, and code mode. +. *Test what you built.* xref:test-tools.adoc[Test a server's tools] uses the Inspector tab to call tools, resources, and prompts live. +. *Wire up user-delegated OAuth* if your users should authenticate against the upstream system with their own credentials. See xref:user-delegated-oauth.adoc[User-delegated OAuth]. +. *Register an existing server* you already run yourself. See xref:register-remote.adoc[Register a self-managed server]. +. *Browse the managed catalog* for the full list of types, their categories, and per-type configuration links. See xref:managed-catalog.adoc[Managed catalog]. + +== Redpanda Cloud Management MCP Server + +Redpanda also publishes a separate, locally-installed MCP server for managing Redpanda Cloud resources — glossterm:cluster[,clusters], glossterm:topic[,topics], glossterm:acl[,ACLs] — from your AI development environment. It is not an Agentic Data Plane resource and does not appear in the MCP Servers list. To install it, see xref:local/index.adoc[Redpanda Cloud Management MCP Server]. diff --git a/modules/mcp/pages/local.adoc b/modules/mcp/pages/local.adoc deleted file mode 100644 index cd81566..0000000 --- a/modules/mcp/pages/local.adoc +++ /dev/null @@ -1,4 +0,0 @@ -= Local MCP -:description: Run MCP servers locally for development and testing. - -// TODO: Add content diff --git a/modules/mcp/pages/local/quickstart.adoc b/modules/mcp/pages/local/quickstart.adoc index 3cd0dcd..2542f36 100644 --- a/modules/mcp/pages/local/quickstart.adoc +++ b/modules/mcp/pages/local/quickstart.adoc @@ -11,7 +11,7 @@ In this quickstart, you'll get your Claude AI agent talking to Redpanda Cloud using the xref:local/overview.adoc[Redpanda Cloud Management MCP Server]. -If you're trying to deploy your own MCP server as a managed service inside your cluster, see xref:remote/quickstart.adoc[]. +If you're trying to deploy your own MCP server through the Agentic Data Plane, see xref:mcp:create-server.adoc[]. After completing this quickstart, you will be able to: diff --git a/modules/mcp/pages/managed-catalog.adoc b/modules/mcp/pages/managed-catalog.adoc new file mode 100644 index 0000000..2fcbcfb --- /dev/null +++ b/modules/mcp/pages/managed-catalog.adoc @@ -0,0 +1,196 @@ += Managed MCP Server Catalog +:description: Reference of every managed MCP server type Redpanda hosts in-process — grouped by category, with display name, description, and a link to a deep-dive where one exists. +:page-topic-type: reference +:personas: app_developer, platform_admin + +include::ROOT:partial$adp-la.adoc[] + +Managed MCP servers are in-process implementations Redpanda hosts for you. Each type has a fixed set of glossterm:tool[,tools] and a type-specific configuration schema. To create one, open *MCP Servers > Create Server* in the ADP UI and pick the type from the marketplace picker. See xref:create-server.adoc[Create an MCP Server] for the full create flow. + +This catalog lists every managed type currently registered, grouped by `ManagedMCPCategory`. Display names and descriptions are lifted verbatim from the type registrations in `cloudv2`. + +// TODO: confirm the registered list at GA — counts and category assignments are subject to last-minute adds/renames. Re-verify against `apps/aigw/internal/mcp/managed/mcps/*/register_mcp.go`. + +== Choosing managed vs. self-managed + +[cols="1,2"] +|=== +|Question |Choose managed when… + +|Who hosts and operates the server? +|You want Redpanda to host it. + +|Where do upstream credentials live? +|You're happy storing them in the ADP secret store. + +|Do you need custom tool logic? +|The fixed tool set of the managed type covers your use case. + +|Do you need per-user identities at the upstream? +|The managed type supports user-delegated OAuth (Slack, Jira, Google types do; SQL/Kafka don't). +|=== + +If any of these answers are "no," prefer xref:register-remote.adoc[a self-managed server] instead. + +== AI + +[cols="1,2,1"] +|=== +|Display name |Description |Deep dive + +|*AWS Bedrock* +|Invoke foundation models (Claude, Llama, Titan) on AWS Bedrock. +|— + +|*Cohere* +|Generate embeddings and chat completions via the Cohere API. +|— + +|*OpenAI* +|Chat completions, embeddings, and tools via the OpenAI API. +|— +|=== + +== AWS + +[cols="1,2,1"] +|=== +|Display name |Description |Deep dive + +|*AWS SNS* +|Publish and manage topics on AWS Simple Notification Service. +|— + +|*AWS SQS* +|Send, receive, and manage messages on AWS Simple Queue Service. +|— +|=== + +== Communication + +[cols="1,2,1"] +|=== +|Display name |Description |Deep dive + +|*Discord* +|Post messages, read channels, and manage servers on Discord. +|— + +|*GitHub (Read)* +|Read-only access to GitHub repositories, pull requests, commits, and code. +|— + +|*Jira* +|Manage Jira issues, projects, and workflows. +|xref:managed/jira.adoc[See the deep-dive →] + +|*Slack* +|Post messages and read channels on Slack. +|xref:managed/slack.adoc[See the deep-dive →] +|=== + +== Database + +[cols="1,2,1"] +|=== +|Display name |Description |Deep dive + +|*Elasticsearch* +|Query and index documents in an Elasticsearch cluster. +|— + +|*MongoDB* +|Query collections and documents in MongoDB. +|— + +|*Qdrant* +|Vector search over a Qdrant collection. +|— + +|*Redis* +|Read, write, and query keys in Redis. +|— + +|*SQL* +|Query SQL databases (Postgres, MySQL, ClickHouse, MSSQL, SQLite) via MCP. +|xref:managed/sql.adoc[See the deep-dive →] +|=== + +== Google + +[cols="1,2,1"] +|=== +|Display name |Description |Deep dive + +|*GCP Pub/Sub* +|Publish and subscribe to topics on Google Cloud Pub/Sub. +|— + +|*Google Calendar* +|Read and manage Google Calendar events and schedules. +|— + +|*Google Drive* +|Read and search files in Google Drive. +|— +|=== + +== Streaming + +[cols="1,2,1"] +|=== +|Display name |Description |Deep dive + +|*Kafka* +|Produce, consume, and inspect topics on Kafka or Redpanda brokers. +|xref:managed/kafka.adoc[See the deep-dive →] + +|*NATS* +|Publish and subscribe on NATS and NATS JetStream. +|— +|=== + +== Utility + +[cols="1,2,1"] +|=== +|Display name |Description |Deep dive + +|*BambooHR* +|Access employee directory, time-off, and performance data from BambooHR. +|— + +|*BILL (bill.com)* +|Manage accounts-payable bills, vendors, AR invoices, payments, and customers in BILL. +|— + +|*DocuSign* +|Send, track, and manage DocuSign signing envelopes. +|— + +|*Greenhouse* +|Manage jobs, candidates, and applications in Greenhouse ATS. +|— + +|*Okta* +|Manage Okta users and groups. +|— + +|*OpenAPI* +|Expose any OpenAPI/Swagger HTTP API as MCP tools. +|xref:managed/openapi.adoc[See the deep-dive →] + +|*Salesforce* +|Query, create, update, and delete Salesforce CRM records using SOQL and the REST API. +|— + +|*Text Chunker* +|Split and chunk text for RAG and LLM ingestion pipelines. +|— +|=== + +== Where to go next + +* xref:create-server.adoc[Create an MCP server] using the marketplace picker. +* xref:test-tools.adoc[Test tools with the Inspector] before pointing an agent at the server. +* xref:user-delegated-oauth.adoc[Configure user-delegated OAuth] for types that need per-user upstream identities. diff --git a/modules/mcp/pages/managed/jira.adoc b/modules/mcp/pages/managed/jira.adoc new file mode 100644 index 0000000..9001463 --- /dev/null +++ b/modules/mcp/pages/managed/jira.adoc @@ -0,0 +1,118 @@ += Jira Managed MCP Server +:description: Let agents read and manage Jira issues, projects, and workflows using each end-user's own Atlassian identity through user-delegated OAuth. +:page-topic-type: how-to +:personas: app_developer +:learning-objective-1: Configure the Jira managed MCP server with Atlassian's OAuth flow +:learning-objective-2: Pick the right scopes for read-only vs. read-write workflows +:learning-objective-3: Walk a user through the consent flow and verify the connection + +include::ROOT:partial$adp-la.adoc[] + +The *Jira* managed MCP server gives agents access to Jira issues, projects, and workflows on behalf of the calling user. It's the enterprise counterpart to xref:managed/slack.adoc[the Slack deep-dive] — both use user-delegated OAuth, but Atlassian's flow has its own scope model and quirks worth calling out. + +After completing this guide, you will be able to: + +* [ ] {learning-objective-1} +* [ ] {learning-objective-2} +* [ ] {learning-objective-3} + +== What this MCP server does + +The Jira managed type exposes tools for: + +* Searching issues with JQL. +* Reading individual issues, projects, and users. +* Creating, updating, and transitioning issues. +* Adding comments and worklog entries. + +// TODO: lift exact tool list and per-tool scope requirements from the Jira server's tool registration. + +== Prerequisites + +* A Jira (Atlassian Cloud) site where you can install or authorize an OAuth app. +* An Atlassian OAuth 2.0 (3LO) app registered against `https://api.atlassian.com`. ++ +// TODO: confirm whether Redpanda publishes a reference Atlassian app or whether each customer brings their own. +* An OAuth Provider in the ADP UI configured for Atlassian's authorize/token URLs and carrying the app's client credentials. +* Familiarity with xref:../user-delegated-oauth.adoc[]. + +== Atlassian's scope model + +Atlassian uses a granular, prefixed scope namespace. Common scopes: + +[cols="1,2"] +|=== +|Scope |Allows + +|`read:jira-user` +|Read user profile. + +|`read:jira-work` +|Read issues, projects, sprints, etc. (read-only operation). + +|`write:jira-work` +|Create, update, transition issues, add comments. + +|`offline_access` +|Issue a refresh token so Redpanda can refresh expired access tokens. *Required* for any long-lived MCP server — without it, tokens expire after one hour and users re-consent every time. +|=== + +// TODO: confirm minimum required scopes per tool from the Jira server's tool registration. + +NOTE: Always include `offline_access` in `required_scopes`. Without it, `OAuthTokenExpired` will hit users every hour. + +== Configure + +. Open *MCP Servers > Create Server*. +. Pick *Jira* from the marketplace picker. +. Fill in identity fields (`name`, `description`). +. In the Jira configuration form: ++ +* *Auth* — choose *User-delegated OAuth*. +* *OAuth Provider* — pick the Atlassian provider you configured. +* *Required scopes* — at minimum `read:jira-user`, `read:jira-work`, `offline_access`. Add `write:jira-work` if your agents will create or update issues. +. Click *Create*. + +// TODO: capture screenshots of the Jira form on `adp-production`. + +== Test the consent flow + +. Open the *Inspector* tab. +. Run an issue-search tool with a small JQL filter. +. The first call returns `OAuthConnectionRequired` with an Atlassian `authorize_url`. The Inspector surfaces it as a consent prompt. +. Click *Authorize*. Atlassian asks you to pick a site (Cloud instance) and approve scopes. +. Atlassian redirects back. Your connection appears under *My Connections* with a site label. +. Re-run the search; results come back. + +== Use with agents + +Point an agent at the *API URL* on the server's detail page. Each user calling the agent will trigger their own consent flow on first call. + +For agents that need both read and write capabilities, define the server's `required_scopes` to include all the scopes any tool might need — Atlassian doesn't allow per-tool scope upgrades, so the user consents once with the full set. + +== Troubleshooting + +[cols="1,2"] +|=== +|Symptom |What to check + +|`OAuthTokenExpired` after about an hour +|`offline_access` wasn't in `required_scopes` at consent time. Update the server config and have users re-consent. + +|"Resource not found" for a project the user has access to +|Atlassian's OAuth grants are *site-scoped*. The user authorized for one Cloud instance; the project lives on another. They need to re-consent with the second site. + +|`scope_upgrade_required` after adding write capability +|You added `write:jira-work` to `required_scopes` after users had already consented to read-only. Users re-consent with the higher scope. + +|`invalid_grant` during refresh +|Refresh tokens expire if unused for ~90 days. The user re-consents. +|=== + +// TODO: capture more Atlassian-specific errors during the live walkthrough. + +== Out of scope + +* *Atlassian app management* — the OAuth app and its callback URLs are managed in `developer.atlassian.com`, not in ADP. +* *Jira Server / Data Center* (self-hosted) — this MCP type targets Atlassian Cloud. Self-hosted Jira may need a self-managed MCP server instead. See xref:../register-remote.adoc[]. +* *Confluence access* — separate scope namespace; not exposed by this MCP server. diff --git a/modules/mcp/pages/managed/kafka.adoc b/modules/mcp/pages/managed/kafka.adoc new file mode 100644 index 0000000..2335da3 --- /dev/null +++ b/modules/mcp/pages/managed/kafka.adoc @@ -0,0 +1,118 @@ += Kafka Managed MCP Server +:description: Produce, consume, and inspect topics on Kafka or Redpanda brokers through a managed MCP server hosted in the Agentic Data Plane. +:page-topic-type: how-to +:personas: platform_admin, app_developer +:learning-objective-1: Configure the Kafka managed MCP server against a Kafka or Redpanda cluster +:learning-objective-2: Produce a test message through the Inspector and consume it back +:learning-objective-3: Pick the right authentication mode for your broker (PLAIN / SCRAM / mTLS / OAuth) + +include::ROOT:partial$adp-la.adoc[] + +The *Kafka* managed MCP server gives agents read and write access to topics on either an Apache Kafka cluster or a Redpanda cluster — the same protocol, the same tools. Despite the name, it works against any Kafka-compatible broker. + +After completing this guide, you will be able to: + +* [ ] {learning-objective-1} +* [ ] {learning-objective-2} +* [ ] {learning-objective-3} + +== What this MCP server does + +The Kafka managed type proxies a managed Kafka client. It exposes tools for: + +* Listing topics, partitions, and consumer groups. +* Producing messages to a topic. +* Consuming a window of messages from a topic. +* Inspecting topic and consumer-group metadata. + +// TODO: lift the exact tool list and descriptions from `proto/mcps/redpanda/mcps/kafka/v1/` once verified against `adp-production`. + +== Prerequisites + +* A Kafka or Redpanda cluster reachable from the Agentic Data Plane. ++ +// TODO: confirm reachability requirements (public bootstrap, peering, etc.) once the standalone ADP product surface ships. +* The cluster's bootstrap servers and SASL/TLS settings. +* For SCRAM or PLAIN: secrets in the ADP secret store for the username and password (`UPPER_SNAKE_CASE`, for example `KAFKA_SASL_USER` and `KAFKA_SASL_PASSWORD`). + +== Configure + +. Open *MCP Servers > Create Server*. +. Pick *Kafka* from the marketplace picker. +. Fill in the identity fields (`name`, `description`). +. In the Kafka configuration form, provide: ++ +// TODO: enumerate exact fields from `proto/mcps/redpanda/mcps/kafka/v1/kafka_config.proto`. ++ +* *Seed brokers* — comma-separated bootstrap addresses. +* *TLS* settings — usually on for production, off for local dev. +* *SASL mechanism* — `PLAIN`, `SCRAM-SHA-256`, `SCRAM-SHA-512`, or `OAUTHBEARER`. +* *Username / password references* — `UPPER_SNAKE_CASE` secret references. +. Click *Create*. + +// TODO: screenshot of the Kafka form filled in for a Redpanda Cloud cluster on `adp-production`. + +== Test + +. Open the *Inspector* tab on the server's detail page. +. In *Tools*, run the topic-listing tool to confirm the broker is reachable and credentials work. +. Produce a test message to a sandbox topic. +. Consume from the same topic and confirm you get the message back. + +// TODO: confirm exact tool names for produce/consume/list-topics and capture screenshots. + +See xref:../test-tools.adoc[] for general Inspector usage. + +== Authentication + +The Kafka managed type's authentication is part of its config, not the generic MCP auth oneof — it speaks Kafka protocol auth (SASL/SSL), not MCP auth. + +[cols="1,2"] +|=== +|Mechanism |Use when + +|`PLAIN` +|Username and password over TLS. Common for managed Kafka services. + +|`SCRAM-SHA-256` / `SCRAM-SHA-512` +|Salted challenge-response. Default for Redpanda Cloud. + +|`OAUTHBEARER` +|Token-based; useful when fronting Kafka with an OAuth proxy. + +|mTLS +|Client certificate. Higher operational overhead, but no shared password. +|=== + +// TODO: confirm whether mTLS and `OAUTHBEARER` are supported in the current registration; lift exact field names from the config proto. + +== Use with agents + +Once the Kafka server is created, point an agent at the *API URL* on the server's detail page. The agent can then list topics and produce/consume messages through the exposed tools. + +== Troubleshooting + +[cols="1,2"] +|=== +|Symptom |What to check + +|`connection refused` or `dial timeout` +|Brokers aren't reachable from ADP egress. Confirm bootstrap addresses and any private-network requirements. + +|`SASL authentication failed` +|Check username/password reference content and the SASL mechanism. + +|TLS handshake error +|Certificate chain isn't trusted, or you've enabled TLS against a plaintext broker. Confirm broker config. + +|Consume returns nothing +|Check topic existence, consumer-group offset behavior, and that messages exist in the time window the tool consumes. +|=== + +// TODO: gather more Kafka failure modes from `adp-production` walkthroughs. + +== Out of scope + +* *Kafka administration* (creating topics, managing ACLs) — this server is read/produce/consume-focused. For administration, use rpk or your broker's admin API. +* *Schema registry* — not exposed by this MCP server. +* *Streaming joins / processing* — for stream processing, use Redpanda Connect. diff --git a/modules/mcp/pages/managed/openapi.adoc b/modules/mcp/pages/managed/openapi.adoc new file mode 100644 index 0000000..9e8fa3e --- /dev/null +++ b/modules/mcp/pages/managed/openapi.adoc @@ -0,0 +1,116 @@ += OpenAPI Managed MCP Server +:description: Expose any OpenAPI- or Swagger-described HTTP API as MCP tools — point Redpanda at a spec URL and get a fully-typed tool surface for agents, with no custom code. +:page-topic-type: how-to +:personas: app_developer +:learning-objective-1: Configure the OpenAPI managed MCP server against an OpenAPI 3 spec +:learning-objective-2: Pick the right authentication mode for the upstream API +:learning-objective-3: Verify generated tools through the Inspector + +include::ROOT:partial$adp-la.adoc[] + +The *OpenAPI* managed MCP server is the "bring your own API" escape hatch. Hand it an OpenAPI 3 (or Swagger 2) spec, and it generates one MCP tool per operation in the spec. No custom code, no per-API managed type — useful when the API you want to expose is not in the catalog. + +After completing this guide, you will be able to: + +* [ ] {learning-objective-1} +* [ ] {learning-objective-2} +* [ ] {learning-objective-3} + +== What this MCP server does + +The OpenAPI managed type: + +* Loads an OpenAPI 3 (or Swagger 2) spec from a URL or pasted JSON/YAML. +* Generates one MCP tool per operation, with input schemas derived from the spec's parameter and request-body schemas. +* Forwards calls to the upstream API, applying the configured authentication. + +// TODO: confirm exact spec versions supported (OpenAPI 3.0 vs. 3.1 vs. Swagger 2) and any spec features that are unsupported (oneOf, discriminators, callbacks). + +== Prerequisites + +* An HTTP API with an OpenAPI 3 (or Swagger 2) spec. +* The spec URL or the spec content itself. +* Credentials for the API, if it requires them. + +== Configure + +. Open *MCP Servers > Create Server*. +. Pick *OpenAPI* from the marketplace picker. +. Fill in identity fields (`name`, `description`). +. In the OpenAPI configuration form: ++ +// TODO: enumerate exact fields from `apps/aigw/internal/mcp/managed/mcps/openapi/register.go` (spec source, base URL override, tool-name strategy, operation include/exclude lists). ++ +* *Spec source* — URL or inline text. +* *Base URL override* (optional) — useful when the spec's `servers` block doesn't match your environment. +* *Operations to expose* (optional) — filter by `operationId`, path, or method if you want only a subset. +. Configure auth (see <>). +. Click *Create*. + +== Authentication + +OpenAPI is the most flexible managed type for auth — the upstream API can need anything. All the standard auth modes apply: + +[cols="1,2"] +|=== +|Mode |Use when + +|*None* +|Public APIs (rare in practice). + +|*Static key* +|API expects a token in a header. Set `header_name` to the API's expected header (`Authorization`, `X-Api-Key`, etc.). + +|*Token passthrough* +|The API already validates the caller's `Authorization` header. + +|*Service-account OAuth* +|API supports OAuth client credentials and you want one shared identity. + +|*User-delegated OAuth* +|API supports OAuth on behalf of users and you want per-user identities. Requires an OAuth Provider configured for that API. See xref:../user-delegated-oauth.adoc[]. +|=== + +== Test + +. Open the *Inspector* tab. +. The Tools panel lists every operation from your spec, named per the `operationId` (or per the path if `operationId` is missing). +. Pick one and run it. The Inspector renders a form from the operation's parameter and request-body schemas. + +// TODO: capture screenshots of a non-trivial OpenAPI spec rendered in the Inspector once we walk a real example on `adp-production`. + +See xref:../test-tools.adoc[] for general Inspector usage. + +== Use with agents + +Once tools generate cleanly, point an agent at the *API URL* on the server's detail page. The agent sees one tool per OpenAPI operation, named accordingly. + +== Troubleshooting + +[cols="1,2"] +|=== +|Symptom |What to check + +|"Failed to load spec" +|Confirm the spec URL is reachable from ADP and serves valid JSON or YAML. CORS doesn't matter (Redpanda fetches server-side). + +|Tools list doesn't include an expected operation +|The operation may be missing an `operationId`, or the operation include/exclude filters might be excluding it. + +|Tool input schema looks wrong +|Spec features (oneOf, discriminator, etc.) might not translate cleanly. See the TODO above on supported versions/features. + +|Calls return 401 +|Auth mode or credentials are wrong. Confirm secret content and the API's expected auth header. + +|Calls return 404 with the right operation +|`servers` block in the spec doesn't match your real API endpoint. Use the *Base URL override*. +|=== + +// TODO: capture more spec-specific failure modes during the live walkthrough. + +== Out of scope + +* *Custom tool logic* — the OpenAPI type is purely a spec-to-tools generator. For business logic on top of the API, use a self-managed MCP server (xref:../register-remote.adoc[]). +* *GraphQL APIs* — OpenAPI doesn't describe GraphQL; for GraphQL APIs, use a self-managed server. +* *gRPC services* — same. diff --git a/modules/mcp/pages/managed/slack.adoc b/modules/mcp/pages/managed/slack.adoc new file mode 100644 index 0000000..68788a7 --- /dev/null +++ b/modules/mcp/pages/managed/slack.adoc @@ -0,0 +1,103 @@ += Slack Managed MCP Server +:description: Let agents post messages and read channels in your Slack workspace using each end-user's own Slack identity through user-delegated OAuth. +:page-topic-type: how-to +:personas: app_developer +:learning-objective-1: Configure the Slack managed MCP server with user-delegated OAuth +:learning-objective-2: Walk through the consent flow and verify the connection in My Connections +:learning-objective-3: Send a test message through the Inspector + +include::ROOT:partial$adp-la.adoc[] + +The *Slack* managed MCP server is the canonical user-delegated OAuth example for ADP. Each agent caller authenticates against Slack with their own credentials, and Redpanda injects their token at call time — so messages posted by the agent appear as the user, not as a shared bot. + +After completing this guide, you will be able to: + +* [ ] {learning-objective-1} +* [ ] {learning-objective-2} +* [ ] {learning-objective-3} + +== What this MCP server does + +The Slack managed type exposes tools for: + +* Listing channels and reading channel history. +* Posting messages and replying in threads. +* Looking up users. + +// TODO: lift exact tool list and tool-by-tool scope requirements from the Slack server's tool registration. + +== Prerequisites + +* A Slack workspace where you can install or authorize an OAuth app. +* A Slack OAuth app registered (your own or a Redpanda-published reference app). ++ +// TODO: confirm whether Redpanda ships a reference Slack OAuth app or whether each customer brings their own. Document the path. +* An OAuth Provider configured in the ADP UI under *OAuth Providers*, pointing at Slack's authorize/token URLs and carrying the OAuth app's client credentials. ++ +// TODO: link the OAuth Provider how-to once it exists. +* Familiarity with xref:../user-delegated-oauth.adoc[]. + +== Configure + +. Open *MCP Servers > Create Server*. +. Pick *Slack* from the marketplace picker. +. Fill in the identity fields (`name`, `description`). +. In the Slack configuration form: ++ +// TODO: enumerate exact fields. Slack's MCP type likely doesn't need workspace-specific configuration — the OAuth flow tells Slack which workspace. ++ +* *Auth* — choose *User-delegated OAuth*. +* *OAuth Provider* — pick the Slack provider you configured. +* *Required scopes* — typical: `channels:read`, `chat:write`, `users:read`. Adjust to your need. +. Click *Create*. + +== Test the consent flow + +. Open the *Inspector* tab. +. Run a tool that requires the user's identity, for example `chat_postMessage`. +. The first call returns `OAuthConnectionRequired` with a Slack `authorize_url`. The Inspector surfaces it as a consent prompt. +. Click *Authorize*. You're redirected to Slack; pick the workspace and approve the requested scopes. +. Slack redirects back to ADP. Your connection now appears under *My Connections*. +. Re-run the original tool call. The message posts to Slack as your user. + +// TODO: screenshots of the consent prompt, Slack's approval screen, and the My Connections entry post-consent. + +== Authentication scopes + +Slack distinguishes user tokens from bot tokens, and many tools need user-token scopes. Common gotchas: + +* `chat:write` is a *user* scope; `chat:write.public` is a separate scope for posting in channels the user isn't a member of. +* `channels:read` returns only channels the user can see. +* Tokens are workspace-scoped — the same user authorizing twice across two workspaces produces two separate connections. + +// TODO: confirm exact required scopes per tool from the Slack server's tool registration. + +== Use with agents + +Once the server is created and at least one user has consented, you can point an agent at the *API URL* on the server's detail page. Each user calling the agent will trigger their own consent flow if they haven't connected yet. + +== Troubleshooting + +[cols="1,2"] +|=== +|Symptom |What to check + +|`OAuthConnectionRequired` even after consent +|The token might be revoked or expired with no refresh. Check *My Connections*; remove and re-add if needed. + +|`scope_upgrade_required` +|The server's required scopes were widened after the user consented. The user re-consents to grant the new scope. + +|"channel not found" on a channel the user can see in Slack +|Some private channels need an explicit `groups:read` scope. Add it to the server's required scopes and have users re-consent. + +|`invalid_auth` from Slack +|The OAuth Provider's client credentials are wrong, or the OAuth app has been suspended in Slack. Check the provider config. +|=== + +// TODO: capture more Slack-specific errors during the live walkthrough. + +== Out of scope + +* *Configuring the Slack OAuth app* — Slack-side configuration (creating the app, picking redirect URIs, choosing scopes) happens in api.slack.com, not in ADP. +* *Posting as a Slack bot* — this page covers user-delegated auth. For bot-token posting, use static-key auth with a bot user OAuth token. diff --git a/modules/mcp/pages/managed/sql.adoc b/modules/mcp/pages/managed/sql.adoc new file mode 100644 index 0000000..85792d0 --- /dev/null +++ b/modules/mcp/pages/managed/sql.adoc @@ -0,0 +1,112 @@ += SQL Managed MCP Server +:description: Query SQL databases — Postgres, MySQL, ClickHouse, MSSQL, SQLite — through a managed MCP server hosted by Redpanda. +:page-topic-type: how-to +:personas: platform_admin, app_developer +:learning-objective-1: Configure the SQL managed MCP server for your database +:learning-objective-2: Run a canonical SELECT query through the Inspector +:learning-objective-3: Pick the right authentication and connection-string pattern for your database + +include::ROOT:partial$adp-la.adoc[] + +The SQL managed MCP server gives agents read access to a SQL database through MCP. Redpanda runs the server in-process; you provide a connection string and credentials. + +After completing this guide, you will be able to: + +* [ ] {learning-objective-1} +* [ ] {learning-objective-2} +* [ ] {learning-objective-3} + +== What this MCP server does + +Redpanda's SQL managed type proxies queries to one of these database engines: + +* PostgreSQL +* MySQL / MariaDB +* ClickHouse +* Microsoft SQL Server +* SQLite + +It exposes a small set of tools for querying schemas and running parameterized queries. + +// TODO: lift the exact tool list and per-tool descriptions from `proto/mcps/redpanda/mcps/sql/v1/` once verified against `adp-production`. + +== Prerequisites + +* A SQL database reachable from the Agentic Data Plane. ++ +// TODO: confirm network reachability requirements (egress / VPC peering / public endpoint) for the standalone ADP product surface. +* A connection string or the connection components (host, port, database, user). +* A secret in the ADP secret store containing the database password (`UPPER_SNAKE_CASE`, for example `SQL_PASSWORD`). + +== Configure + +. Open *MCP Servers > Create Server*. +. Pick *SQL* from the marketplace picker. +. Fill in the identity fields (`name`, `description`). +. In the SQL configuration form, provide: ++ +// TODO: enumerate exact fields from `proto/mcps/redpanda/mcps/sql/v1/sql_config.proto` — driver, DSN/connection-string format, query timeout, read-vs-write-tool split, max rows. ++ +* *Driver* — Postgres, MySQL, ClickHouse, MSSQL, or SQLite. +* *Connection string* — driver-specific. +* *Password reference* — `UPPER_SNAKE_CASE` secret reference. +* *Query timeout* (optional). +. Click *Create*. + +// TODO: screenshot of the SQL form filled in for a Postgres example on `adp-production`. + +== Test + +After create, exercise the server through the Inspector tab. See xref:../test-tools.adoc[]. + +A canonical first call: + +. Open the *Inspector* tab. +. In *Tools*, select the schema-listing tool (likely `list_tables` or similar). ++ +// TODO: confirm exact tool name from the proto's service definition. +. Run with no arguments. Confirm a list of tables comes back. +. Select the query tool. Run `SELECT 1` (or your driver's equivalent). Confirm a single-row response. + +== Authentication + +The SQL managed type supports: + +* *None* — only useful for local SQLite without auth. +* *Static key* — most common; the password lives in a secret reference. + +User-delegated OAuth and service-account OAuth are *not* supported for SQL — there's no per-user identity model that maps to a database password. + +// TODO: confirm exact auth modes the SQL type registers in its `register_mcp.go` once an auth-mode list is exposed on `ManagedMCPType`. + +== Use with agents + +Once the SQL server is created, point an agent at the *API URL* on the server's detail page. The agent sees the SQL tools alongside any other MCP servers it has access to. + +// TODO: link the Agents docs section that walks through wiring an MCP server into an agent definition. + +== Troubleshooting + +[cols="1,2"] +|=== +|Symptom |What to check + +|`connection refused` from create +|Database isn't reachable from ADP. Confirm host, port, and any egress / firewall rules. + +|`authentication failed for user` +|Password reference points at the wrong secret, or the secret content is wrong. Re-create the secret with `UPPER_SNAKE_CASE` and verify it. + +|Query timeout +|Long-running queries exceed the configured timeout. Either tighten the query or raise the timeout on the server config. + +|Tools list returns empty +|The driver couldn't introspect the schema. Verify the user has read access to `information_schema` (Postgres/MySQL) or the equivalent. +|=== + +// TODO: gather more failure modes once we walk SQL on `adp-production`. + +== Out of scope + +* *Schema migrations* — this server is read/query-focused; running DDL is not the intended use. +* *Per-user database identities* — see <>. diff --git a/modules/mcp/pages/overview.adoc b/modules/mcp/pages/overview.adoc deleted file mode 100644 index 507bfa2..0000000 --- a/modules/mcp/pages/overview.adoc +++ /dev/null @@ -1,92 +0,0 @@ -= MCP Servers for Redpanda Cloud Overview -:page-aliases: redpanda-cloud:ai-agents:mcp/overview.adoc -:description: Connect AI agents to your databases, queues, CRMs, and other business systems without writing glue code, using Redpanda's proven connectors. -:page-topic-type: overview -:personas: evaluator, ai_agent_developer -// Reader journey: "I'm new" - understanding the landscape -// Learning objectives - what readers should understand after reading this page: -:learning-objective-1: Describe what MCP enables for AI agents -:learning-objective-2: Distinguish between Redpanda Cloud Management MCP Server and Remote MCP -:learning-objective-3: Choose the right MCP option for your use case - -This page introduces MCP in Redpanda Cloud and helps you choose the right option for your use case. - -After reading this page, you will be able to: - -* [ ] {learning-objective-1} -* [ ] {learning-objective-2} -* [ ] {learning-objective-3} - -== What is MCP? - -MCP (Model Context Protocol) is an open standard that translates AI agent intent into real connections to databases, queues, CRMs, HRIS, accounting software, and other business systems. Instead of writing custom glue code for every integration, you define your tools once using MCP, and any MCP-compatible AI client can discover and use them. - -Without MCP, connecting AI to your business systems requires custom API code, authentication handling, and response formatting for each AI platform. With MCP, you describe what a tool does and what inputs it needs, and the protocol handles the rest. Redpanda's MCP servers are built on the same proven connectors that power the world's largest e-commerce, electric vehicle, energy, and AI companies today. - -== MCP options in Redpanda Cloud - -Redpanda Cloud offers two complementary MCP options: - -* *Redpanda Cloud Management MCP Server*: A pre-built server that gives AI agents access to Redpanda Cloud APIs. It runs on your computer and lets you manage clusters, topics, and other resources through natural language. -+ -Example: "Create a cluster called `dev-analytics` with 3 brokers." - -* *Remote MCP*: Your own MCP server built with Redpanda Connect and hosted inside your Redpanda Cloud cluster. You define custom tools that access your data, call external APIs, or trigger workflows. -+ -Example: "Analyze the last 100 orders and show me the top product categories." - -=== Comparison - -[cols="1h,2,2"] -|=== -| | Redpanda Cloud Management MCP Server | Remote MCP - -| Purpose -| Operate your Redpanda Cloud account -| Build custom tools for your data and workflows - -| Where it runs -| Your computer -| Redpanda Cloud (managed) - -| Who builds it -| Redpanda -| You, using Redpanda Connect - -| Access to -| Redpanda Cloud APIs (clusters, topics, users, ACLs) -| Anything you configure (databases, APIs, Redpanda topics, LLMs) - -| Best for -| Platform operations, quick admin tasks, incident response -| Data analysis, workflow automation, team-shared tools -|=== - -== Which should I use? - -Choose based on what you want to accomplish: - -**Use the Redpanda Cloud Management MCP Server** when you want to: - -* Manage Redpanda Cloud resources without memorizing CLI commands -* Quickly create test clusters, topics, or users -* Inspect cluster health during incidents -* Onboard team members who prefer natural language over APIs - -**Use Remote MCP** when you want to: - -* Build tools that access your business data in Redpanda topics -* Create reusable tools shared across your team -* Connect AI agents to external systems (databases, APIs, LLMs) -* Run tools close to your data with managed infrastructure - -You can use both options together. For example, use the Redpanda Cloud Management MCP Server to create a cluster, then deploy Remote MCP tools to analyze data in that cluster. - -== Get started - -* xref:local/quickstart.adoc[]: Connect Claude to your Redpanda Cloud account -* xref:remote/quickstart.adoc[]: Build and deploy custom MCP tools - -== Suggested reading - -* xref:home:ROOT:mcp-setup.adoc[]: Access Redpanda documentation through AI agents (read-only, no Cloud access required) diff --git a/modules/mcp/pages/register-remote.adoc b/modules/mcp/pages/register-remote.adoc new file mode 100644 index 0000000..4de38d1 --- /dev/null +++ b/modules/mcp/pages/register-remote.adoc @@ -0,0 +1,147 @@ += Register a Self-Managed MCP Server +:description: Front your own MCP server with a managed Redpanda URL — pick a transport, configure authentication, and let agents discover the server's tools through Redpanda. +:page-topic-type: how-to +:personas: platform_admin +:learning-objective-1: Register a self-managed MCP server in the ADP UI +:learning-objective-2: Pick the right transport (SSE vs. Streamable HTTP) and authentication mode +:learning-objective-3: Confirm tool discovery completed and the server is reachable through its proxy URL + +include::ROOT:partial$adp-la.adoc[] + +Register your existing MCP server with Redpanda to add authentication, observability, and agent aggregation without changing your server's code. This guide covers the self-managed path from xref:create-server.adoc[Create an MCP Server] in depth — choose this when you already run a server and want Redpanda to proxy it. + +After completing this guide, you will be able to: + +* [ ] {learning-objective-1} +* [ ] {learning-objective-2} +* [ ] {learning-objective-3} + +== When to use this + +Choose self-managed registration when: + +* The MCP server is already deployed in your environment and you don't want to migrate it to a managed type. +* You need custom tool logic that no managed type provides. +* You want a unified MCP URL (and Inspector / observability / agent access) across servers without standing up your own gateway. + +If you don't already run a server, prefer a managed type — see xref:managed-catalog.adoc[Managed catalog] for the catalog. + +== Prerequisites + +* An MCP server reachable from the Agentic Data Plane. ++ +// TODO: confirm network reachability requirements (egress / VPC peering / public endpoint) once the standalone ADP product surface ships. +* The endpoint URL. `http://` is allowed for everything except user-delegated OAuth, which requires `https://` (proto rule `remote_mcp.user_oauth_requires_https`). +* Knowledge of which transport the server speaks — SSE or Streamable HTTP. If you don't know, see <>. +* If using static-key or service-account-OAuth: secrets pre-created in the ADP secret store, `UPPER_SNAKE_CASE` (proto regex `^[A-Z][A-Z0-9_]*$`). +* If using user-delegated OAuth: an OAuth Provider already configured. See xref:user-delegated-oauth.adoc[User-delegated OAuth]. + +== Create the server + +. Open *MCP Servers* and click *Create Server*. +. In the marketplace picker, choose *Remote (Proxied)*. ++ +// TODO: screenshot of the marketplace picker with Remote (Proxied) highlighted. +. Fill in the identity fields (`name`, `description`, `enabled`) — same constraints as in xref:create-server.adoc[Create an MCP Server]. +. Provide the *URL* and *Transport*. +. Configure authentication (see <>). +. Click *Create*. + +// TODO: screenshot of the self-managed create form with URL and transport visible. + +[[test-transport]] +== Transport choice + +Two transports are available on the proto enum `MCPTransport`: + +* *SSE* — server-sent events. The traditional MCP transport. +* *Streamable HTTP* — newer bidirectional protocol. + +Pick whichever your server actually speaks. To probe a server quickly: + +[source,bash] +---- +# SSE handshake — expect a stream of `event:` lines on success. +curl -N -H "Accept: text/event-stream" https://your-server.example.com/mcp/sse + +# Streamable HTTP — expect a JSON-RPC response on success. +curl -X POST -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \ + https://your-server.example.com/mcp +---- + +// TODO: lift exact handshake examples from the MCP spec and verify against `adp-production` once we have a known-good self-managed test endpoint. + +[[authentication]] +== Authentication + +The five auth modes from xref:create-server.adoc#configure-authentication[create-server.adoc] all apply. Three patterns are particularly common for self-managed servers: + +[cols="1,2"] +|=== +|Pattern |Use when + +|*Static key with a custom header* +|First-party servers that authenticate with a non-`Authorization` header. Provide a `header_name` (for example, `X-Api-Key`) and a `key_ref` pointing at a `UPPER_SNAKE_CASE` secret. + +|*Service-account OAuth* +|The upstream system supports OAuth client credentials and you want one shared identity for all callers. Provide `client_id`, `client_secret_ref`, `token_url`, and any required `scopes`. + +|*Token passthrough* +|The upstream server already validates client tokens — Redpanda just forwards the caller's `Authorization` header. +|=== + +For user-delegated OAuth, the URL must be `https://` and you also need an OAuth Provider. See xref:user-delegated-oauth.adoc[User-delegated OAuth]. + +// TODO: screenshots of each auth-mode form panel after walking `adp-production`. + +== Tool discovery + +After create, Redpanda runs a live `tools/list` (the `ListMCPServerTools` RPC) against the server. The result is cached on the `MCPServer.tools` output-only field and shown on the detail page's *Overview* tab. The *Inspector* tab (see xref:test-tools.adoc[Test a server's tools]) exercises individual glossterm:tool[,tools]. + +If the tools list is empty or stale, hit the *Refresh tools* action on the Overview tab to re-query the server. + +// TODO: confirm exact UI affordance for triggering a re-list. + +== Connection errors and retry + +[cols="1,2"] +|=== +|Error |What it means + +|`OAuthConnectionRequired` +|The user-delegated auth path needs a stored token vault entry for the calling user. Redpanda surfaces an `authorize_url` so the user can complete the consent flow. See xref:user-delegated-oauth.adoc[User-delegated OAuth]. + +|`OAuthTokenExpired` +|The user's stored token has expired and refresh failed. Surface the new authorize URL and have the user re-consent. + +|Plain connection error / 502 / 504 +|Redpanda couldn't reach your server. Look at the *Connection* tab on the detail page for the upstream error and check the connection-status banner. +|=== + +== Troubleshooting + +[cols="1,2"] +|=== +|Symptom |What to check + +|"Transport mismatch" or empty stream +|Your server speaks the other transport. Re-probe with curl per <> and update the *Transport* field on the server's edit page. + +|TLS errors when registering an `https://` URL +|Confirm the server's certificate chains to a public CA (or the CA Redpanda's egress trusts). Self-signed certs aren't supported. ++ +// TODO: confirm TLS / private CA story for the standalone ADP product surface. + +|`401 Unauthorized` from the upstream +|Authentication is misconfigured. For static-key or service-account-OAuth, verify the secret content and `header_name`. For token passthrough, confirm the caller is sending an `Authorization` header. + +|Tool schema parse errors +|The server returned a `tools/list` response with an invalid JSON schema for one or more tool inputs. Fix the upstream tool's schema and refresh. +|=== + +== Out of scope + +* *User-delegated OAuth consent flow* — see xref:user-delegated-oauth.adoc[User-delegated OAuth]. +* *Multi-server aggregation* (one MCP URL fronting many servers) — handled by AI Gateway. See xref:ai-gateway:aggregation.adoc[MCP aggregation]. +* *Server hosting and deployment guidance* — Redpanda doesn't operate self-managed servers; deployment, scaling, and patching are your responsibility. diff --git a/modules/mcp/pages/remote/best-practices.adoc b/modules/mcp/pages/remote/best-practices.adoc deleted file mode 100644 index 6883115..0000000 --- a/modules/mcp/pages/remote/best-practices.adoc +++ /dev/null @@ -1,42 +0,0 @@ -= MCP Tool Design -:description: Design effective MCP tool interfaces with clear names, descriptions, and input properties. -:page-topic-type: best-practices -:personas: agent_developer -// Reader journey: "I want AI clients to discover and use my tools effectively" -// Learning objectives - what readers should be able to do after reading this page: -:learning-objective-1: Write tool names and descriptions that help AI clients select the right tool -:learning-objective-2: Define input properties with appropriate types and constraints -:learning-objective-3: Design focused tools that complete quickly - -After xref:remote/create-tool.adoc[creating your first tool], apply these design guidelines so AI clients can discover, understand, and invoke your tools correctly. - -After reading this page, you will be able to: - -* [ ] {learning-objective-1} -* [ ] {learning-objective-2} -* [ ] {learning-objective-3} - -[[tool-discovery]] -== Tool discovery - -include::redpanda-connect:ai-agents:partial$mcp/best-practices/mcp-metadata-design.adoc[] - -[[tool-execution]] -== Tool execution - -include::redpanda-connect:ai-agents:partial$mcp/best-practices/tool-implementation-practices.adoc[] - -== Complete example - -This example combines all the best practices: - -[source,yaml] ----- -include::redpanda-connect:ai-agents:example$best-practices/mcp-metadata/search-customer-orders.yaml[tags=complete-example] ----- - -== Next steps - -* xref:remote/create-tool.adoc#secrets[Use secrets for credentials] -* xref:mcp:remote/patterns.adoc[] -* xref:remote/troubleshooting.adoc[] diff --git a/modules/mcp/pages/remote/concepts.adoc b/modules/mcp/pages/remote/concepts.adoc deleted file mode 100644 index 84b486b..0000000 --- a/modules/mcp/pages/remote/concepts.adoc +++ /dev/null @@ -1,48 +0,0 @@ -= MCP Tool Execution and Components -:description: Understand how MCP tools execute requests, choose the right Redpanda Connect component type, and use traces for observability. -// TODO: Add 'redpanda-cloud:ai-agents:mcp/remote/concepts.adoc' after ai-agents removed from cloud-docs -:page-aliases: redpanda-cloud:ai-agents:mcp/remote/understanding-mcp-tools.adoc -:page-topic-type: concepts -:personas: agent_developer, streaming_developer -// Reader journey: "I want to understand how it works" -// Learning objectives - what readers should know after reading this page: -:learning-objective-1: Describe the request/response execution model -:learning-objective-2: Choose the right component type for a use case -:learning-objective-3: Interpret MCP server traces for debugging and monitoring - -This page explains how MCP tools execute and how to choose the right component type for your use case. - -After reading this page, you will be able to: - -* [ ] {learning-objective-1} -* [ ] {learning-objective-2} -* [ ] {learning-objective-3} - -// Component mapping - single-sourced from partial -include::redpanda-connect:ai-agents:partial$mcp/concepts/component-mapping.adoc[] - -// Execution model - single-sourced from partial -include::redpanda-connect:ai-agents:partial$mcp/concepts/execution-model.adoc[] - -MCP tools use an agent-initiated execution model where agents invoke tools on-demand. Redpanda also supports pipeline-initiated integration where pipelines call agents using the `a2a_message` processor. For guidance on choosing between these patterns, see xref:agents:integration-overview.adoc[]. - -[[component-selection]] -== Choose the right component type - -// Component selection guide - single-sourced from partial -include::redpanda-connect:ai-agents:partial$mcp/concepts/component-selection.adoc[] - -== Observability - -MCP servers automatically emit OpenTelemetry traces for monitoring and debugging. For detailed information about traces, spans, and the trace structure, see xref:observability:concepts.adoc[]. - -To monitor MCP server activity, consume traces, and debug failures, see xref:remote/monitor-mcp-servers.adoc[]. - -include::ROOT:partial$service-account-authorization.adoc[] - -== Next steps - -* xref:remote/create-tool.adoc[] -* xref:remote/best-practices.adoc[] -* xref:mcp:remote/patterns.adoc[] -* xref:remote/troubleshooting.adoc[] diff --git a/modules/mcp/pages/remote/create-tool.adoc b/modules/mcp/pages/remote/create-tool.adoc deleted file mode 100644 index 8cf29c9..0000000 --- a/modules/mcp/pages/remote/create-tool.adoc +++ /dev/null @@ -1,260 +0,0 @@ -= Create an MCP Tool -:description: Create an MCP tool with the correct YAML structure, metadata, and parameter mapping. -:page-topic-type: how-to -:personas: agent_developer, streaming_developer, data_engineer -// Reader journey: "I want to create a tool for my AI agent" -// Learning objectives - what readers can do after reading this page: -:learning-objective-1: Create a tool with the correct structure and MCP metadata -:learning-objective-2: Map MCP parameters to component configuration fields using Bloblang -:learning-objective-3: Test tools using the MCP Inspector - -After xref:remote/quickstart.adoc[deploying your first MCP server], create custom tools that AI clients can discover and invoke. This guide walks you through the process using any Redpanda Connect component. - -After reading this page, you will be able to: - -* [ ] {learning-objective-1} -* [ ] {learning-objective-2} -* [ ] {learning-objective-3} - -== Prerequisites - -* A Redpanda Cloud cluster with *Remote MCP* enabled. -* You can describe the MCP execution model (see xref:remote/concepts.adoc#execution-model[The MCP execution model]) -* You have chosen the right component type for your use case (see xref:remote/concepts.adoc#component-selection[Choose the right component type]) - -== Create the tool - -In Redpanda Cloud, you create tools directly in the Cloud Console or using the Data Plane API. - -[tabs] -====== -Cloud Console:: -+ --- -. Log in to the link:https://cloud.redpanda.com/[Redpanda Cloud Console^]. - -. Navigate to *Agentic AI* > *Remote MCP* and either create a new MCP server or edit an existing one. - -. In the *Tools* section, click *Add Tool*. - -. Enter the YAML configuration for your tool. - -. Click *Lint* to validate your configuration. - -. Click *Save* to deploy the tool. --- - -Data Plane API:: -+ --- -Use the link:/api/doc/cloud-dataplane/operation/operation-mcpserverservice_createmcpserver[Create MCP Server] or link:/api/doc/cloud-dataplane/operation/operation-mcpserverservice_updatemcpserver[Update MCP Server] endpoints to add tools programmatically. --- -====== - -[[yaml-structure]] -== Add the tool structure - -An MCP tool wraps a xref:redpanda-cloud:develop:connect/components/about.adoc[Redpanda Connect component] and exposes it to AI clients. Each tool has three parts: - -* **Label**: The tool name AI clients see -* **Component configuration**: A Redpanda Connect component (processor, input, output, or cache) that does the work -* **MCP metadata**: Describes the tool's purpose and parameters for AI clients - -Here's an example using the xref:redpanda-cloud:develop:connect/components/processors/sql_select.adoc[`sql_select` processor]: - -[source,yaml] ----- -include::ROOT:example$mcp-tools/processors/lookup_customer.yaml[tag=complete,indent=0] ----- - -<1> **Label**: Becomes the tool name. -<2> **Component**: The `sql_select` processor configured to query a database. -<3> **MCP metadata**: Tells AI clients what this tool does and what parameters it accepts. - -Each tool configuration must contain exactly one component. The component type is inferred from the type you select when creating or editing the MCP server. The component can be a processor, input, output, or cache. - -The following sections show how to structure tools for each component type. - -=== Label naming rules - -include::redpanda-connect:ai-agents:partial$mcp/create-tool/label-naming-rules.adoc[] - -=== Component types - -xref:redpanda-cloud:develop:connect/components/processors/about.adoc[Processors] transform, filter, or enrich data. Use a `processors:` array with one or more processors: - -.Processor tool -[source,yaml] ----- -include::ROOT:example$mcp-tools/processors/enrich_order.yaml[tag=complete,indent=0] ----- - -xref:redpanda-cloud:develop:connect/components/inputs/about.adoc[Inputs] read data from sources, xref:redpanda-cloud:develop:connect/components/outputs/about.adoc[outputs] write data to destinations, and xref:redpanda-cloud:develop:connect/components/caches/about.adoc[caches] store and retrieve data. Define these components directly at the top level: - -.Input tool -[source,yaml] ----- -include::ROOT:example$mcp-tools/inputs/read_events.yaml[tag=complete,indent=0] ----- -<1> The component name (`redpanda`) is at the top level, not wrapped in `input:`. - -.Output tool -[source,yaml] ----- -include::ROOT:example$mcp-tools/outputs/publish_event.yaml[tag=complete,indent=0] ----- - -.Cache tool -[source,yaml] ----- -include::ROOT:example$mcp-tools/caches/session_cache.yaml[tag=complete,indent=0] ----- - -Outputs can include a `processors:` section to transform data before publishing: - -.Output tool with processors -[source,yaml] ----- -include::ROOT:example$mcp-tools/outputs/publish_with_timestamp.yaml[tag=complete,indent=0] ----- - -See xref:mcp:remote/patterns.adoc#outputs-with-processors[outputs with processors] for more examples. - -Do not wrap components in `input:`, `output:`, or `cache:` blocks. This syntax is for pipelines, not MCP tools. - -[[mcp-metadata]] -=== MCP metadata fields - -The `meta.mcp` block defines how AI clients discover and interact with your tool. These fields control tool visibility, naming, and input parameters. - -include::redpanda-connect:ai-agents:partial$mcp/create-tool/mcp-metadata-fields-table.adoc[] - -[#mcp-property-fields] -==== Property fields - -include::redpanda-connect:ai-agents:partial$mcp/create-tool/property-fields-table.adoc[] - -[[property-restrictions]] -==== Property restrictions by component type - -include::redpanda-connect:ai-agents:partial$mcp/create-tool/property-restrictions-table.adoc[] - -[[parameter-mapping]] -== Map parameters to component fields - -When an AI client calls your tool, the `arguments` object becomes the message body. You can access these arguments using xref:redpanda-cloud:develop:connect/guides/bloblang/about.adoc[Bloblang], but the syntax depends on where you're using it: - -* **Inside Bloblang contexts** (mutation, mapping, args_mapping): Use `this.field_name` -* **Inside string fields** (URLs, topics, headers): Use interpolation `${! json("field_name") }` - -=== In Bloblang contexts - -Use `this` to access message fields directly in processors like `mutation`, `mapping`, or in `args_mapping` fields: - -[source,yaml] ----- -include::ROOT:example$mcp-tools/snippets/bloblang_this_context.yaml[tag=mutation,indent=0] ----- - -[source,yaml] ----- -include::ROOT:example$mcp-tools/snippets/bloblang_this_context.yaml[tag=args_mapping,indent=0] ----- - -=== In string fields (interpolation) - -Use `${! ... }` interpolation to embed Bloblang expressions inside string values like URLs or topic names: - -[source,yaml] ----- -include::ROOT:example$mcp-tools/snippets/interpolation.yaml[tag=http_url,indent=0] ----- - -[source,yaml] ----- -include::ROOT:example$mcp-tools/snippets/interpolation.yaml[tag=redpanda_topic,indent=0] ----- -<1> `$\{VAR}` without `!` is environment variable substitution, not Bloblang. -<2> `${! ... }` with `!` is Bloblang interpolation that accesses message data. - -TIP: For more on Bloblang syntax, see xref:redpanda-cloud:develop:connect/guides/bloblang/about.adoc[]. For interpolation details, see xref:redpanda-cloud:develop:connect/configuration/interpolation.adoc[]. - -=== Provide defaults for optional parameters - -Use `.or(default)` to handle missing optional parameters: - -[source,yaml] ----- -include::ROOT:example$mcp-tools/snippets/defaults.yaml[tag=mutation,indent=0] ----- - -Declare which parameters are required in your `meta.mcp.properties`: - -[source,yaml] ----- -include::ROOT:example$mcp-tools/snippets/defaults.yaml[tag=properties,indent=0] ----- - -[[secrets]] -== Use the Secrets Store - -Never hardcode credentials, API keys, or connection strings in your tool configurations. Use the xref:redpanda-cloud:develop:connect/configuration/secret-management.adoc[Secrets Store] to securely manage sensitive values. - -Reference secrets using `${secrets.SECRET_NAME}` syntax: - -[source,yaml] ----- -include::ROOT:example$mcp-tools/snippets/secrets.yaml[tag=example,indent=0] ----- - -When you add secret references to your tool configuration, the Cloud Console automatically detects them and provides an interface to create the required secrets. - -=== Secrets best practices - -* Use uppercase snake_case for secret names (for example, `DATAPLANE_TOKEN`, `API_KEY`). -* Rotate secrets periodically. -* Follow the principle of least privilege. Only request the scopes and roles your tool actually needs. - -See xref:remote/best-practices.adoc#secrets[Secrets management] for more guidance. - -== Test the tool - -. Click *Lint* to validate your configuration. - -. Deploy the MCP server. - -. Use the *MCP Inspector* tab to test tool calls: -+ -* Select the tool from the list -* Enter test parameter values -* Click *Run Tool* to execute -* Review the response - -. Connect an AI client and verify the tool appears: -+ -[,bash] ----- -rpk cloud mcp proxy \ - --cluster-id \ - --mcp-server-id \ - --install --client claude-code ----- - -. Test end-to-end with realistic prompts to verify the AI client uses your tool correctly. - -== Complete example - -Here's a complete tool that wraps the `http` processor to fetch weather data: - -[source,yaml] ----- -include::ROOT:example$mcp-tools/processors/get_weather_complete.yaml[tag=complete,indent=0] ----- - -== Next steps - -* xref:agents:quickstart.adoc[] -* xref:remote/best-practices.adoc[] -* xref:mcp:remote/patterns.adoc[] -* xref:remote/troubleshooting.adoc[] -* xref:redpanda-cloud:develop:connect/components/about.adoc[] diff --git a/modules/mcp/pages/remote/index.adoc b/modules/mcp/pages/remote/index.adoc deleted file mode 100644 index 2233299..0000000 --- a/modules/mcp/pages/remote/index.adoc +++ /dev/null @@ -1,3 +0,0 @@ -= Remote MCP Servers for Redpanda Cloud -:description: Build MCP tools that connect AI agents to databases, queues, CRMs, and other business systems using Redpanda's proven connectors. -:page-layout: index diff --git a/modules/mcp/pages/remote/manage-servers.adoc b/modules/mcp/pages/remote/manage-servers.adoc deleted file mode 100644 index 1123f43..0000000 --- a/modules/mcp/pages/remote/manage-servers.adoc +++ /dev/null @@ -1,168 +0,0 @@ -= Manage Remote MCP Servers -:description: Learn how to edit, stop, start, and delete MCP servers in Redpanda Cloud. -// TODO: Add 'redpanda-cloud:ai-agents:mcp/remote/manage-servers.adoc' after ai-agents removed from cloud-docs -:page-aliases: redpanda-cloud:ai-agents:mcp/remote/admin-guide.adoc -:page-topic-type: how-to -:personas: platform_admin, agent_developer -// Reader journey: "I operate and maintain" -// Learning objectives - what readers can accomplish from this page: -:learning-objective-1: Edit MCP server configurations -:learning-objective-2: Stop and start MCP servers -:learning-objective-3: Delete MCP servers safely - -After creating an MCP server, you can manage its lifecycle, including editing configurations, pausing to save costs, and permanent deletion. - -After reading this page, you will be able to: - -* [ ] {learning-objective-1} -* [ ] {learning-objective-2} -* [ ] {learning-objective-3} - -== Prerequisites - -You must have an existing MCP server. If you do not have one, see xref:remote/quickstart.adoc[]. - -== Edit an MCP server - -You can update the configuration, resources, or metadata of an MCP server at any time. - -[tabs] -===== -Cloud Console:: -+ --- -. In the Redpanda Cloud Console, navigate to *Agentic AI* > *Remote MCP*. -. Find the MCP server you want to edit and click its name. -. Click *Edit configuration*. -. Make your changes. -. Click *Save* to apply changes. - -[NOTE] -==== -Editing a running MCP server may cause a brief interruption. Review changes before deploying to production. -==== --- - -Data Plane API:: -+ --- -. link:/api/doc/cloud-dataplane/topic/topic-quickstart[Authenticate and get the base URL] for the Data Plane API. -. Make a request to link:/api/doc/cloud-dataplane/operation/operation-mcpserverservice_getmcpserver[`GET /v1/redpanda-connect/mcp-servers/\{mcp_server_id}`] to retrieve the current configuration. -. Make a request to link:/api/doc/cloud-dataplane/operation/operation-mcpserverservice_updatemcpserver[`PATCH /v1/redpanda-connect/mcp-servers/\{mcp_server_id}`] to update the configuration: -+ -[,bash] ----- -curl -X PATCH "https:///v1/redpanda-connect/mcp-servers/?update_mask=display_name,description" \ - -H "Authorization: Bearer " \ - -H "Content-Type: application/json" \ - -d '{ - "mcp_server": { - "display_name": "updated-name", - "description": "Updated description" - } - }' ----- --- -===== - -== Stop an MCP server - -Stopping a server pauses all tool execution and releases compute resources, but preserves configuration and state. This is useful for temporarily disabling a server to save costs while retaining the ability to restart it later. - -[tabs] -===== -Cloud Console:: -+ --- -. In the Redpanda Cloud Console, navigate to *Agentic AI* > *Remote MCP*. -. Find the server you want to stop. -. Click the three dots and select *Stop*. -. Confirm the action. --- - -Data Plane API:: -+ --- -. link:/api/doc/cloud-dataplane/topic/topic-quickstart[Authenticate and get the base URL] for the Data Plane API. -. Make a request to link:/api/doc/cloud-dataplane/operation/operation-mcpserverservice_stopmcpserver[`POST /v1/redpanda-connect/mcp-servers/\{mcp_server_id}:stop`]: -+ -[,bash] ----- -curl -X POST "https:///v1/redpanda-connect/mcp-servers/:stop" \ - -H "Authorization: Bearer " ----- --- -===== - -While stopped, the server cannot respond to MCP requests. Start it to restore service. - -== Start a stopped MCP server - -Resume a stopped server to restore its functionality. - -[tabs] -===== -Cloud Console:: -+ --- -. In the Redpanda Cloud Console, navigate to *Agentic AI* > *Remote MCP*. -. Find the stopped server. -. Click the three dots and select *Start*. -. Wait for the status to show *Running* before reconnecting clients. --- - -Data Plane API:: -+ --- -. link:/api/doc/cloud-dataplane/topic/topic-quickstart[Authenticate and get the base URL] for the Data Plane API. -. Make a request to link:/api/doc/cloud-dataplane/operation/operation-mcpserverservice_startmcpserver[`POST /v1/redpanda-connect/mcp-servers/\{mcp_server_id}:start`]: -+ -[,bash] ----- -curl -X POST "https:///v1/redpanda-connect/mcp-servers/:start" \ - -H "Authorization: Bearer " ----- -+ -. Wait for the status to show *Running* before reconnecting clients. --- -===== - -== Delete an MCP server - -Deleting a server permanently removes it. You cannot undo this action. Redpanda removes all configuration, tools, and associated resources. - -[tabs] -===== -Cloud Console:: -+ --- -. In the Redpanda Cloud Console, navigate to *Agentic AI* > *Remote MCP*. -. Find the server you want to delete. -. Click the three dots and select *Delete*. -. Confirm the deletion when prompted. --- - -Data Plane API:: -+ --- -. link:/api/doc/cloud-dataplane/topic/topic-quickstart[Authenticate and get the base URL] for the Data Plane API. -. Make a request to link:/api/doc/cloud-dataplane/operation/operation-mcpserverservice_deletemcpserver[`DELETE /v1/redpanda-connect/mcp-servers/\{mcp_server_id}`]: -+ -[,bash] ----- -curl -X DELETE "https:///v1/redpanda-connect/mcp-servers/" \ - -H "Authorization: Bearer " ----- --- -===== - -[WARNING] -==== -Deletion is immediate and permanent. Make sure you have backed up any important configuration before deleting an MCP server. -==== - -== Next steps - -* xref:mcp:remote/scale.adoc[] -* xref:remote/monitor-mcp-servers.adoc[] -* xref:remote/best-practices.adoc[] diff --git a/modules/mcp/pages/remote/monitor-mcp-servers.adoc b/modules/mcp/pages/remote/monitor-mcp-servers.adoc deleted file mode 100644 index dc93333..0000000 --- a/modules/mcp/pages/remote/monitor-mcp-servers.adoc +++ /dev/null @@ -1,104 +0,0 @@ -= Monitor MCP Server Activity -:description: Consume traces, track tool invocations, measure performance, and debug failures in MCP servers. -:page-topic-type: how-to -:personas: platform_admin, agent_developer, data_engineer -:learning-objective-1: Consume traces from the redpanda.otel_traces topic -:learning-objective-2: Track tool invocations and measure performance -:learning-objective-3: Debug tool failures using trace data - -Monitor MCP server activity using OpenTelemetry traces emitted to the `redpanda.otel_traces` glossterm:topic[]. - -After reading this page, you will be able to: - -* [ ] {learning-objective-1} -* [ ] {learning-objective-2} -* [ ] {learning-objective-3} - -For conceptual background on traces, spans, and the trace data structure, see xref:observability:concepts.adoc[]. - -== Prerequisites - -You must have an existing MCP server. If you do not have one, see xref:remote/quickstart.adoc[]. - -== View transcripts in the Cloud Console - -:context: mcp -include::observability:partial$transcripts-ui-guide.adoc[] - -== Analyze traces programmatically - -MCP servers emit OpenTelemetry traces to the `redpanda.otel_traces` topic. Consume these traces to build custom monitoring, track tool usage, and analyze performance. - -=== Consume traces - -[tabs] -===== -Cloud Console:: -+ --- -. In the Redpanda Cloud Console, navigate to *Topics*. -. Select `redpanda.otel_traces`. -. Click *Messages* to view recent traces. -. Use filters to search for specific trace IDs, span names, or time ranges. --- - -rpk:: -+ --- -Consume the most recent traces: - -[,bash] ----- -rpk topic consume redpanda.otel_traces --offset end -n 10 ----- - -Filter for specific MCP server activity by examining the span attributes. --- - -Data Plane API:: -+ --- -Use the link:/api/doc/cloud-dataplane/[Data Plane API^] to programmatically consume traces and integrate with your monitoring pipeline. --- -===== - -=== Track tool invocations - -Monitor which tools are being called and how often by filtering spans where `instrumentationScope.name` is `rpcn-mcp`. The `name` field shows which tool was invoked. - -Example: Find all invocations of a specific tool: - -[,bash] ----- -rpk topic consume redpanda.otel_traces --offset start \ - | jq '.value | select(.instrumentationScope.name == "rpcn-mcp" and .name == "weather")' ----- - -=== Measure performance - -Calculate tool execution time using span timestamps: - -[,bash] ----- -Duration (ms) = (endTimeUnixNano - startTimeUnixNano) / 1000000 ----- - -Track percentiles (p50, p95, p99) to identify performance issues and set alerts for durations exceeding acceptable thresholds. - -=== Debug failures - -Filter for error spans where `status.code` is `2`: - -[,bash] ----- -rpk topic consume redpanda.otel_traces --offset start \ - | jq '.value | select(.status.code == 2)' ----- - -Check `status.message` for error details and the `events` array for error events with timestamps. Use `traceId` to correlate related spans across the distributed system. - -== Next steps - -* xref:observability:concepts.adoc[] -* xref:remote/troubleshooting.adoc[] -* xref:remote/manage-servers.adoc[] diff --git a/modules/mcp/pages/remote/oauth-user-delegated.adoc b/modules/mcp/pages/remote/oauth-user-delegated.adoc deleted file mode 100644 index d571a56..0000000 --- a/modules/mcp/pages/remote/oauth-user-delegated.adoc +++ /dev/null @@ -1,4 +0,0 @@ -= User-Delegated OAuth -:description: Configure OAuth for user-delegated authentication in MCP servers. - -// TODO: Add content diff --git a/modules/mcp/pages/remote/overview.adoc b/modules/mcp/pages/remote/overview.adoc deleted file mode 100644 index fff0297..0000000 --- a/modules/mcp/pages/remote/overview.adoc +++ /dev/null @@ -1,73 +0,0 @@ -= Remote MCP Server Overview -:page-aliases: redpanda-cloud:ai-agents:mcp/remote/overview.adoc -:description: Build and host MCP tools that connect AI agents to your business systems without writing glue code, using Redpanda's proven connectors. -:page-topic-type: overview -:personas: evaluator, agent_developer -// Reader journey: "I'm evaluating this" -// Learning objectives - what readers should understand after reading this page: -:learning-objective-1: Explain what a Remote MCP server is and how tools differ from pipelines -:learning-objective-2: Identify use cases where Remote MCP provides business value -:learning-objective-3: Describe how MCP tools expose Redpanda Connect components to AI - -Remote MCP lets you give AI agents access to your databases, queues, CRMs, and other systems of record without writing custom integration code. This page introduces Remote MCP servers and helps you decide if they're right for your use case. - -After reading this page, you will be able to: - -* [ ] {learning-objective-1} -* [ ] {learning-objective-2} -* [ ] {learning-objective-3} - -== What is MCP? - -// What is MCP - single-sourced from rp-connect-docs partial -include::redpanda-connect:ai-agents:partial$mcp/overview/what-is-mcp.adoc[] - -== What is Remote MCP? - -Remote MCP lets you build and host MCP servers in your Redpanda Cloud clusters. Your tools run next to your data, managed by Redpanda, so you get: - -* *Always-on availability:* No local process to run. Your tools are hosted and managed by Redpanda Cloud. -* *Proximity to data:* Tools execute next to your cluster for lower latency and simpler networking. -* *Secure secrets management:* Use the xref:redpanda-cloud:develop:connect/configuration/secret-management.adoc[Secrets Store] instead of hardcoding credentials. -* *Fast iteration:* Define tools as YAML, deploy, and your AI agents can use them immediately. - -// MCP tools vs pipelines - single-sourced from rp-connect-docs partial -include::redpanda-connect:ai-agents:partial$mcp/overview/mcp-vs-pipelines.adoc[] - -// Use cases table - single-sourced from rp-connect-docs partial -include::redpanda-connect:ai-agents:partial$mcp/overview/use-cases-table.adoc[] - -== How it works - -Remote MCP servers sit between AI clients and your data: - -. Your AI agent connects to your MCP server using `rpk cloud mcp proxy` or direct authentication. -. A user asks their AI agent something like "What's the weather in London?" -. The server finds the matching tool and runs your Redpanda Connect configuration. -. Your configuration fetches data, transforms it, and returns a structured response. -. The AI agent gets the data and can use it to answer the user. - -=== What a tool looks like - -A tool is a YAML configuration with two parts: the logic (what the tool does) and the metadata (how AI understands it). - -Here's a minimal example that returns weather data: - -[source,yaml] ----- -include::ROOT:example$mcp-tools/processors/get_weather_simple.yaml[tag=complete,indent=0] ----- - -When an AI client asks about weather, it calls this tool with the city name. The tool fetches data from the weather API and returns it. - -// MCP specification support - single-sourced from rp-connect-docs partial -include::redpanda-connect:ai-agents:partial$mcp/overview/specification-support.adoc[] - -== Next steps - -* xref:remote/quickstart.adoc[] -* xref:agents:overview.adoc[] -* xref:remote/concepts.adoc[] -* xref:remote/create-tool.adoc[] -* link:https://modelcontextprotocol.io/[Model Context Protocol documentation^] - diff --git a/modules/mcp/pages/remote/patterns.adoc b/modules/mcp/pages/remote/patterns.adoc deleted file mode 100644 index e4b9712..0000000 --- a/modules/mcp/pages/remote/patterns.adoc +++ /dev/null @@ -1,260 +0,0 @@ -= MCP Tool Patterns -// TODO: Add 'redpanda-cloud:ai-agents:mcp/remote/tool-patterns.adoc' after ai-agents removed from cloud-docs -:page-aliases: redpanda-cloud:ai-agents:mcp/remote/pipeline-patterns.adoc -:description: Catalog of patterns for MCP server tools in Redpanda Cloud. -:page-byoc: true -:page-topic-type: cookbook -:personas: agent_developer, data_engineer -// Reader journey: "I need an example for X" -:learning-objective-1: Find reusable patterns for common MCP tool scenarios -:learning-objective-2: Apply validation and error handling patterns for production robustness -:learning-objective-3: Format responses consistently for AI client consumption - -When building tools, use these patterns as starting points for common scenarios. For step-by-step instructions, see xref:remote/create-tool.adoc[]. For design guidelines, see xref:remote/best-practices.adoc[]. - -After reading this page, you will be able to: - -* [ ] {learning-objective-1} -* [ ] {learning-objective-2} -* [ ] {learning-objective-3} - -[[read-data]] -== Read data - -Use xref:redpanda-cloud:develop:connect/components/inputs/about.adoc[inputs] to create tools that read from data sources or generate sample data. - -[[data-generators]] -=== Generate test data - -*When to use:* Development and testing environments where you need synthetic data, load testing scenarios, or demonstrating data flows without real data sources. - -*Example use cases:* Mock user events, test order data, synthetic sensor readings, demo data for presentations. - -[source,yaml] ----- -include::ROOT:example$mcp-tools/inputs/generate_input.yaml[] ----- - -See also: xref:redpanda-cloud:develop:connect/components/inputs/generate.adoc[`generate` input component] - -[[consume-from-redpanda]] -=== Consume from Redpanda topics - -*When to use:* Processing events from Redpanda topics, building event-driven AI agents, consuming audit logs, or subscribing to data change streams. - -*Example use cases:* Monitor order events, process user activity streams, consume IoT sensor data, react to system notifications. - -[source,yaml] ----- -include::ROOT:example$mcp-tools/inputs/consume_redpanda.yaml[tag=component,indent=0] ----- - -See also: xref:redpanda-cloud:develop:connect/components/inputs/redpanda.adoc[`redpanda` input] - -[[stream-processing]] -=== Process streaming data - -*When to use:* Real-time analytics, windowed aggregations, computing metrics over time, or building streaming dashboards. - -*Example use cases:* Calculate rolling averages, count events per time window, detect anomalies in streams, aggregate metrics. - -[source,yaml] ----- -include::ROOT:example$mcp-tools/inputs/stream_processing.yaml[tag=component,indent=0] ----- - -See also: xref:redpanda-cloud:develop:connect/components/inputs/redpanda.adoc[`redpanda` input] - -[[call-external-services]] -== Call external services - -Use xref:redpanda-cloud:develop:connect/components/processors/about.adoc[processors] to fetch data from external APIs, databases, or AI services. - -[[external-api-calls]] -=== Call REST APIs - -*When to use:* Integrating with third-party services, fetching real-time data, calling internal microservices, or enriching event data with external information. - -*Example use cases:* Fetch user profile from CRM, get product pricing from inventory API, validate addresses with geocoding service, retrieve weather data. - -[source,yaml] ----- -include::ROOT:example$mcp-tools/processors/http_processor.yaml[] ----- - -See also: xref:redpanda-cloud:develop:connect/components/processors/http.adoc[`http` processor], xref:redpanda-cloud:develop:connect/components/processors/mutation.adoc[`mutation` processor] - -[[database-queries]] -=== Query databases - -*When to use:* Retrieving customer records, querying analytics data, looking up configuration values, or joining streaming data with dimensional data from data warehouses. - -*Example use cases:* Fetch customer details from PostgreSQL, query sales data from BigQuery, retrieve product catalog from MongoDB, look up reference data. - -[source,yaml] ----- -include::ROOT:example$mcp-tools/processors/gcp_bigquery_select_processor.yaml[] ----- - -See also: xref:redpanda-cloud:develop:connect/components/processors/gcp_bigquery_select.adoc[`gcp_bigquery_select` processor], xref:redpanda-cloud:develop:connect/components/processors/sql_select.adoc[`sql_select` processor] - -[[jira-queries]] -=== Query Jira issues - -*When to use:* Fetching tickets by status, checking assignments, finding recent issues, or building AI agents that interact with project management data. - -*Example use cases:* Get open bugs for a sprint, find issues assigned to a user, list recently updated tickets, search by custom fields. - -NOTE: The `jira` processor is available on Dedicated and BYOC clusters. - -[source,yaml] ----- -include::ROOT:example$mcp-tools/processors/search_jira.yaml[tag=complete,indent=0] ----- - -For more patterns including pagination, custom fields, and creating issues via the HTTP processor, see xref:redpanda-cloud:develop:connect/cookbooks/jira.adoc[]. - -[[ai-llm-integration]] -=== Integrate with AI/LLM services - -*When to use:* Generating embeddings for semantic search, calling LLM APIs for text generation, building RAG pipelines, or analyzing sentiment. - -*Example use cases:* Generate embeddings for documents, classify customer feedback, summarize long text, extract entities, answer questions with context. - -==== OpenAI chat completion - -[source,yaml] ----- -include::ROOT:example$mcp-tools/processors/openai_chat.yaml[tag=component,indent=0] ----- - -See also: xref:redpanda-cloud:develop:connect/components/processors/openai_chat_completion.adoc[`openai_chat_completion`], xref:redpanda-cloud:develop:connect/components/processors/openai_embeddings.adoc[`openai_embeddings`] - -==== Generate embeddings - -[source,yaml] ----- -include::ROOT:example$mcp-tools/processors/openai_embeddings.yaml[tag=component,indent=0] ----- - -See also: xref:redpanda-cloud:develop:connect/components/processors/cohere_embeddings.adoc[`cohere_embeddings`], xref:redpanda-cloud:develop:connect/components/processors/gcp_vertex_ai_embeddings.adoc[`gcp_vertex_ai_embeddings`] - -[[write-data]] -== Write data - -Use xref:redpanda-cloud:develop:connect/components/outputs/about.adoc[outputs] to write data to Redpanda topics or cache stores. - -[[publish-to-redpanda]] -=== Publish to Redpanda topics - -*When to use:* Publishing events to Redpanda for consumption by other services, creating event sourcing patterns, building audit trails, or triggering downstream workflows. - -*Example use cases:* Publish order confirmations, emit audit events, trigger notifications, create event-driven workflows. - -[source,yaml] ----- -include::ROOT:example$mcp-tools/outputs/redpanda_output.yaml[] ----- - -See also: xref:redpanda-cloud:develop:connect/components/outputs/redpanda.adoc[`redpanda` output] - -==== Outputs with processors - -Output tools can include processors to transform data before publishing. This pattern is useful when you need to process data and save the result to a destination in a single tool. - -*When to use:* Processing user input with an LLM and saving the response, transforming data before publishing to a topic, enriching events before writing to external systems. - -[source,yaml] ----- -include::ROOT:example$mcp-tools/outputs/redpanda_output_with_processors.yaml[] ----- - -[[caching]] -=== Cache data - -*When to use:* Reducing repeated API calls, storing lookup tables, caching database query results, or maintaining session state across tool invocations. - -*Example use cases:* Cache user profiles, store API rate limit counters, maintain configuration values, cache product catalogs. - -.Redpanda-backed cache -[source,yaml] ----- -include::ROOT:example$mcp-tools/caches/redpanda_cache.yaml[] ----- - -.In-memory cache -[source,yaml] ----- -include::ROOT:example$mcp-tools/caches/memory_cache.yaml[] ----- - -See also: xref:redpanda-cloud:develop:connect/components/caches/memory.adoc[`memory` cache], xref:redpanda-cloud:develop:connect/components/outputs/redpanda.adoc[`redpanda` output] - -[[transform-data]] -== Transform data - -Use Bloblang and processors to transform, validate, and route data. - -[[data-transformation]] -=== Transform and validate - -*When to use:* Converting data formats, validating schemas, filtering events, enriching messages with computed fields, or normalizing data structures. - -*Example use cases:* Parse JSON payloads, validate required fields, add timestamps, convert units, mask sensitive data, aggregate nested objects. - -[source,yaml] ----- -include::ROOT:example$mcp-tools/processors/transform_validate.yaml[tag=mapping,indent=0] ----- - -See also: xref:redpanda-cloud:develop:connect/components/processors/mapping.adoc[`mapping` processor], xref:redpanda-cloud:develop:connect/guides/bloblang/about.adoc[Bloblang guide] - -[[event-driven-workflows]] -=== Build event-driven workflows - -*When to use:* Orchestrating multi-step processes, responding to business events, implementing saga patterns, or coordinating microservices. - -*Example use cases:* Order fulfillment workflows, approval processes, notification cascades, data pipeline orchestration. - -[source,yaml] ----- -include::ROOT:example$mcp-tools/inputs/event_driven_workflow.yaml[tag=component,indent=0] ----- - -See also: xref:redpanda-cloud:develop:connect/components/inputs/redpanda.adoc[`redpanda` input] - -[[production-readiness]] -== Production readiness - -Build production-ready tools with proper input validation, error handling, and response formatting. - -[[input-validation]] -=== Validate input - -AI clients may send unexpected or malformed input. Validate early to return helpful error messages instead of cryptic failures from downstream components. - -include::redpanda-connect:ai-agents:partial$mcp/tool-patterns/input-validation.adoc[leveloffset=+1] - -[[error-handling]] -=== Handle errors - -External services fail. Databases go down. APIs return unexpected responses. Wrap risky operations in error handling so your tool returns useful error messages instead of crashing. - -include::redpanda-connect:ai-agents:partial$mcp/tool-patterns/error-handling.adoc[leveloffset=+1] - -[[response-formatting]] -=== Format responses - -AI clients work best with clean, predictable response structures. Transform raw component output into consistent formats. - -include::redpanda-connect:ai-agents:partial$mcp/tool-patterns/response-formatting.adoc[leveloffset=+1] - -// Production workflows section - single-sourced from rp-connect-docs -include::redpanda-connect:ai-agents:partial$mcp/tool-patterns/production-workflows.adoc[] - -== Next steps - -* xref:agents:integration-overview.adoc[] -* xref:remote/create-tool.adoc[] -* xref:remote/best-practices.adoc[] -* xref:remote/troubleshooting.adoc[] \ No newline at end of file diff --git a/modules/mcp/pages/remote/quickstart.adoc b/modules/mcp/pages/remote/quickstart.adoc deleted file mode 100644 index f0ac917..0000000 --- a/modules/mcp/pages/remote/quickstart.adoc +++ /dev/null @@ -1,394 +0,0 @@ -= Remote MCP Server Quickstart -:page-aliases: redpanda-cloud:ai-agents:mcp/remote/quickstart.adoc -:description: Build and deploy your first MCP tools to connect AI agents to your Redpanda data without writing custom integration code. -:page-topic-type: tutorial -:personas: agent_developer, streaming_developer, evaluator -// Reader journey: "I want to try it now" -// Learning objectives - what readers will achieve by completing this quickstart: -:learning-objective-1: Create an MCP server in Redpanda Cloud -:learning-objective-2: Define tools that generate and publish data -:learning-objective-3: Connect Claude Code to your MCP server and invoke tools - -This quickstart builds an MCP server in Redpanda Cloud that exposes tools for generating and publishing event data. You'll create two tools, then ask Claude Code to use them through natural language: - -> Generate 10 user events and publish them to the events topic. - -By completing this quickstart, you will be able to: - -* [ ] {learning-objective-1} -* [ ] {learning-objective-2} -* [ ] {learning-objective-3} - -TIP: For background on how MCP tools work and when to use each component type, see xref:remote/concepts.adoc[]. - -== Prerequisites - -* A Redpanda Cloud cluster with *Remote MCP* enabled. -* Access to the xref:redpanda-cloud:develop:connect/configuration/secret-management.adoc[Secrets Store] for storing credentials. -* At least version 25.2.5 of the xref:redpanda-cloud:manage:rpk/rpk-install.adoc[Redpanda CLI (`rpk`)] installed on your computer. -* link:https://docs.anthropic.com/en/docs/claude-code/setup[Claude Code] installed. - -== Prepare your cluster - -Before creating the MCP server, you need to set up a topic for event publishing. - -[tabs] -====== -rpk:: -+ --- -. Log in to your Redpanda Cloud account: -+ -[,bash] ----- -rpk cloud login ----- -+ -This opens a browser window to authenticate. The token is saved locally inside your `rpk` configuration file. It is valid for 4 hours. You can refresh it by running `rpk cloud login` again. - -. Create a topic called `events` for storing user event data: -+ -[,bash] ----- -rpk topic create events --partitions 3 --replicas 3 ----- - -. Create a user called `mcp` with a strong password: -+ -[,bash] ----- -rpk acl user create mcp --password ----- -+ -Save the password securely. You need it later when configuring the MCP server. - -. Grant the `mcp` user permissions to produce and consume from the `events` topic: -+ -[,bash] ----- -rpk acl create --allow-principal User:mcp --operation all --topic events ----- --- - -Data Plane API:: -+ --- -. link:/api/doc/cloud-controlplane/authentication#topic-request-an-access-token[Authenticate to the Control Plane API] to get an access token. -+ -[NOTE] -==== -Access tokens expire after 1 hour. To refresh, make the same authentication request again with your service account credentials. The same token works for both Control Plane and Data Plane API requests. -==== - -. Get the Data Plane API URL for your cluster: -+ -[tabs] -==== -BYOC or Dedicated:: -+ -Make a request to the link:/api/doc/cloud-controlplane/operation/operation-clusterservice_getcluster[`GET /v1/clusters/\{id}`] endpoint: -+ -[,bash,role="no-placeholders"] ----- -curl "https://api.redpanda.com/v1/clusters/" \ - -H "Authorization: Bearer " ----- - -Serverless:: -+ -Make a request to the link:/api/doc/cloud-controlplane/operation/operation-serverlessclusterservice_getserverlesscluster[`GET /v1/serverless/clusters/\{id}`] endpoint: -+ -[,bash] ----- -curl "https://api.redpanda.com/v1/serverless/clusters/" \ - -H "Authorization: Bearer " ----- -==== -+ -The response includes a `dataplane_api.url` value: -+ -[.no-copy] ----- - "id": "....", - "name": "my-cluster", -.... - "dataplane_api": { - "url": "https://api-xyz.abc.fmc.ppd.cloud.redpanda.com" - }, -... ----- -+ -[NOTE] -==== -The `dataplane_api.url` field might not be immediately available when a cluster reaches STATE_READY. If the field is missing or null, wait a few minutes and make the request again. The Data Plane API URL is typically available within 5-10 minutes after cluster creation completes. -==== - -. Make a request to link:/api/doc/cloud-dataplane/operation/operation-topicservice_createtopic[`POST /v1/topics`] to create the topic: -+ -[,bash] ----- -curl -X POST "https:///v1/topics" \ - -H "Authorization: Bearer " \ - -H "Content-Type: application/json" \ - -d '{ - "name": "events", - "partition_count": 3, - "replication_factor": 3 - }' ----- - -. Make a request to link:/api/doc/cloud-dataplane/operation/operation-userservice_createuser[`POST /v1/users`] to create a user called `mcp`: -+ -[,bash] ----- -curl -X POST "https:///v1/users" \ - -H "Authorization: Bearer " \ - -H "Content-Type: application/json" \ - -d '{ - "name": "mcp", - "password": "", - "mechanism": "SASL_MECHANISM_SCRAM_SHA_256" - }' ----- -+ -Save the password securely. You need it later when configuring the MCP server. - -. Make a request to link:/api/doc/cloud-dataplane/operation/operation-aclservice_createacl[`POST /v1/acls`] to grant the `mcp` user permissions to produce and consume from the `events` topic: -+ -[,bash] ----- -curl -X POST "https:///v1/acls" \ - -H "Authorization: Bearer " \ - -H "Content-Type: application/json" \ - -d '{ - "resource_type": "RESOURCE_TYPE_TOPIC", - "resource_name": "events", - "resource_pattern_type": "RESOURCE_PATTERN_TYPE_LITERAL", - "principal": "User:mcp", - "host": "*", - "operation": "OPERATION_ALL", - "permission_type": "PERMISSION_TYPE_ALLOW" - }' ----- --- -====== - -== Create an MCP Server in Redpanda Cloud - -[tabs] -===== -Cloud Console:: -+ --- -. Log in to the link:https://cloud.redpanda.com/[Redpanda Cloud Console^]. - -. Navigate to *Agentic AI* > *Remote MCP*. -+ -This page shows a list of existing servers. - -. Click *Create new MCP Server*. In *Server Metadata*, configure the basic information and resources: -+ -* *Display Name*: A human-friendly name such as `event-data-generator`. This name is shown in the Redpanda Cloud Console. It is not the name of the MCP server itself. -* *Description*: Explain what the server does. For example, `Generates fake user event data and publishes it to Redpanda topics`. -* *Tags*: Add key/value tags such as `owner=platform` or `env=demo`. The tag names `service_account_id` and `secret_id` are reserved and cannot be used. -* *Resources*: Choose a size (XSmall / Small / Medium / Large / XLarge). Larger sizes allow more concurrent requests and faster processing, but cost more. You can change this later. -* *Service Account*: A service account is automatically created for authenticating the MCP server to your cluster. The name is pre-filled but you can customize it. For details about default permissions and how to manage service accounts, see xref:remote/concepts.adoc#service-account-authorization[Service account authorization]. - -. Click *Next* to define tools. -+ -Tools define the actions your MCP server can perform. In this example, you create two tools: one for generating user event data and another for publishing that data to Redpanda. - -. From the *Template* dropdown, select *Generate Input*. -+ -The template populates the configuration with YAML for the tool definition. - -. Click *Add Tool* to create a second tool. - -. From the *Template* dropdown, select *Redpanda Output*. -+ -The template populates the configuration for publishing to Redpanda and a section for adding the required secrets is displayed. - -. Enter the values for the `mcp` user's credentials in the *Add Required Secrets* section. - -. Click *Lint* to check the configuration. You should see no errors. - -. Click *Create MCP Server* to deploy the server. -+ -It may take a few seconds to start. The status changes from *Starting* to *Running* when it's ready. - -. Open the *MCP Inspector* tab to test the tools: -+ -* For the `generate_input` tool, click *Run Tool* to generate sample event data. -* For the `redpanda_output` tool, enter some sample event data such as `user_id=user123`, `event_type=login`, and `timestamp=2025-10-21T10:30:00Z` then click *Run Tool* to publish it to the `events` topic. --- - -Data Plane API:: -+ --- -. Create a secret for the username: -+ -[,bash] ----- -curl -X POST "https:///v1/secrets" \ - -H "Authorization: Bearer " \ - -H "Content-Type: application/json" \ - -d '{ - "id": "MCP_USERNAME", - "scopes": ["SCOPE_MCP_SERVER"], - "secret_data": "bWNw" - }' ----- -+ -The `secret_data` value `bWNw` is the base64-encoded string `mcp`. -+ -Create a secret for the password: -+ -[,bash] ----- -curl -X POST "https:///v1/secrets" \ - -H "Authorization: Bearer " \ - -H "Content-Type: application/json" \ - -d '{ - "id": "MCP_PASSWORD", - "scopes": ["SCOPE_MCP_SERVER"], - "secret_data": "" - }' ----- -+ -Replace `` with your password encoded in base64. You can encode it with: `echo -n '' | base64`. - -. Using the Data Plane API URL from the previous section, make a request to link:/api/doc/cloud-dataplane/operation/operation-mcpserverservice_createmcpserver[`POST /v1/redpanda-connect/mcp-servers`] to create the MCP server: -+ -[,bash] ----- -curl -X POST "https:///v1/redpanda-connect/mcp-servers" \ - -H "Authorization: Bearer " \ - -H "Content-Type: application/json" \ - -d '{ - "display_name": "event-data-generator", - "description": "Generates fake user event data and publishes it to Redpanda topics", - "tags": { - "owner": "platform", - "env": "demo" - }, - "resources": { - "memory_shares": "400M", - "cpu_shares": "100m" - }, - "tools": { - "generate_input": { - "component_type": "COMPONENT_TYPE_INPUT", - "config_yaml": "generate:\n interval: 1s\n mapping: |\n root.user_id = \"user\" + random_int(min: 1, max: 1000).string()\n root.event_type = [\"login\", \"logout\", \"purchase\", \"view\"].index(random_int(max: 3))\n root.timestamp = now().ts_format(\"2006-01-02T15:04:05Z07:00\")" - }, - "redpanda_output": { - "component_type": "COMPONENT_TYPE_OUTPUT", - "config_yaml": "redpanda:\n seed_brokers: [ \"${REDPANDA_BROKERS}\" ]\n topic: events\n tls:\n enabled: true\n sasl:\n - mechanism: SCRAM-SHA-256\n username: \"${secrets.MCP_USERNAME}\"\n password: \"${secrets.MCP_PASSWORD}\"\n" - } - } - }' ----- -+ -The response includes the MCP server ID. Wait for the status to show *Running* before testing the tools. - -. To test the tools, use the link:/api/doc/cloud-dataplane/operation/operation-mcpserverservice_getmcpserver[`GET /v1/redpanda-connect/mcp-servers/\{mcp_server_id}`] endpoint to verify the server is running. --- -===== - -== Connect an AI client - -Now that your MCP server is running with two tools available, you'll connect Claude Code so it can discover and use them. You can connect any MCP-compatible AI client to your MCP server. - -When you connect Claude Code: - -. Claude automatically discovers your `generate_input` and `redpanda_output` tools. -. You can ask Claude in natural language to perform tasks using these tools. -. Claude decides which tools to call and in what order based on your request. -. The Redpanda CLI acts as a secure proxy, forwarding Claude's tool requests to your MCP server in the cloud. - -This example uses Claude Code, but the same pattern works with any MCP-compatible client. - -. Log in to your Redpanda Cloud account: -+ -[,bash] ----- -rpk cloud login ----- -+ -This opens a browser window to authenticate. The token is saved locally inside your `rpk` configuration file. It is valid for 4 hours. You can refresh it by running `rpk cloud login` again. - -. Open the *Connection* tab in Redpanda Cloud to get connection details and run the `rpk` command for Claude Code. -+ -For BYOC and Dedicated clusters, use: -+ -[,bash] ----- -rpk cloud mcp proxy \ ---cluster-id \ ---mcp-server-id \ ---install --client claude-code ----- -+ -For Serverless clusters, use: -+ -[,bash] ----- -rpk cloud mcp proxy \ ---serverless-cluster-id \ ---mcp-server-id \ ---install --client claude-code ----- - -. Restart Claude Code and invoke your tool. -+ -[,bash] ----- -claude ----- - -. Ask Claude Code to use your tools. Try these example requests: -+ -* "Generate 10 user events and then publish them to the events topic." -* "Create sample login events for users user001, user002, and user003, then publish them to Redpanda." -* "Generate purchase events with metadata and publish them to the events topic." -+ -Watch what happens: -+ --- -* Claude analyzes your natural language request -* Claude identifies which tools to use (`generate_input` to create data, `redpanda_output` to publish) -* Claude calls your tools via the MCP server running in Redpanda Cloud -* You see the tool execution results in your Claude Code session --- -+ -You may need to respond to prompts to grant Claude permission to call the tools. - -. Verify the events were published by consuming from the `events` topic: -+ -[,bash] ----- -rpk topic consume events --num 10 ----- -+ -You should see the generated event data in JSON format, confirming that Claude successfully used your custom tools to generate data and publish it to Redpanda. - -== Troubleshoot - -If you encounter issues during this quickstart: - -- **MCP server not starting**: Check the *Logs* tab and verify your YAML syntax by clicking *Lint*. -- **Connection issues**: Verify you're logged in with `rpk cloud login` and that your server status shows *Running*. -- **Publishing failures**: Verify the `events` topic exists with `rpk topic list`. - -For detailed solutions, see xref:remote/troubleshooting.adoc[]. - -== Next steps - -You've deployed an MCP server and connected Claude Code to your Redpanda cluster. Here's where to go next: - -* xref:agents:quickstart.adoc[] -* xref:remote/concepts.adoc[] -* xref:remote/create-tool.adoc[] -* xref:remote/best-practices.adoc[] -* xref:mcp:remote/patterns.adoc[] -* xref:remote/troubleshooting.adoc[] -* xref:mcp:remote/manage-servers.adoc[] diff --git a/modules/mcp/pages/remote/register-external.adoc b/modules/mcp/pages/remote/register-external.adoc deleted file mode 100644 index 29164ac..0000000 --- a/modules/mcp/pages/remote/register-external.adoc +++ /dev/null @@ -1,4 +0,0 @@ -= Register a Self-Hosted Server -:description: Connect your self-hosted MCP server to Redpanda ADP. - -// TODO: Add content diff --git a/modules/mcp/pages/remote/scale.adoc b/modules/mcp/pages/remote/scale.adoc deleted file mode 100644 index 606c3c1..0000000 --- a/modules/mcp/pages/remote/scale.adoc +++ /dev/null @@ -1,76 +0,0 @@ -= Scale Remote MCP Server Resources -:description: Learn how to scale MCP server resources up or down to match workload demands and optimize costs. -:page-byoc: true -:page-topic-type: how-to -:personas: platform_admin -// Reader journey: "I optimize costs and performance" -// Learning objectives - what readers can accomplish from this page: -:learning-objective-1: Scale MCP server resources up or down -:learning-objective-2: Choose appropriate resource sizes for workloads -:learning-objective-3: Optimize costs through resource management - -After creating an MCP server, you can scale its resources up or down to match your workload needs. Resource allocation affects your xref:redpanda-cloud:billing:billing.adoc#remote-mcp-billing-metrics[billing costs], which are charged per compute unit hour. - -After reading this page, you will be able to: - -* [ ] {learning-objective-1} -* [ ] {learning-objective-2} -* [ ] {learning-objective-3} - -== Prerequisites - -You must have an existing MCP server. If you do not have one, see xref:remote/quickstart.adoc[]. - -== Scale resources - -[tabs] -===== -Cloud Console:: -+ --- -. In the Redpanda Cloud Console, navigate to *Agentic AI* > *Remote MCP*. -. Find the MCP server you want to scale and click its name. -. Click *Edit configuration*. -. Under *Resources*, select a new size: -+ -* *XSmall*: Lowest cost, suitable for development or light workloads -* *Small*: Light production workloads -* *Medium*: Standard production workloads -* *Large*: High-throughput workloads -* *XLarge*: Highest performance for demanding workloads - -. Click *Save* to apply the new resource allocation. -+ -Redpanda makes the specified resources available immediately. --- - -Data Plane API:: -+ --- -. link:/api/doc/cloud-dataplane/topic/topic-quickstart[Authenticate and get the base URL] for the Data Plane API. -. Make a request to link:/api/doc/cloud-dataplane/operation/operation-mcpserverservice_getmcpserver[`GET /v1/redpanda-connect/mcp-servers/\{mcp_server_id}`] to retrieve the current configuration. -. Make a request to link:/api/doc/cloud-dataplane/operation/operation-mcpserverservice_updatemcpserver[`PATCH /v1/redpanda-connect/mcp-servers/\{mcp_server_id}`] to update the resources: -+ -[,bash] ----- -curl -X PATCH "https:///v1/redpanda-connect/mcp-servers/?update_mask=resources" \ - -H "Authorization: Bearer " \ - -H "Content-Type: application/json" \ - -d '{ - "mcp_server": { - "resources": { - "memory_shares": "2Gi", - "cpu_shares": "1000m" - } - } - }' ----- -+ -Redpanda makes the updated resources available immediately. --- -===== - -[TIP] -==== -Monitor your MCP server's performance and adjust resources as needed. You can scale up during peak usage periods and scale down during quieter times to optimize costs. For compute unit definitions and pricing, see xref:redpanda-cloud:billing:billing.adoc#remote-mcp-billing-metrics[MCP billing metrics]. -==== diff --git a/modules/mcp/pages/remote/troubleshooting.adoc b/modules/mcp/pages/remote/troubleshooting.adoc deleted file mode 100644 index f177c93..0000000 --- a/modules/mcp/pages/remote/troubleshooting.adoc +++ /dev/null @@ -1,46 +0,0 @@ -= Troubleshoot Remote MCP Servers -:description: Diagnose and fix common issues when building and running Remote MCP servers in Redpanda Cloud. -:page-topic-type: troubleshooting -:personas: agent_developer, streaming_developer, platform_admin -// Reader journey: "Something went wrong" -// Learning objectives - what readers can do with this page: -:learning-objective-1: Diagnose and fix lint and YAML configuration errors -:learning-objective-2: Resolve runtime issues when tools don't appear or return unexpected results -:learning-objective-3: Debug client connection problems - -This page helps you diagnose and fix common issues when building and running Remote MCP servers. - -Use this page to: - -* [ ] {learning-objective-1} -* [ ] {learning-objective-2} -* [ ] {learning-objective-3} - -== Lint errors - -include::redpanda-connect:ai-agents:partial$mcp/troubleshooting/troubleshooting-lint.adoc[] - -== Runtime issues - -include::redpanda-connect:ai-agents:partial$mcp/troubleshooting/troubleshooting-runtime.adoc[] - -== Connection issues - -include::redpanda-connect:ai-agents:partial$mcp/troubleshooting/troubleshooting-connection.adoc[] - -[[debugging]] -== Debugging techniques - -Use these techniques to systematically isolate and fix issues with your MCP tools. - -include::redpanda-connect:ai-agents:partial$mcp/troubleshooting/debugging-techniques.adoc[] - -== Next steps - -If you're still experiencing issues: - -* xref:remote/create-tool.adoc[] -* xref:remote/best-practices.adoc[] -* xref:remote/concepts.adoc[] - -For protocol-level troubleshooting, see the link:https://modelcontextprotocol.io/[MCP documentation^]. diff --git a/modules/mcp/pages/test-tools.adoc b/modules/mcp/pages/test-tools.adoc new file mode 100644 index 0000000..fb33665 --- /dev/null +++ b/modules/mcp/pages/test-tools.adoc @@ -0,0 +1,110 @@ += Test an MCP Server's Tools with the Inspector +:description: Use the Inspector tab to call tools, inspect resources and prompts, and verify your MCP server works — without standing up an agent. +:page-topic-type: how-to +:personas: app_developer +:learning-objective-1: Run an MCP tool from the Inspector and read its response +:learning-objective-2: Inspect resources, prompts, and call history +:learning-objective-3: Diagnose common errors (auth missing, scope upgrade required, transport mismatch) before pointing an agent at the server + +include::ROOT:partial$adp-la.adoc[] + +Test your MCP server's glossterm:tool[,tools], glossterm:resource[,resources], and glossterm:prompt[,prompts] using the Inspector — a built-in MCP client in the ADP UI. It runs on the same JSON-RPC connection that agents use, so if a tool works in the Inspector, it will work for an agent. Use this after creating your server (xref:create-server.adoc[Create an MCP Server]) or whenever you change a tool's schema. + +After completing this guide, you will be able to: + +* [ ] {learning-objective-1} +* [ ] {learning-objective-2} +* [ ] {learning-objective-3} + +== When to use the Inspector + +* After creating or registering a server, to confirm tool discovery completed and tools run correctly. +* While iterating on a self-managed server, to test schema changes against a live connection. +* When debugging an agent failure, to isolate whether the issue is in the agent or in the MCP server itself. + +== Open the Inspector + +. Open *MCP Servers* and click into your server. +. Switch to the *Inspector* tab. ++ +// TODO: screenshot of the Inspector tab with all four panels visible. + +The Inspector has four panels: *Tools*, *Resources*, *Prompts*, and *Session*. + +== Tools panel + +The Tools panel lists every tool the server returned from `tools/list`. + +. Select a tool from the list. The right-hand pane renders a form from the tool's input JSON schema. +. Fill in the form fields. +. Click *Run*. The response appears below the form. + +// TODO: screenshot of a successful Tools-panel call (use a SQL `query` against a sample table on `adp-production`). + +If the tool returns an error, the response pane shows the structured error detail. See <> for what each common error means. + +=== Code-mode tools + +If the server has *Code mode* enabled, the Tools panel also lists `{name}_search` and `{name}_execute` alongside the server's regular tools. These are the helpers an agent uses to discover and orchestrate tools through generated Python or JavaScript. Test them like any other tool. + +// TODO: screenshot of the code-mode helper tools in the Tools panel and a sample `_execute` call. + +== Resources panel + +The Resources panel lists any resources the server exposes through `resources/list`. Many MCP servers don't expose resources at all — if the panel is empty, that's fine. + +If your server does expose resources: + +. Click a resource to load its content into the right-hand pane. +. The Inspector renders text, JSON, and binary types differently; binary types show a download link. + +== Prompts panel + +The Prompts panel lists any prompt templates the server exposes through `prompts/list`. Prompt templates are parameterized prompts an agent can invoke by name. As with resources, many servers don't expose prompts. + +If your server does expose prompts: + +. Click a prompt to render its template. +. Fill in any required parameters in the rendered form. +. Click *Run* to see the rendered prompt content. + +== Session panel + +The Session panel keeps a running history of every call you've made through the Inspector — request, response, latency. Use it to: + +* Replay a previous call by clicking it in the history list. +* Diff two responses side-by-side (useful when iterating on a tool's logic). +* Copy a request as JSON-RPC for use outside the Inspector. + +// TODO: confirm exact session-history affordances and capture a screenshot. + +[[errors]] +== Common errors + +[cols="1,2"] +|=== +|Error |Meaning and fix + +|`OAuthConnectionRequired` +|User-delegated auth has no stored token for the calling user. Redpanda includes an `authorize_url` in the error detail; complete the consent flow per xref:user-delegated-oauth.adoc[User-delegated OAuth]. + +|`OAuthTokenExpired` +|Stored token is expired and refresh failed. Re-consent through *My Connections*. + +|`scope_upgrade_required` +|The user's connection lacks one of the server's `required_scopes`. Re-consent with the higher scope. + +|Transport / connection error +|The Inspector can't reach the upstream. For self-managed servers, check the *Connection* tab on the detail page; verify the URL and transport choice. + +|Tool input validation error +|The form's input doesn't match the tool's schema. The error message includes the offending field. Update and re-run. +|=== + +// TODO: screenshots of each error case once captured against `adp-production`. + +== Out of scope + +* *Pointing an agent at the server* — see the Agents docs. +* *Aggregating multiple servers* — see xref:ai-gateway:aggregation.adoc[MCP aggregation]. +* *Debugging the upstream system itself* (your SQL database, your Slack app) — outside the scope of MCP tooling. diff --git a/modules/mcp/pages/user-delegated-oauth.adoc b/modules/mcp/pages/user-delegated-oauth.adoc new file mode 100644 index 0000000..9f7cb77 --- /dev/null +++ b/modules/mcp/pages/user-delegated-oauth.adoc @@ -0,0 +1,104 @@ += Configure User-Delegated OAuth for an MCP Server +:description: Have each end-user authenticate against the MCP server's upstream system with their own credentials — Redpanda stores their token in the vault and injects it at call time. +:page-topic-type: how-to +:personas: platform_admin, app_developer +:learning-objective-1: Configure an MCP server to use user-delegated OAuth with a registered OAuth Provider +:learning-objective-2: Walk an end-user through the consent flow and verify the connection +:learning-objective-3: Troubleshoot scope upgrades, token expiry, and refresh failures + +include::ROOT:partial$adp-la.adoc[] + +User-delegated OAuth means each end-user authenticates against the MCP server's upstream system (Slack, Jira, Google, …) with their own credentials. Redpanda stores their token in the token vault and injects it at call time. Contrast with service-account OAuth, where one shared identity is used for every caller. + +After completing this guide, you will be able to: + +* [ ] {learning-objective-1} +* [ ] {learning-objective-2} +* [ ] {learning-objective-3} + +== Prerequisites + +* An OAuth Provider resource configured in the ADP UI under *OAuth Providers*. The provider declares the upstream's `authorize_url`, `token_url`, supported scopes, and client credentials. ++ +// TODO: link the OAuth Provider how-to once it exists. +* The required scopes for the upstream API you plan to call. +* For *self-managed* MCP servers: the server URL must be `https://` (proto rule `remote_mcp.user_oauth_requires_https`). HTTP is rejected at create time. +* For *managed* MCP servers: the type must support user-delegated OAuth. SQL doesn't; Slack, Jira, and Google managed types do. Check xref:managed-catalog.adoc[Managed catalog] before configuring. + +== Configure the server + +. Create or edit your MCP server (see xref:create-server.adoc[Create an MCP Server]). +. In the auth section, choose *User-delegated OAuth*. +. Pick the configured *OAuth Provider* (`UserOAuthAuth.provider_name`). +. List the *required scopes* (`UserOAuthAuth.required_scopes`). Redpanda enforces these at consent time. +. (Optional) Override token injection. By default Redpanda sends `Authorization: Bearer `. To use a different header, set `TokenInjection.header_name`. To omit the prefix entirely (for example, an upstream that expects a bare API key as the token), set `TokenInjection.header_prefix` to the empty string. ++ +// TODO: confirm exact UI labels for `TokenInjection.header_name` and `header_prefix`. +. Save. + +NOTE: Choosing user-delegated OAuth instead of service-account OAuth *is* the credential-mode decision — there's no separate field. User-delegated gives each caller a per-user upstream identity; service-account gives every caller one shared identity. Switching between them later requires re-consent for every active user. + +== The user connection flow + +The first time a user calls a tool that needs this server's auth, Redpanda doesn't have a stored token for them. The behavior is: + +. The MCP RPC returns `FAILED_PRECONDITION` with an `OAuthConnectionRequired` error detail. The detail carries an `authorize_url`. +. The ADP UI surfaces a consent prompt to the user, pointing at the `authorize_url`. +. The user completes the device-authorization flow with the upstream provider. +. The upstream provider redirects back to Redpanda with a token. Redpanda stores it in the token vault under that user's identity. +. The original tool call retries automatically. Subsequent calls reuse the stored token. + +After consent, the user can see and revoke their connection under *My Connections* in the ADP UI. + +// TODO: screenshot of the consent prompt and the resulting *My Connections* entry. + +== Scope upgrades + +If a user's stored connection has fewer scopes than the server's `required_scopes`, the gateway returns a `scope_upgrade_required` error and surfaces a new `authorize_url` requesting the additional scopes. The user re-consents; the connection is updated in place. + +// TODO: confirm the exact error code or status used for scope upgrade and capture a screenshot. + +== Refresh and expiry + +Redpanda transparently refreshes tokens before they expire, using the refresh token returned at consent time. + +When refresh fails (revoked token, idle too long, upstream error), the next tool call returns `OAuthTokenExpired` with a `reason`. The user must re-consent through the same flow as initial connection. + +== Service-account OAuth contrast + +If you want one shared upstream identity for every caller (instead of per-user identities), choose *Service-account OAuth* on the server instead of *User-delegated OAuth*. With service-account OAuth, every caller of every tool sees the same upstream identity; the upstream system has no idea which ADP user invoked the tool. With user-delegated OAuth, the upstream system sees each end-user as themselves and applies their own permissions. + +For the field-by-field service-account-OAuth setup, see xref:create-server.adoc#configure-authentication[create-server.adoc]. + +== Worked examples + +* xref:managed/slack.adoc[Slack] — consumer-facing user-delegated OAuth example. Shows the consent flow against a real Slack workspace. +* xref:managed/jira.adoc[Jira] — enterprise user-delegated OAuth example. Atlassian's OAuth flow differs from Slack's; this page calls out scope-management gotchas. + +== Troubleshooting + +[cols="1,2"] +|=== +|Symptom |What to check + +|"OAuth provider not found" +|The provider name on the server doesn't match an OAuth Provider in the ADP UI. Check spelling and that the provider exists. + +|"HTTPS required" on save (self-managed only) +|User-delegated OAuth requires `https://` URLs on the MCP server (proto rule `remote_mcp.user_oauth_requires_https`). Switch the server's URL to HTTPS. + +|`OAuthConnectionRequired` returned even after the user consented +|The user's vault entry might have been revoked or the token expired with no refresh. Have the user re-consent through *My Connections*. + +|`scope_upgrade_required` returned +|The required scopes on the server changed (or the user originally consented with fewer scopes). The user re-consents with the higher scope. + +|*My Connections* shows stale entries +|Connections persist until manually revoked. Have the user remove and re-add the connection if upstream credentials changed. +|=== + +== Out of scope + +* *Configuring an OAuth Provider* — separate workflow under the *OAuth Providers* section. +* *Service-account OAuth setup* — see xref:create-server.adoc#configure-authentication[create-server.adoc]. +* *Token vault internals* — Redpanda manages the vault; users see their own connections under *My Connections*, but the underlying storage isn't user-configurable. diff --git a/modules/observability/pages/concepts.adoc b/modules/observability/pages/concepts.adoc index 82c11f7..589bc3d 100644 --- a/modules/observability/pages/concepts.adoc +++ b/modules/observability/pages/concepts.adoc @@ -349,6 +349,6 @@ Trace data on `redpanda.otel_traces` is subject to a retention policy. When a tr == Next steps -* xref:ai-agents:observability/transcripts.adoc[] -* xref:ai-agents:agents/monitor-agents.adoc[] -* xref:ai-agents:mcp/remote/monitor-mcp-servers.adoc[] +* xref:transcripts.adoc[] +* xref:agents:monitor.adoc[] +* xref:mcp:test-tools.adoc[] diff --git a/modules/observability/pages/transcripts.adoc b/modules/observability/pages/transcripts.adoc index b6fe4b9..ef30135 100644 --- a/modules/observability/pages/transcripts.adoc +++ b/modules/observability/pages/transcripts.adoc @@ -20,11 +20,8 @@ After reading this page, you will be able to: == Prerequisites -* A running xref:ai-agents:agents/create-agent.adoc[agent] or xref:ai-agents:mcp/remote/quickstart.adoc[MCP server] with at least one execution -* Access to the ADP UI -// TODO: Replace with the exact standalone-ADP sign-in URL and IAM/role requirement once the standalone product surface ships. Today: flag `enableTranscriptsInConsole` must be on for the user's cluster. -* Read access to the `redpanda.otel_traces` glossterm:topic[] -// TODO: Confirm whether this ACL is user-managed or auto-granted on the standalone ADP UI. +* xref:agents:create-agent.adoc[Running agent] or xref:mcp:create-server.adoc[MCP server] with at least one execution +* Access to the Transcripts view (requires appropriate permissions to read the `redpanda.otel_traces` glossterm:topic[]) == Open the Transcripts view @@ -197,6 +194,6 @@ For long-running conversations, accept some reconstruction; for short conversati == Next steps -* xref:ai-agents:agents/monitor-agents.adoc[] -* xref:ai-agents:mcp/remote/monitor-mcp-servers.adoc[] -* xref:ai-agents:agents/troubleshooting.adoc[] +* xref:agents:monitor.adoc[] +* xref:mcp:test-tools.adoc[] +* xref:agents:troubleshoot.adoc[]