Skip to content

Conversation

@jaideepr97
Copy link
Contributor

@jaideepr97 jaideepr97 commented Jan 28, 2026

What does this PR do?

  • ensures config is the source of truth for stored connectors at boot time by removing any stored connectors that no longer appear in the config
  • implements read only api endpoints for connectors

Test Plan

unit tests

For API changes, include:

  1. A testing script (Python, curl, etc.) that exercises the new/modified endpoints
  2. The output from running your script

Example:

#!/bin/bash
# Demo script for the Llama Stack Connectors API (readonly endpoints)
#
# Prerequisites:
# 1. A Llama Stack server running (e.g., llama stack run)
# 2. Connectors configured in your stack config file
#
# Example stack config with connectors:
#   connectors:
#     - connector_id: my-mcp-server
#       connector_type: mcp
#       url: http://localhost:3000/mcp
#       server_label: "My MCP Server"

set -e

# Configuration
BASE_URL="${LLAMA_STACK_URL:-http://localhost:8321}"
API_VERSION="v1alpha"

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

echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}Llama Stack Connectors API Demo${NC}"
echo -e "${BLUE}========================================${NC}"
echo -e "Base URL: ${BASE_URL}"
echo ""

# -----------------------------------------------------------------------------
# 1. List all connectors
# -----------------------------------------------------------------------------
echo -e "${GREEN}1. List all connectors${NC}"
echo -e "${YELLOW}GET ${API_VERSION}/connectors${NC}"
echo ""

curl -s -X GET "${BASE_URL}/${API_VERSION}/connectors" \
  -H "Content-Type: application/json" | jq .

echo ""
echo "---"
echo ""

# -----------------------------------------------------------------------------
# 2. Get a specific connector by ID
# -----------------------------------------------------------------------------
CONNECTOR_ID="kubernetes"

echo -e "${GREEN}2. Get connector by ID${NC}"
echo -e "${YELLOW}GET ${API_VERSION}/connectors/${CONNECTOR_ID}${NC}"
echo ""

curl -s -X GET "${BASE_URL}/${API_VERSION}/connectors/${CONNECTOR_ID}" \
  -H "Content-Type: application/json" | jq .

echo ""
echo "---"
echo ""

# -----------------------------------------------------------------------------
# 3. List tools from a connector
# -----------------------------------------------------------------------------
echo -e "${GREEN}3. List tools from connector${NC}"
echo -e "${YELLOW}GET ${API_VERSION}/connectors/${CONNECTOR_ID}/tools${NC}"
echo ""

curl -s -X GET "${BASE_URL}/${API_VERSION}/connectors/${CONNECTOR_ID}/tools" \
  -H "Content-Type: application/json" | jq .

echo ""
echo "---"
echo ""

# -----------------------------------------------------------------------------
# 4. Get a specific tool from a connector
# -----------------------------------------------------------------------------
TOOL_NAME="namespaces_list"

echo -e "${GREEN}4. Get specific tool from connector${NC}"
echo -e "${YELLOW}GET ${API_VERSION}/connectors/${CONNECTOR_ID}/tools/${TOOL_NAME}${NC}"
echo ""

curl -s -X GET "${BASE_URL}/${API_VERSION}/connectors/${CONNECTOR_ID}/tools/${TOOL_NAME}" \
  -H "Content-Type: application/json" | jq .

echo ""
echo "---"
echo ""

# -----------------------------------------------------------------------------
# 5. With Authorization header (for OAuth-protected MCP servers)
# -----------------------------------------------------------------------------
echo -e "${GREEN}5. Get connector with Authorization header${NC}"
echo -e "${YELLOW}(For OAuth-protected MCP servers)${NC}"
echo ""

echo "curl -X GET '${BASE_URL}/${API_VERSION}/connectors/${CONNECTOR_ID}' \\"
echo "  -H 'Content-Type: application/json' \\"
echo "  -H 'Authorization: Bearer <your-oauth-token>'"
echo ""

# Uncomment to actually run with a token:
# AUTH_TOKEN="${LLAMA_STACK_AUTH_TOKEN:-}"
# if [ -n "$AUTH_TOKEN" ]; then
#   curl -s -X GET "${BASE_URL}/${API_VERSION}/connectors/${CONNECTOR_ID}" \
#     -H "Content-Type: application/json" \
#     -H "Authorization: Bearer ${AUTH_TOKEN}" | jq .
# fi

echo "---"
echo ""

# -----------------------------------------------------------------------------
# Summary
# -----------------------------------------------------------------------------
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}API Endpoints Summary${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
echo "Readonly Connectors API endpoints:"
echo ""
echo "  GET /${API_VERSION}/connectors"
echo "      List all configured connectors"
echo ""
echo "  GET /${API_VERSION}/connectors/{connector_id}"
echo "      Get a specific connector (fetches live server info)"
echo ""
echo "  GET /${API_VERSION}/connectors/{connector_id}/tools"
echo "      List all tools available from a connector"
echo ""
echo "  GET /${API_VERSION}/connectors/{connector_id}/tools/{tool_name}"
echo "      Get a specific tool definition from a connector"
echo ""
echo "Note: Connectors are configured via the stack config file."
echo "      There are no POST/PUT/DELETE endpoints - connectors are"
echo "      managed declaratively through configuration."
echo ""
echo -e "${BLUE}Usage:${NC}"
echo "  $0 [connector_id] [tool_name]"
echo ""
echo -e "${BLUE}Environment variables:${NC}"
echo "  LLAMA_STACK_URL - Base URL (default: http://localhost:8321)"
echo ""

Output:

╰─ ./demo_connectors_api.sh                                                                           ─╯
========================================
Llama Stack Connectors API Demo
========================================
Base URL: http://localhost:8321

1. List all connectors
GET v1alpha/connectors

{
  "data": [
    {
      "connector_type": "mcp",
      "connector_id": "kubernetes",
      "url": "http://localhost:8080/mcp",
      "server_label": null,
      "server_name": null,
      "server_description": null,
      "server_version": null
    },
    {
      "connector_type": "mcp",
      "connector_id": "slack",
      "url": "http://localhost:13080/sse",
      "server_label": null,
      "server_name": null,
      "server_description": null,
      "server_version": null
    }
  ]
}

---

2. Get connector by ID
GET v1alpha/connectors/kubernetes

{
  "connector_type": "mcp",
  "connector_id": "kubernetes",
  "url": "http://localhost:8080/mcp",
  "server_label": null,
  "server_name": "kubernetes-mcp-server",
  "server_description": null,
  "server_version": "v0.0.57"
}

---

3. List tools from connector
GET v1alpha/connectors/kubernetes/tools

{
  "data": [
    {
      "toolgroup_id": null,
      "name": "configuration_contexts_list",
      "description": "List all available context names and associated server urls from the kubeconfig file",
      "input_schema": {
        "type": "object"
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "configuration_view",
      "description": "Get the current Kubernetes configuration content as a kubeconfig YAML",
      "input_schema": {
        "type": "object",
        "properties": {
          "minified": {
            "type": "boolean",
            "description": "Return a minified version of the configuration. If set to true, keeps only the current-context and the relevant pieces of the configuration for that context. If set to false, all contexts, clusters, auth-infos, and users are returned in the configuration. (Optional, default true)"
          }
        }
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "events_list",
      "description": "List all the Kubernetes events in the current cluster from all namespaces",
      "input_schema": {
        "type": "object",
        "properties": {
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "namespace": {
            "type": "string",
            "description": "Optional Namespace to retrieve the events from. If not provided, will list events from all namespaces"
          }
        }
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "helm_install",
      "description": "Install a Helm chart in the current or provided namespace",
      "input_schema": {
        "type": "object",
        "properties": {
          "chart": {
            "type": "string",
            "description": "Chart reference to install (for example: stable/grafana, oci://ghcr.io/nginxinc/charts/nginx-ingress)"
          },
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "name": {
            "type": "string",
            "description": "Name of the Helm release (Optional, random name if not provided)"
          },
          "namespace": {
            "type": "string",
            "description": "Namespace to install the Helm chart in (Optional, current namespace if not provided)"
          },
          "values": {
            "type": "object",
            "properties": {},
            "description": "Values to pass to the Helm chart (Optional)"
          }
        },
        "required": [
          "chart"
        ]
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "helm_list",
      "description": "List all the Helm releases in the current or provided namespace (or in all namespaces if specified)",
      "input_schema": {
        "type": "object",
        "properties": {
          "all_namespaces": {
            "type": "boolean",
            "description": "If true, lists all Helm releases in all namespaces ignoring the namespace argument (Optional)"
          },
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "namespace": {
            "type": "string",
            "description": "Namespace to list Helm releases from (Optional, all namespaces if not provided)"
          }
        }
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "helm_uninstall",
      "description": "Uninstall a Helm release in the current or provided namespace",
      "input_schema": {
        "type": "object",
        "properties": {
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "name": {
            "type": "string",
            "description": "Name of the Helm release to uninstall"
          },
          "namespace": {
            "type": "string",
            "description": "Namespace to uninstall the Helm release from (Optional, current namespace if not provided)"
          }
        },
        "required": [
          "name"
        ]
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "namespaces_list",
      "description": "List all the Kubernetes namespaces in the current cluster",
      "input_schema": {
        "type": "object",
        "properties": {
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          }
        }
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "nodes_log",
      "description": "Get logs from a Kubernetes node (kubelet, kube-proxy, or other system logs). This accesses node logs through the Kubernetes API proxy to the kubelet",
      "input_schema": {
        "type": "object",
        "properties": {
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "name": {
            "type": "string",
            "description": "Name of the node to get logs from"
          },
          "query": {
            "type": "string",
            "description": "query specifies services(s) or files from which to return logs (required). Example: \"kubelet\" to fetch kubelet logs, \"/<log-file-name>\" to fetch a specific log file from the node (e.g., \"/var/log/kubelet.log\" or \"/var/log/kube-proxy.log\")"
          },
          "tailLines": {
            "type": "integer",
            "description": "Number of lines to retrieve from the end of the logs (Optional, 0 means all logs)",
            "default": 100,
            "minimum": 0
          }
        },
        "required": [
          "name",
          "query"
        ]
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "nodes_stats_summary",
      "description": "Get detailed resource usage statistics from a Kubernetes node via the kubelet's Summary API. Provides comprehensive metrics including CPU, memory, filesystem, and network usage at the node, pod, and container levels. On systems with cgroup v2 and kernel 4.20+, also includes PSI (Pressure Stall Information) metrics that show resource pressure for CPU, memory, and I/O. See https://kubernetes.io/docs/reference/instrumentation/understand-psi-metrics/ for details on PSI metrics",
      "input_schema": {
        "type": "object",
        "properties": {
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "name": {
            "type": "string",
            "description": "Name of the node to get stats from"
          }
        },
        "required": [
          "name"
        ]
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "nodes_top",
      "description": "List the resource consumption (CPU and memory) as recorded by the Kubernetes Metrics Server for the specified Kubernetes Nodes or all nodes in the cluster",
      "input_schema": {
        "type": "object",
        "properties": {
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "label_selector": {
            "type": "string",
            "description": "Kubernetes label selector (e.g. 'node-role.kubernetes.io/worker=') to filter nodes by label (Optional, only applicable when name is not provided)",
            "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]"
          },
          "name": {
            "type": "string",
            "description": "Name of the Node to get the resource consumption from (Optional, all Nodes if not provided)"
          }
        }
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "pods_delete",
      "description": "Delete a Kubernetes Pod in the current or provided namespace with the provided name",
      "input_schema": {
        "type": "object",
        "properties": {
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "name": {
            "type": "string",
            "description": "Name of the Pod to delete"
          },
          "namespace": {
            "type": "string",
            "description": "Namespace to delete the Pod from"
          }
        },
        "required": [
          "name"
        ]
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "pods_exec",
      "description": "Execute a command in a Kubernetes Pod in the current or provided namespace with the provided name and command",
      "input_schema": {
        "type": "object",
        "properties": {
          "command": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Command to execute in the Pod container. The first item is the command to be run, and the rest are the arguments to that command. Example: [\"ls\", \"-l\", \"/tmp\"]"
          },
          "container": {
            "type": "string",
            "description": "Name of the Pod container where the command will be executed (Optional)"
          },
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "name": {
            "type": "string",
            "description": "Name of the Pod where the command will be executed"
          },
          "namespace": {
            "type": "string",
            "description": "Namespace of the Pod where the command will be executed"
          }
        },
        "required": [
          "name",
          "command"
        ]
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "pods_get",
      "description": "Get a Kubernetes Pod in the current or provided namespace with the provided name",
      "input_schema": {
        "type": "object",
        "properties": {
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "name": {
            "type": "string",
            "description": "Name of the Pod"
          },
          "namespace": {
            "type": "string",
            "description": "Namespace to get the Pod from"
          }
        },
        "required": [
          "name"
        ]
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "pods_list",
      "description": "List all the Kubernetes pods in the current cluster from all namespaces",
      "input_schema": {
        "type": "object",
        "properties": {
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "fieldSelector": {
            "type": "string",
            "description": "Optional Kubernetes field selector to filter pods by field values (e.g. 'status.phase=Running', 'spec.nodeName=node1'). Supported fields: metadata.name, metadata.namespace, spec.nodeName, spec.restartPolicy, spec.schedulerName, spec.serviceAccountName, status.phase (Pending/Running/Succeeded/Failed/Unknown), status.podIP, status.nominatedNodeName. Note: CrashLoopBackOff is a container state, not a pod phase, so it cannot be filtered directly. See https://kubernetes.io/docs/concepts/overview/working-with-objects/field-selectors/",
            "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]"
          },
          "labelSelector": {
            "type": "string",
            "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
            "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]"
          }
        }
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "pods_list_in_namespace",
      "description": "List all the Kubernetes pods in the specified namespace in the current cluster",
      "input_schema": {
        "type": "object",
        "properties": {
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "fieldSelector": {
            "type": "string",
            "description": "Optional Kubernetes field selector to filter pods by field values (e.g. 'status.phase=Running', 'spec.nodeName=node1'). Supported fields: metadata.name, metadata.namespace, spec.nodeName, spec.restartPolicy, spec.schedulerName, spec.serviceAccountName, status.phase (Pending/Running/Succeeded/Failed/Unknown), status.podIP, status.nominatedNodeName. Note: CrashLoopBackOff is a container state, not a pod phase, so it cannot be filtered directly. See https://kubernetes.io/docs/concepts/overview/working-with-objects/field-selectors/",
            "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]"
          },
          "labelSelector": {
            "type": "string",
            "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
            "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]"
          },
          "namespace": {
            "type": "string",
            "description": "Namespace to list pods from"
          }
        },
        "required": [
          "namespace"
        ]
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "pods_log",
      "description": "Get the logs of a Kubernetes Pod in the current or provided namespace with the provided name",
      "input_schema": {
        "type": "object",
        "properties": {
          "container": {
            "type": "string",
            "description": "Name of the Pod container to get the logs from (Optional)"
          },
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "name": {
            "type": "string",
            "description": "Name of the Pod to get the logs from"
          },
          "namespace": {
            "type": "string",
            "description": "Namespace to get the Pod logs from"
          },
          "previous": {
            "type": "boolean",
            "description": "Return previous terminated container logs (Optional)"
          },
          "tail": {
            "type": "integer",
            "description": "Number of lines to retrieve from the end of the logs (Optional, default: 100)",
            "default": 100,
            "minimum": 0
          }
        },
        "required": [
          "name"
        ]
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "pods_run",
      "description": "Run a Kubernetes Pod in the current or provided namespace with the provided container image and optional name",
      "input_schema": {
        "type": "object",
        "properties": {
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "image": {
            "type": "string",
            "description": "Container Image to run in the Pod"
          },
          "name": {
            "type": "string",
            "description": "Name of the Pod (Optional, random name if not provided)"
          },
          "namespace": {
            "type": "string",
            "description": "Namespace to run the Pod in"
          },
          "port": {
            "type": "number",
            "description": "TCP/IP port to expose from the Pod container (Optional, no port exposed if not provided)"
          }
        },
        "required": [
          "image"
        ]
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "pods_top",
      "description": "List the resource consumption (CPU and memory) as recorded by the Kubernetes Metrics Server for the specified Kubernetes Pods in the all namespaces, the provided namespace, or the current namespace",
      "input_schema": {
        "type": "object",
        "properties": {
          "all_namespaces": {
            "type": "boolean",
            "description": "If true, list the resource consumption for all Pods in all namespaces. If false, list the resource consumption for Pods in the provided namespace or the current namespace",
            "default": true
          },
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "label_selector": {
            "type": "string",
            "description": "Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label (Optional, only applicable when name is not provided)",
            "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]"
          },
          "name": {
            "type": "string",
            "description": "Name of the Pod to get the resource consumption from (Optional, all Pods in the namespace if not provided)"
          },
          "namespace": {
            "type": "string",
            "description": "Namespace to get the Pods resource consumption from (Optional, current namespace if not provided and all_namespaces is false)"
          }
        }
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "resources_create_or_update",
      "description": "Create or update a Kubernetes resource in the current cluster by providing a YAML or JSON representation of the resource\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
      "input_schema": {
        "type": "object",
        "properties": {
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "resource": {
            "type": "string",
            "description": "A JSON or YAML containing a representation of the Kubernetes resource. Should include top-level fields such as apiVersion,kind,metadata, and spec"
          }
        },
        "required": [
          "resource"
        ]
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "resources_delete",
      "description": "Delete a Kubernetes resource in the current cluster by providing its apiVersion, kind, optionally the namespace, and its name\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
      "input_schema": {
        "type": "object",
        "properties": {
          "apiVersion": {
            "type": "string",
            "description": "apiVersion of the resource (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)"
          },
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "kind": {
            "type": "string",
            "description": "kind of the resource (examples of valid kind are: Pod, Service, Deployment, Ingress)"
          },
          "name": {
            "type": "string",
            "description": "Name of the resource"
          },
          "namespace": {
            "type": "string",
            "description": "Optional Namespace to delete the namespaced resource from (ignored in case of cluster scoped resources). If not provided, will delete resource from configured namespace"
          }
        },
        "required": [
          "apiVersion",
          "kind",
          "name"
        ]
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "resources_get",
      "description": "Get a Kubernetes resource in the current cluster by providing its apiVersion, kind, optionally the namespace, and its name\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
      "input_schema": {
        "type": "object",
        "properties": {
          "apiVersion": {
            "type": "string",
            "description": "apiVersion of the resource (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)"
          },
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "kind": {
            "type": "string",
            "description": "kind of the resource (examples of valid kind are: Pod, Service, Deployment, Ingress)"
          },
          "name": {
            "type": "string",
            "description": "Name of the resource"
          },
          "namespace": {
            "type": "string",
            "description": "Optional Namespace to retrieve the namespaced resource from (ignored in case of cluster scoped resources). If not provided, will get resource from configured namespace"
          }
        },
        "required": [
          "apiVersion",
          "kind",
          "name"
        ]
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "resources_list",
      "description": "List Kubernetes resources and objects in the current cluster by providing their apiVersion and kind and optionally the namespace and label selector\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
      "input_schema": {
        "type": "object",
        "properties": {
          "apiVersion": {
            "type": "string",
            "description": "apiVersion of the resources (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)"
          },
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "fieldSelector": {
            "type": "string",
            "description": "Optional Kubernetes field selector to filter resources by field values (e.g. 'status.phase=Running', 'metadata.name=myresource'). Supported fields vary by resource type. For Pods: metadata.name, metadata.namespace, spec.nodeName, spec.restartPolicy, spec.schedulerName, spec.serviceAccountName, status.phase (Pending/Running/Succeeded/Failed/Unknown), status.podIP, status.nominatedNodeName. See https://kubernetes.io/docs/concepts/overview/working-with-objects/field-selectors/",
            "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]"
          },
          "kind": {
            "type": "string",
            "description": "kind of the resources (examples of valid kind are: Pod, Service, Deployment, Ingress)"
          },
          "labelSelector": {
            "type": "string",
            "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the resources by label",
            "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]"
          },
          "namespace": {
            "type": "string",
            "description": "Optional Namespace to retrieve the namespaced resources from (ignored in case of cluster scoped resources). If not provided, will list resources from all namespaces"
          }
        },
        "required": [
          "apiVersion",
          "kind"
        ]
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    },
    {
      "toolgroup_id": null,
      "name": "resources_scale",
      "description": "Get or update the scale of a Kubernetes resource in the current cluster by providing its apiVersion, kind, name, and optionally the namespace. If the scale is set in the tool call, the scale will be updated to that value. Always returns the current scale of the resource",
      "input_schema": {
        "type": "object",
        "properties": {
          "apiVersion": {
            "type": "string",
            "description": "apiVersion of the resource (examples of valid apiVersion are apps/v1)"
          },
          "context": {
            "type": "string",
            "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
            "enum": [
              "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
              "kind-kind"
            ]
          },
          "kind": {
            "type": "string",
            "description": "kind of the resource (examples of valid kind are: StatefulSet, Deployment)"
          },
          "name": {
            "type": "string",
            "description": "Name of the resource"
          },
          "namespace": {
            "type": "string",
            "description": "Optional Namespace to get/update the namespaced resource scale from (ignored in case of cluster scoped resources). If not provided, will get/update resource scale from configured namespace"
          },
          "scale": {
            "type": "integer",
            "description": "Optional scale to update the resources scale to. If not provided, will return the current scale of the resource, and not update it"
          }
        },
        "required": [
          "apiVersion",
          "kind",
          "name"
        ]
      },
      "output_schema": null,
      "metadata": {
        "endpoint": "http://localhost:8080/mcp"
      }
    }
  ]
}

---

4. Get specific tool from connector
GET v1alpha/connectors/kubernetes/tools/namespaces_list

{
  "toolgroup_id": null,
  "name": "namespaces_list",
  "description": "List all the Kubernetes namespaces in the current cluster",
  "input_schema": {
    "type": "object",
    "properties": {
      "context": {
        "type": "string",
        "description": "Optional parameter selecting which context to run the tool in. Defaults to kind-kind if not set",
        "enum": [
          "default/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
          "jrao/api-agentic-mcp-i6a3-p3-openshiftapps-com:443/cluster-admin",
          "kind-kind"
        ]
      }
    }
  },
  "output_schema": null,
  "metadata": {
    "endpoint": "http://localhost:8080/mcp"
  }
}

---

5. Get connector with Authorization header
(For OAuth-protected MCP servers)

curl -X GET 'http://localhost:8321/v1alpha/connectors/kubernetes' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <your-oauth-token>'

---

========================================
API Endpoints Summary
========================================

Readonly Connectors API endpoints:

  GET /v1alpha/connectors
      List all configured connectors

  GET /v1alpha/connectors/{connector_id}
      Get a specific connector (fetches live server info)

  GET /v1alpha/connectors/{connector_id}/tools
      List all tools available from a connector

  GET /v1alpha/connectors/{connector_id}/tools/{tool_name}
      Get a specific tool definition from a connector

Note: Connectors are configured via the stack config file.
      There are no POST/PUT/DELETE endpoints - connectors are
      managed declaratively through configuration.

Usage:
  ./demo_connectors_api.sh [connector_id] [tool_name]

Environment variables:
  LLAMA_STACK_URL - Base URL (default: http://localhost:8321)

Signed-off-by: Jaideep Rao <jrao@redhat.com>
Comment on lines +134 to +135
if not connector_json:
continue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to log anything here? Or are we unconcerned if there is no connector json?

Comment on lines +44 to +45
async def keys_in_range(self, start_key, end_key):
return [k for k in storage.keys() if start_key <= k < end_key]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice change

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants