~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/asyncai

0
0
main
179 lines · 7.4 KB Raw History
//! Tool descriptions (each with a code-mode example) and MCP output schemas
//! shared by the read-only and read-write kcp servers.

use std::sync::Arc;

use rmcp::model::JsonObject;
use serde_json::{json, Value};

pub const LIST_KCPS: &str = "Discover running socialweb-computer kcp servers. Other tools use the only running kcp when `kcp` is omitted.\nExample: [k[\"id\"] for k in (await list_kcps())[\"kcps\"] if k[\"running\"]]";
pub const LIST_WORKSPACES: &str = "List the workspace tree of one kcp.\nExample: [w[\"path\"] for w in (await list_workspaces())[\"workspaces\"]]";
pub const GET_API_RESOURCES: &str = "List the API resources served in one workspace.\nExample: [r[\"kind\"] for r in (await get_api_resources(workspace=\"root:app\"))[\"resources\"] if r[\"api_version\"].startswith(\"socialweb.computer/\")]";
pub const LIST_OBJECTS: &str = "List objects of one resource in a workspace (kubectl get -o json).\nExample: names(await list_objects(workspace=\"root:app\", resource=\"configmaps\", all_namespaces=True))";
pub const GET_OBJECT: &str = "Get one object (kubectl get -o json).\nExample: dig(await get_object(workspace=\"root:app\", resource=\"configmaps\", name=\"x\", namespace=\"default\"), \"data\")";
pub const GET_LOGS: &str = "Read pod logs. Returns plain text.\nExample: (await get_logs(workspace=\"root:app\", pod=\"web-1\", tail_lines=50)).splitlines()[-5:]";
pub const GET_EVENTS: &str = "List events in a workspace (kubectl get events -o json).\nExample: count_by(await get_events(workspace=\"root:app\"), \"type\")";
pub const READONLY_CREDENTIALS: &str = "Ensure the read-only ServiceAccount, ClusterRole, and ClusterRoleBinding exist, then mint a short-lived token for one workspace. All other read tools use the minted token. Reports the token kubeconfig path and lifetime, never the token.\nExample: (await readonly_credentials(workspace=\"root:app\"))[\"token_expires_in_seconds\"]";
pub const APPLY_OBJECT: &str = "Server-side apply one Kubernetes object to a workspace. Mutates the cluster unless dry_run is set.\nExample: await apply_object(workspace=\"root:app\", manifest={\"apiVersion\": \"v1\", \"kind\": \"ConfigMap\", \"metadata\": {\"name\": \"x\", \"namespace\": \"default\"}, \"data\": {\"k\": \"v\"}})";
pub const DELETE_OBJECT: &str = "Delete one object from a workspace. Mutates the cluster. Returns the deleted name as text.\nExample: await delete_object(workspace=\"root:app\", resource=\"configmaps\", name=\"x\", namespace=\"default\")";
pub const PATCH_OBJECT: &str = "Patch one object in a workspace (merge patch by default). Mutates the cluster.\nExample: await patch_object(workspace=\"root:app\", resource=\"configmaps\", name=\"x\", namespace=\"default\", patch={\"data\": {\"k\": \"v2\"}})";
pub const SCALE_OBJECT: &str = "Scale one object in a workspace. Mutates the cluster.\nExample: await scale_object(workspace=\"root:app\", resource=\"deployments\", name=\"web\", namespace=\"default\", replicas=2)";

fn schema(value: Value) -> Arc<JsonObject> {
    match value {
        Value::Object(object) => Arc::new(object),
        _ => unreachable!("schemas are objects"),
    }
}

fn string() -> Value {
    json!({"type": "string"})
}

fn kube_object_value() -> Value {
    json!({
        "type": "object",
        "properties": {
            "apiVersion": string(),
            "kind": string(),
            "metadata": {
                "type": "object",
                "properties": {
                    "name": string(),
                    "namespace": string(),
                    "labels": {"type": "object"},
                    "annotations": {"type": "object"},
                    "uid": string(),
                    "resourceVersion": string(),
                    "creationTimestamp": string(),
                },
            },
            "spec": {"type": "object"},
            "status": {"type": "object"},
            "data": {"type": "object"},
        },
    })
}

/// One Kubernetes object.
pub fn kube_object() -> Arc<JsonObject> {
    schema(kube_object_value())
}

/// A Kubernetes `List`.
pub fn kube_list() -> Arc<JsonObject> {
    schema(json!({
        "type": "object",
        "properties": {
            "apiVersion": string(),
            "kind": string(),
            "items": {"type": "array", "items": kube_object_value()},
        },
    }))
}

/// A list of core/v1 Events.
pub fn event_list() -> Arc<JsonObject> {
    schema(json!({
        "type": "object",
        "properties": {
            "items": {"type": "array", "items": {
                "type": "object",
                "properties": {
                    "type": string(),
                    "reason": string(),
                    "message": string(),
                    "count": {"type": "integer"},
                    "lastTimestamp": string(),
                    "involvedObject": {"type": "object", "properties": {
                        "kind": string(),
                        "name": string(),
                        "namespace": string(),
                    }},
                },
            }},
        },
    }))
}

pub fn kcp_report() -> Arc<JsonObject> {
    schema(json!({
        "type": "object",
        "properties": {
            "kcps": {"type": "array", "items": {
                "type": "object",
                "properties": {
                    "id": string(),
                    "host": string(),
                    "kubeconfig": string(),
                    "server": string(),
                    "workspace": string(),
                    "context": string(),
                    "running": {"type": "boolean"},
                    "error": {"type": ["string", "null"]},
                },
                "additionalProperties": false,
            }},
            "errors": {"type": "array", "items": string()},
        },
        "additionalProperties": false,
    }))
}

pub fn workspaces() -> Arc<JsonObject> {
    schema(json!({
        "type": "object",
        "properties": {
            "workspaces": {"type": "array", "items": {
                "type": "object",
                "properties": {
                    "name": string(),
                    "path": string(),
                    "url": string(),
                    "phase": string(),
                    "kind": string(),
                },
                "additionalProperties": false,
            }},
        },
        "additionalProperties": false,
    }))
}

pub fn api_resources() -> Arc<JsonObject> {
    let strings = json!({"type": "array", "items": string()});
    schema(json!({
        "type": "object",
        "properties": {
            "resources": {"type": "array", "items": {
                "type": "object",
                "properties": {
                    "name": string(),
                    "short_names": strings,
                    "api_version": string(),
                    "namespaced": {"type": "boolean"},
                    "kind": string(),
                    "verbs": strings,
                    "categories": strings,
                },
                "additionalProperties": false,
            }},
        },
        "additionalProperties": false,
    }))
}

pub fn credential() -> Arc<JsonObject> {
    schema(json!({
        "type": "object",
        "properties": {
            "kcp": string(),
            "host": string(),
            "workspace": string(),
            "token_kubeconfig": string(),
            "token_expires_in_seconds": {"type": "integer"},
            "note": string(),
        },
        "additionalProperties": false,
    }))
}