Skip to main content

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 limit parameter

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 clusters
  • page (int, default=1)
  • page_size (int, default=20, max=100)

Same pagination structure as applications

Key Features

Pagination Logic

  1. Page bounds checking: Returns error if page > total_pages
  2. Page size limits: Enforces max 100 items per page
  3. Metadata included: Every response includes pagination info
  4. Zero-based safe: Handles empty results gracefully

Benefits

  1. Memory control: Returns max 100 items instead of 800+
  2. Consistent API: All list operations use same pagination structure
  3. Client-friendly: Provides has_next/has_prev for UI navigation
  4. 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

  1. ✅ Pagination implemented for all list operations
  2. TODO: Implement unified search tool for keyword-based filtering
  3. TODO: Update ArgoCD agent system prompt to use pagination
  4. TODO: Test all endpoints with updated pagination
  5. TODO: Verify OOM is resolved with real workload

Files Modified

  1. ai_platform_engineering/agents/argocd/mcp/mcp_argocd/tools/api_v1_applications.py
  2. ai_platform_engineering/agents/argocd/mcp/mcp_argocd/tools/api_v1_projects.py
  3. ai_platform_engineering/agents/argocd/mcp/mcp_argocd/tools/api_v1_applicationsets.py
  4. ai_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"}'