Skip to content

Commit 64dccfb

Browse files
Single source MCP server docs (#344)
Co-authored-by: Michele Cyran <michele@redpanda.com>
1 parent a0d2c50 commit 64dccfb

28 files changed

Lines changed: 1384 additions & 443 deletions
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: Test MCP Examples
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'modules/ai-agents/examples/**/*.yaml'
8+
- 'modules/ai-agents/examples/test-mcp-examples.sh'
9+
pull_request:
10+
branches: [main]
11+
paths:
12+
- 'modules/ai-agents/examples/**/*.yaml'
13+
- 'modules/ai-agents/examples/test-mcp-examples.sh'
14+
15+
jobs:
16+
lint-and-test:
17+
name: Lint and Test All Examples
18+
runs-on: ubuntu-latest
19+
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
24+
- name: Install dependencies
25+
run: npm install
26+
27+
- name: Install yq
28+
run: |
29+
sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
30+
sudo chmod +x /usr/local/bin/yq
31+
32+
- name: Install tools
33+
run: |
34+
npx doc-tools install-test-dependencies
35+
rpk connect install
36+
37+
- name: Make test script executable
38+
run: chmod +x modules/ai-agents/examples/test-mcp-examples.sh
39+
40+
# Test all examples
41+
- name: Run automated test script
42+
run: |
43+
cd modules/ai-agents/examples
44+
./test-mcp-examples.sh
45+
46+
test-matrix:
47+
name: Test Examples by Component Type
48+
runs-on: ubuntu-latest
49+
strategy:
50+
matrix:
51+
component: [processors, inputs, outputs, caches, o11y]
52+
fail-fast: false
53+
54+
steps:
55+
- name: Checkout code
56+
uses: actions/checkout@v4
57+
58+
- name: Install dependencies
59+
run: npm install
60+
61+
- name: Install yq
62+
run: |
63+
sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
64+
sudo chmod +x /usr/local/bin/yq
65+
66+
- name: Install tools
67+
run: |
68+
npx doc-tools install-test-dependencies
69+
rpk connect install
70+
71+
- name: Make test script executable
72+
run: chmod +x modules/ai-agents/examples/test-mcp-examples.sh
73+
74+
- name: Test ${{ matrix.component }} examples
75+
run: |
76+
cd modules/ai-agents/examples
77+
./test-mcp-examples.sh ${{ matrix.component }}

.github/workflows/update-docs.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
cancel-in-progress: true
1919

2020
env:
21-
NODE_VERSION: '18'
21+
NODE_VERSION: '22'
2222
DOCS_OVERRIDES: docs-data/overrides.json
2323

2424
steps:
@@ -51,13 +51,13 @@ jobs:
5151

5252
- name: Install tools
5353
run: |
54-
npx doc-tools install-test-dependencies
54+
npx --no-install doc-tools install-test-dependencies
5555
rpk connect install
5656
5757
- name: Generate RPCN Connector docs
5858
id: generate
5959
run: |
60-
npx doc-tools generate rpcn-connector-docs \
60+
npx --no-install doc-tools generate rpcn-connector-docs \
6161
--fetch-connectors \
6262
--overrides $DOCS_OVERRIDES \
6363
--draft-missing \

.github/workflows/update-extensions.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232

3333
- uses: actions/setup-node@v4
3434
with:
35-
node-version: '18'
35+
node-version: '22'
3636

3737
- run: npm install
3838

local-antora-playbook.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ asciidoc:
3232
- '@redpanda-data/docs-extensions-and-macros/macros/config-ref'
3333
- '@redpanda-data/docs-extensions-and-macros/macros/helm-ref'
3434
- '@redpanda-data/docs-extensions-and-macros/asciidoc-extensions/add-line-numbers-highlights'
35+
- '@redpanda-data/docs-extensions-and-macros/macros/badge'
3536
antora:
3637
extensions:
3738
- require: '@redpanda-data/docs-extensions-and-macros/extensions/generate-rp-connect-categories'

modules/ai-agents/examples/resources/inputs/event-workflow.yaml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,3 @@ meta:
99
mcp:
1010
enabled: true
1111
description: "Consume order events to trigger workflows"
12-
properties:
13-
- name: event_type
14-
type: string
15-
description: "Type of event to process (order_created, order_cancelled, etc.)"
16-
required: false
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
generate:
2+
interval: 1s
3+
count: 0
4+
mapping: |
5+
root.id = uuid_v4()
6+
root.timestamp = now()
7+
root.user_id = random_int(min: 1000, max: 9999)
8+
root.event_type = ["login", "purchase", "logout"].index(random_int(max: 2))
9+
root.amount = if this.event_type == "purchase" { random_int(min: 10, max: 500) }
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
redpanda:
2+
seed_brokers: [ "${REDPANDA_BROKERS}" ]
3+
topic: "llm-responses"
4+
5+
processors:
6+
- openai_chat_completion:
7+
api_key: "${OPENAI_API_KEY}"
8+
model: "gpt-4"
9+
prompt: ${! json("question") }
10+
- mapping: |
11+
root.question = this.question
12+
root.answer = this.content
13+
root.timestamp = now().ts_format("2006-01-02T15:04:05Z07:00")

modules/ai-agents/examples/resources/outputs/redpanda-publish.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ meta:
2121
description: "Customer ID for partitioning"
2222
required: true
2323
- name: order_data
24-
type: object
25-
description: "Order details (items, total, etc.)"
24+
type: string
25+
description: "Order details as JSON string (items, total, etc.)"
2626
required: true
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Automated testing script for Redpanda Connect MCP examples
4+
#
5+
# Usage:
6+
# ./test-mcp-examples.sh
7+
8+
set -euo pipefail
9+
10+
# Colors for output
11+
RED='\033[0;31m'
12+
GREEN='\033[0;32m'
13+
YELLOW='\033[1;33m'
14+
BLUE='\033[0;34m'
15+
NC='\033[0m'
16+
17+
# Counters
18+
TOTAL=0
19+
SKIPPED=0
20+
MCP_FAILS=0
21+
22+
echo "🧪 Redpanda Connect MCP Examples Test Suite"
23+
echo "============================================"
24+
echo ""
25+
26+
# Run MCP server lint on the directory
27+
echo "Running rpk connect mcp-server lint..."
28+
LINT_OUTPUT=$(rpk connect mcp-server lint --skip-env-var-check --verbose 2>&1) || {
29+
echo -e "${RED}❌ Linting failed${NC}"
30+
echo ""
31+
echo "$LINT_OUTPUT"
32+
exit 1
33+
}
34+
echo -e "${GREEN}✅ Linting passed${NC}"
35+
echo ""
36+
37+
# Function to validate MCP metadata
38+
validate_mcp_metadata() {
39+
local file=$1
40+
41+
echo -n " Validating MCP metadata... "
42+
43+
# Determine which YAML parser to use
44+
local use_yq=true
45+
if ! command -v yq &> /dev/null; then
46+
use_yq=false
47+
if ! command -v python3 &> /dev/null; then
48+
echo -e "${RED}FAILED${NC} (neither yq nor python3 available)"
49+
MCP_FAILS=$((MCP_FAILS + 1))
50+
return 1
51+
fi
52+
fi
53+
54+
# Check if .meta.mcp exists
55+
local mcp_exists
56+
if $use_yq; then
57+
mcp_exists=$(yq eval '.meta.mcp' "$file" 2>/dev/null)
58+
else
59+
mcp_exists=$(python3 -c "
60+
import yaml
61+
try:
62+
with open('$file') as f:
63+
doc = yaml.safe_load(f)
64+
meta = doc.get('meta', {}) if doc else {}
65+
mcp = meta.get('mcp')
66+
print('null' if mcp is None else 'exists')
67+
except:
68+
print('null')
69+
" 2>/dev/null)
70+
fi
71+
72+
if [[ "$mcp_exists" == "null" || -z "$mcp_exists" ]]; then
73+
echo -e "${YELLOW}SKIPPED${NC} (no MCP metadata)"
74+
SKIPPED=$((SKIPPED + 1))
75+
return 0
76+
fi
77+
78+
# Read .meta.mcp.enabled
79+
local enabled
80+
if $use_yq; then
81+
enabled=$(yq eval '.meta.mcp.enabled' "$file" 2>/dev/null)
82+
else
83+
enabled=$(python3 -c "
84+
import yaml
85+
try:
86+
with open('$file') as f:
87+
doc = yaml.safe_load(f)
88+
enabled = doc.get('meta', {}).get('mcp', {}).get('enabled')
89+
print('null' if enabled is None else str(enabled).lower())
90+
except:
91+
print('null')
92+
" 2>/dev/null)
93+
fi
94+
95+
if [[ "$enabled" != "true" ]]; then
96+
echo -e "${YELLOW}WARNING${NC} (mcp.enabled not set to true)"
97+
return 0
98+
fi
99+
100+
# Read .meta.mcp.description
101+
local description
102+
if $use_yq; then
103+
description=$(yq eval '.meta.mcp.description' "$file" 2>/dev/null)
104+
else
105+
description=$(python3 -c "
106+
import yaml
107+
try:
108+
with open('$file') as f:
109+
doc = yaml.safe_load(f)
110+
desc = doc.get('meta', {}).get('mcp', {}).get('description')
111+
print('null' if desc is None or desc == '' else str(desc))
112+
except:
113+
print('null')
114+
" 2>/dev/null)
115+
fi
116+
117+
if [[ "$description" == "null" || -z "$description" ]]; then
118+
echo -e "${RED}FAILED${NC} (missing description)"
119+
MCP_FAILS=$((MCP_FAILS + 1))
120+
return 1
121+
fi
122+
123+
echo -e "${GREEN}PASSED${NC}"
124+
return 0
125+
}
126+
127+
# Validate MCP metadata for each file
128+
for file in resources/*/*.yaml; do
129+
if [[ -f "$file" ]]; then
130+
TOTAL=$((TOTAL + 1))
131+
echo ""
132+
echo -e "${BLUE}📄 Validating: $file${NC}"
133+
validate_mcp_metadata "$file"
134+
fi
135+
done
136+
137+
# Summary
138+
echo ""
139+
echo "============================================"
140+
echo "📊 Test Summary"
141+
echo "============================================"
142+
echo "Total configs tested: $TOTAL"
143+
if [[ $MCP_FAILS -gt 0 ]]; then
144+
echo -e "MCP validation failures: ${RED}$MCP_FAILS${NC}"
145+
fi
146+
if [[ $SKIPPED -gt 0 ]]; then
147+
echo -e "Skipped: ${YELLOW}$SKIPPED${NC}"
148+
fi
149+
echo ""
150+
151+
if [[ $MCP_FAILS -gt 0 ]]; then
152+
echo -e "${RED}❌ Some tests failed${NC}"
153+
exit 1
154+
else
155+
echo -e "${GREEN}✅ All tests passed!${NC}"
156+
exit 0
157+
fi

0 commit comments

Comments
 (0)