ADR: MCP ArgoCD Pagination Implementation
Status: 🟢 In-use Category: Features & Enhancements Date: November 5, 2025 Signed-off-by: Sri Aradhyula <sraradhy@cisco.com>
Summary
Implemented strict pagination for all ArgoCD MCP list operations to prevent OOM issues caused by large responses (e.g., 819 applications = 255KB JSON).
Changes Made
1. Applications (api_v1_applications.py)
Function: list_applications()
New Parameters:
page(int, default=1): Page number (1-indexed)page_size(int, default=20, max=100): Items per page
Response Structure:
{
"items": [...], // Only 20 items instead of 819
"pagination": {
"page": 1,
"page_size": 20,
"total_items": 819,
"total_pages": 41,
"has_next": true,
"has_prev": false,
"showing_from": 1,
"showing_to": 20
},
"summary_only": true
}
2. Projects (api_v1_projects.py)
Function: project_list()
New Parameters:
page(int, default=1)page_size(int, default=20, max=100)- Removed old
limitparameter
Same pagination structure as applications
3. Application Sets (api_v1_applicationsets.py)
Function: applicationset_list()
New Parameters:
page(int, default=1)page_size(int, default=20, max=100)
Same pagination structure as applications
4. Clusters (api_v1_clusters.py)
Function: cluster_service__list()
New Parameters:
summary_only(bool, default=True): New addition for clusterspage(int, default=1)page_size(int, default=20, max=100)
Same pagination structure as applications
Key Features
Pagination Logic
- Page bounds checking: Returns error if page > total_pages
- Page size limits: Enforces max 100 items per page
- Metadata included: Every response includes pagination info
- Zero-based safe: Handles empty results gracefully
Benefits
- Memory control: Returns max 100 items instead of 800+
- Consistent API: All list operations use same pagination structure
- Client-friendly: Provides has_next/has_prev for UI navigation
- Backward compatible: Default values maintain similar behavior
Example Usage
# Get first page (default)
result = await list_applications()
# Returns items 1-20 of 819
# Get second page
result = await list_applications(page=2)
# Returns items 21-40 of 819
# Get more items per page
result = await list_applications(page=1, page_size=50)
# Returns items 1-50 of 819
# Navigate using metadata
if result["pagination"]["has_next"]:
next_page = result["pagination"]["page"] + 1
next_result = await list_applications(page=next_page)
Impact on OOM Issue
Before Pagination
- Request: "List ALL ArgoCD applications"
- Response: 819 apps × ~300 bytes = ~255KB in single tool output
- Problem: This gets stored in LangGraph message history
- Result: Context explodes to 460K+ tokens → OOM kill
After Pagination
- Request: "List ALL ArgoCD applications" (page defaults to 1)
- Response: 20 apps × ~300 bytes = ~6KB in single tool output
- Context size: Reduced by 97%
- Result: Stays well within 20K token limit → No OOM
Next Steps
- ✅ Pagination implemented for all list operations
- ⏳ TODO: Implement unified search tool for keyword-based filtering
- ⏳ TODO: Update ArgoCD agent system prompt to use pagination
- ⏳ TODO: Test all endpoints with updated pagination
- ⏳ TODO: Verify OOM is resolved with real workload
Files Modified
ai_platform_engineering/agents/argocd/mcp/mcp_argocd/tools/api_v1_applications.pyai_platform_engineering/agents/argocd/mcp/mcp_argocd/tools/api_v1_projects.pyai_platform_engineering/agents/argocd/mcp/mcp_argocd/tools/api_v1_applicationsets.pyai_platform_engineering/agents/argocd/mcp/mcp_argocd/tools/api_v1_clusters.py
Testing Required
Need to restart MCP server and test:
# Restart MCP ArgoCD server
docker compose -f docker-compose.dev.yaml --profile=p2p-no-rag restart mcp-argocd agent-argocd-p2p
# Test pagination
curl -X POST http://localhost:8000 \
-H "Content-Type: application/json" \
-d '{"message": "List applications page 1"}'