Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5b3c8b2
Enhance MCP server pipeline patterns documentation
JakeSCahill Dec 5, 2025
68557dd
Add MCP documentation partials for single-sourcing
JakeSCahill Dec 5, 2025
6dd0b81
Update MCP pages to use single-sourced partials
JakeSCahill Dec 5, 2025
0ca0c8d
Add CI/CD testing infrastructure for MCP examples
JakeSCahill Dec 5, 2025
d3a4f31
Add generate input example for data generators pattern
JakeSCahill Dec 5, 2025
2810949
fix anchor
JakeSCahill Dec 5, 2025
be6626e
Use Cloud remote that includes single-sourced content DO NOT MERGE TH…
JakeSCahill Dec 8, 2025
fbfb7c4
Fix doc-tools not found error in GitHub Actions
JakeSCahill Dec 8, 2025
0cd112c
Make MCP validation failures fail the test suite
JakeSCahill Dec 8, 2025
e5b650a
fix: Resolve ShellCheck warnings in test script
JakeSCahill Dec 8, 2025
6a8ef6e
Add badge macro:
JakeSCahill Dec 8, 2025
502a566
Add badge macro:
JakeSCahill Dec 8, 2025
2a31da5
Add 'Outputs with processors' pattern for MCP servers
JakeSCahill Dec 9, 2025
d5b61d2
apply suggestions
JakeSCahill Dec 10, 2025
d425f35
Apply suggestions from code review
JakeSCahill Dec 10, 2025
0ee420a
Apply suggestions from code review
JakeSCahill Dec 10, 2025
717d9cd
Fix tests to use mcp-server lint
JakeSCahill Dec 10, 2025
82c713e
Use verbose linting and check for output since Connect doe
JakeSCahill Dec 11, 2025
046a5f6
Fix linter
JakeSCahill Dec 11, 2025
24977cd
Apply suggestions from code review
JakeSCahill Dec 17, 2025
685641c
Merge branch 'main' into single-source
JakeSCahill Dec 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions .github/workflows/test-mcp-examples.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: Test MCP Examples

on:
push:
branches: [main]
paths:
- 'modules/ai-agents/examples/**/*.yaml'
- 'modules/ai-agents/examples/test-mcp-examples.sh'
pull_request:
branches: [main]
paths:
- 'modules/ai-agents/examples/**/*.yaml'
- 'modules/ai-agents/examples/test-mcp-examples.sh'

jobs:
lint-and-test:
name: Lint and Test All Examples
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install dependencies
run: npm install

- name: Install yq
run: |
sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
sudo chmod +x /usr/local/bin/yq

- name: Install tools
run: |
npx doc-tools install-test-dependencies
rpk connect install

- name: Make test script executable
run: chmod +x modules/ai-agents/examples/test-mcp-examples.sh

# Test all examples
- name: Run automated test script
run: |
cd modules/ai-agents/examples
./test-mcp-examples.sh

test-matrix:
name: Test Examples by Component Type
runs-on: ubuntu-latest
strategy:
matrix:
component: [processors, inputs, outputs, caches, o11y]
fail-fast: false

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install dependencies
run: npm install

- name: Install yq
run: |
sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
sudo chmod +x /usr/local/bin/yq

- name: Install tools
run: |
npx doc-tools install-test-dependencies
rpk connect install

- name: Make test script executable
run: chmod +x modules/ai-agents/examples/test-mcp-examples.sh

- name: Test ${{ matrix.component }} examples
run: |
cd modules/ai-agents/examples
./test-mcp-examples.sh ${{ matrix.component }}
6 changes: 3 additions & 3 deletions .github/workflows/update-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
cancel-in-progress: true

env:
NODE_VERSION: '18'
NODE_VERSION: '22'
DOCS_OVERRIDES: docs-data/overrides.json

steps:
Expand Down Expand Up @@ -51,13 +51,13 @@ jobs:

- name: Install tools
run: |
npx doc-tools install-test-dependencies
npx --no-install doc-tools install-test-dependencies
rpk connect install

- name: Generate RPCN Connector docs
id: generate
run: |
npx doc-tools generate rpcn-connector-docs \
npx --no-install doc-tools generate rpcn-connector-docs \
--fetch-connectors \
--overrides $DOCS_OVERRIDES \
--draft-missing \
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update-extensions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:

- uses: actions/setup-node@v4
with:
node-version: '18'
node-version: '22'

- run: npm install

Expand Down
1 change: 1 addition & 0 deletions local-antora-playbook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ asciidoc:
- '@redpanda-data/docs-extensions-and-macros/macros/config-ref'
- '@redpanda-data/docs-extensions-and-macros/macros/helm-ref'
- '@redpanda-data/docs-extensions-and-macros/asciidoc-extensions/add-line-numbers-highlights'
- '@redpanda-data/docs-extensions-and-macros/macros/badge'
antora:
extensions:
- require: '@redpanda-data/docs-extensions-and-macros/extensions/generate-rp-connect-categories'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,3 @@ meta:
mcp:
enabled: true
description: "Consume order events to trigger workflows"
properties:
- name: event_type
type: string
description: "Type of event to process (order_created, order_cancelled, etc.)"
required: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
generate:
interval: 1s
count: 0
mapping: |
root.id = uuid_v4()
root.timestamp = now()
root.user_id = random_int(min: 1000, max: 9999)
root.event_type = ["login", "purchase", "logout"].index(random_int(max: 2))
root.amount = if this.event_type == "purchase" { random_int(min: 10, max: 500) }
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
redpanda:
seed_brokers: [ "${REDPANDA_BROKERS}" ]
topic: "llm-responses"

processors:
- openai_chat_completion:
api_key: "${OPENAI_API_KEY}"
model: "gpt-4"
prompt: ${! json("question") }
- mapping: |
root.question = this.question
root.answer = this.content
root.timestamp = now().ts_format("2006-01-02T15:04:05Z07:00")
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ meta:
description: "Customer ID for partitioning"
required: true
- name: order_data
type: object
description: "Order details (items, total, etc.)"
type: string
description: "Order details as JSON string (items, total, etc.)"
required: true
157 changes: 157 additions & 0 deletions modules/ai-agents/examples/test-mcp-examples.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
#!/usr/bin/env bash
#
# Automated testing script for Redpanda Connect MCP examples
#
# Usage:
# ./test-mcp-examples.sh

set -euo pipefail

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# Counters
TOTAL=0
SKIPPED=0
MCP_FAILS=0

echo "🧪 Redpanda Connect MCP Examples Test Suite"
echo "============================================"
echo ""

# Run MCP server lint on the directory
echo "Running rpk connect mcp-server lint..."
LINT_OUTPUT=$(rpk connect mcp-server lint --skip-env-var-check --verbose 2>&1) || {
echo -e "${RED}❌ Linting failed${NC}"
echo ""
echo "$LINT_OUTPUT"
exit 1
}
echo -e "${GREEN}✅ Linting passed${NC}"
echo ""

# Function to validate MCP metadata
validate_mcp_metadata() {
local file=$1

echo -n " Validating MCP metadata... "

# Determine which YAML parser to use
local use_yq=true
if ! command -v yq &> /dev/null; then
use_yq=false
if ! command -v python3 &> /dev/null; then
echo -e "${RED}FAILED${NC} (neither yq nor python3 available)"
MCP_FAILS=$((MCP_FAILS + 1))
return 1
fi
fi

# Check if .meta.mcp exists
local mcp_exists
if $use_yq; then
mcp_exists=$(yq eval '.meta.mcp' "$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)
fi

if [[ "$mcp_exists" == "null" || -z "$mcp_exists" ]]; then
echo -e "${YELLOW}SKIPPED${NC} (no MCP metadata)"
SKIPPED=$((SKIPPED + 1))
return 0
fi

# Read .meta.mcp.enabled
local enabled
if $use_yq; then
enabled=$(yq eval '.meta.mcp.enabled' "$file" 2>/dev/null)
else
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)
fi

if [[ "$enabled" != "true" ]]; then
echo -e "${YELLOW}WARNING${NC} (mcp.enabled not set to true)"
return 0
fi

# Read .meta.mcp.description
local description
if $use_yq; then
description=$(yq eval '.meta.mcp.description' "$file" 2>/dev/null)
else
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

if [[ "$description" == "null" || -z "$description" ]]; then
echo -e "${RED}FAILED${NC} (missing description)"
MCP_FAILS=$((MCP_FAILS + 1))
return 1
fi

echo -e "${GREEN}PASSED${NC}"
return 0
}
Comment thread
JakeSCahill marked this conversation as resolved.

# Validate MCP metadata for each file
for file in resources/*/*.yaml; do
if [[ -f "$file" ]]; then
TOTAL=$((TOTAL + 1))
echo ""
echo -e "${BLUE}📄 Validating: $file${NC}"
validate_mcp_metadata "$file"
fi
done

# Summary
echo ""
echo "============================================"
echo "📊 Test Summary"
echo "============================================"
echo "Total configs tested: $TOTAL"
if [[ $MCP_FAILS -gt 0 ]]; then
echo -e "MCP validation failures: ${RED}$MCP_FAILS${NC}"
fi
if [[ $SKIPPED -gt 0 ]]; then
echo -e "Skipped: ${YELLOW}$SKIPPED${NC}"
fi
echo ""

if [[ $MCP_FAILS -gt 0 ]]; then
echo -e "${RED}❌ Some tests failed${NC}"
exit 1
else
echo -e "${GREEN}✅ All tests passed!${NC}"
exit 0
fi
Loading