mcpField
O
openchoreo-developer

openchoreo-developer

github.com/openchoreoCloud & DevOps453 installsUpdated 2w ago
Repository

About openchoreo-developer

A developer skill for deploying and operating services on OpenChoreo through its control-plane MCP server. It guides agents through platform discovery, task-specific references, application lifecycle operations, and runtime inspection.

Key features

  1. 01OpenChoreo application lifecycle guidance
  2. 02MCP-based platform discovery
  3. 03Deployment and promotion procedures
  4. 04Workload and dependency configuration
  5. 05Runtime inspection and debugging

Use cases

  1. 01Creating and configuring Components
  2. 02Deploying or promoting services across environments
  3. 03Investigating workload status and logs

MCP support

Uses the `openchoreo-cp` control-plane MCP server for OpenChoreo operations and live platform discovery.

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/openchoreo/skills --skill openchoreo-developer

After installing, type/openchoreo-developerin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

assets/
workload-descriptor.yaml
references/
concepts.md
getting-started.md
references/recipes/
build-from-source.md
configure-workload.md
connect-components.md
deploy-and-promote.md
deploy-prebuilt-image.md
inspect-and-debug.md
manage-secrets.md
override-per-environment.md
use-a-resource.md

Details

From the project README

OpenChoreo Developer Guide

Help an application developer ship and operate a service on OpenChoreo through the control-plane MCP server. Discover the live platform shape via MCP; read detailed references only when the task needs them.

Step 0 — Confirm MCP connectivity

Run list_namespaces. If the tool isn't reachable, tell the user the openchoreo-cp MCP server needs configuring per https://openchoreo.dev/docs/ai/mcp-servers/ and stop.

Step 1 — Load concepts (MANDATORY)

Read ./references/concepts.md in full before anything else. Not optional, even if the task looks simple — you'll get these wrong from memory. Load once per session; if you catch yourself acting without it, stop and load now.

Then load the matching reference for the task:

Step 2 — Load the PE skill for platform tasks

If the request touches ProjectType / ComponentType / ResourceType / Trait / Workflow (or cluster variants) or anything under What this skill cannot do, also load ../openchoreo-platform-engineer/SKILL.md. If the PE skill isn't installed, escalate.

What this skill can do

  • Projects — create, update. create_project takes an optional type_name / type_kind / parameters referencing a PE-authored (Cluster)ProjectType; omitted, it defaults to the default ProjectType. A project's cell must be deployed per environment before its components can be → see Deploy the project cell in deploy-and-promote.md.
  • Components — create, update, patch_component for auto_deploy / parameters / traits / workflow / metadata.
  • Workloads — image, ports, endpoints, env vars, files → configure-workload.md
  • Attach Traits — pick from the platform's catalog → configure-workload.md
  • Connect components — endpoint dependencies; platform injects env vars → connect-components.md
  • Consume Resources — managed-infrastructure dependencies (databases, queues, caches); platform injects outputs as env vars and file mounts via dependencies.resources[] → use-a-resource.md
  • SecretReferences — CRUD + secretKeyRef consumption → manage-secrets.md. The ClusterSecretStore is PE-owned.
  • Deploy and promote — deploy the project cell per env (create_project_release_binding, pin seeded by the controller), then bind a ComponentRelease to an Environment and promote both along the DeploymentPipeline → deploy-and-promote.md
  • Per-environment overrides — replicas, resources, env vars, trait config on the ReleaseBinding → override-per-environment.md
  • Soft-undeploy / rollback — update_release_binding release_state: Undeploy, or rebind to a prior ComponentRelease.
  • Hard-delete developer resources — delete_component, delete_workload, delete_release_binding, delete_project, delete_component_release. Destructive; confirm first. No delete_namespace — PE-side.
  • Inspect runtime — Component / ReleaseBinding status.conditions[] and status.endpoints[]; get_resource_tree to map a binding to its rendered K8s resources; get_resource_events / get_resource_logs for pod-level evidence; WorkflowRun logs and events → inspect-and-debug.md
  • Discover platform resources (read-only) — ProjectTypes, ComponentTypes, ResourceTypes, Traits, Workflows, Environments, DeploymentPipelines, planes.

What this skill cannot do

Platform-side work: authoring ProjectTypes / ComponentTypes / ResourceTypes / Traits / Workflows, Environments, DeploymentPipelines, planes, authorization, gateway / secret-store / IdP config, observability setup, longer-horizon log / metric / trace queries (pod-level events and current logs are covered via get_resource_events / get_resource_logs).

Load ../openchoreo-platform-engineer/SKILL.md if it's installed; otherwise tell the user to escalate to a platform engineer. PE scope catalog: https://openchoreo.dev/docs/platform-engineer-guide/.

Tool surface

One MCP server: openchoreo-cp. Throughout this skill, tools are referenced by bare name (e.g. get_component); your agent wraps with its prefix (Claude Code uses mcp__openchoreo-cp__<tool>).

ComponentType / ResourceType / Trait / Workflow and the plane tools are scope-collapsed: one tool with a scope arg — "namespace" (default) or "cluster" for the platform-wide Cluster* resource. This skill always uses the canonical name + scope. The old *_cluster_* names still exist as deprecated aliases (banner in v1.1, hidden in v1.2, removed in v1.3) and can be used alternatively against a v1.1 server — but prefer the canonical form.

The resource toolset (dev-facing, enabled by default) covers Resource CRUD plus scope-collapsed reads on (Cluster)ResourceType. ResourceReleaseBinding and ProjectReleaseBinding CRUD both sit in the deployment toolset alongside ReleaseBinding. The resource_release_binding create/update calls are how a Resource gets deployed into an env (or promoted); project_release_binding create/update are the same for a project's cell. (Cluster)ProjectType is read-only here (list_project_types / get_project_type / get_project_type_schema, scope-aware) — authoring it is PE-side.

Working style

  • Live cluster output beats memory. Discover via MCP first; don't guess available ComponentTypes / Traits / Workflows / Environments / field names.
  • Schema-first authoring. get_workload_schema, or get_component_type_schema / get_trait_schema with scope: "cluster" for platform-wide standards, before writing a spec from scratch.

Stable guardrails

  • All work goes through the control-plane MCP server. If a task can't be done via MCP, it's platform-side — hand off.
  • Third-party / public apps: default to BYO image. Source builds commonly fail on third-party Dockerfiles using ARG BUILDPLATFORM (exit 125). Switch to BYO immediately if you see it.
  • Before deploying any third-party app: fetch the official manifests and extract every required env var — dependencies inject service addresses but not PORT, feature flags, or vendor SDK disable flags.
  • A handed-over migration plan is the spec. When the user supplies a migration/onboarding plan, take namespace, env var placement (static Workload env vs per-env workloadOverrides), and wiring decisions from it. Deviate only out loud — state what you're changing and why before acting, never silently substitute.
  • Author types to fit the app — never re-shape the app to fit shipped types. When the plan (or the app) needs a ComponentType / ResourceType / Trait that isn't installed or that ships but doesn't meet the requirement, the fix is to author it — load ../openchoreo-platform-engineer/SKILL.md and create a fit-for-purpose type. Do not work around the gap by: re-modeling a managed dependency as a plain Component because the shipped ResourceType doesn't fit (it's still a Resource — author a ResourceType that reproduces what the dependency needs); dropping a capability the app needs because no shipped Trait provides it (author the Trait); or forcing the workload onto a shipped ComponentType whose shape or defaults don't fit (author the ComponentType). Reuse a shipped type only when it genuinely meets the contract. The needs drive the types, not the reverse.
  • Set resources from the source, not the ComponentType's defaults. Use the workload's source-declared requests/limits (CPU and memory). If the source declares none, pick a plausible default for the workload class — never inherit a generic CT's defaults, which are typically demo-grade and under-provision. When you author the CT, bake sensible defaults into its environmentConfigs; otherwise set them via the ReleaseBinding's per-env config.
  • Injected connection values are literal — there is no $(VAR) interpolation. Dependency envBindings inject each connection value (address / host / port / basePath) as the literal env var you name; the platform does not expand shell/Kubernetes $(VAR) references inside other env values, so value: "http://$(HOST):$(PORT)" reaches the container verbatim. Bind the exact env var the app reads. If the app needs a composed string the injected vars don't directly provide (a full URI, a bare host:port with no scheme, a scheme prefix), set that composed value as a literal env var — typically a per-env workloadOverride using the resolved address — rather than referencing $(VAR).
  • A missing tool means version skew, not absence. When a documented MCP tool isn't found, check the server version against the cluster before concluding the surface doesn't exist — report the mismatch to the user, then fall back or escalate.

Anti-patterns

  • Skipping the recipe. Before any new operation (new CRD kind this turn, lifecycle action, runtime inspection) — re-scan the recipe index above, load the matching recipe (one Read call), THEN call MCP / kubectl. Skipping is how kubectl falls multiply and existing MCP tools get missed. Concept references aren't enough — recipes name the right tool calls in sequence.
  • Running every discovery call before checking the resource already implicated.
  • Writing specs from memory when get_*_schema / get_* can reveal the current shape.
  • Guessing deployed URLs instead of reading ReleaseBinding.status.endpoints[].
  • Treating a platform-side failure as an app-only problem after the evidence points elsewhere.
  • Creating source-build components for third-party apps that have pre-built images.
  • Setting visibility: external on a service-to-service dependency in the same project — project is the default.
  • Treating Ready=True as "working". Ready means reconciled, not functional. A crash-looping container can flap Ready, and a stable container can be Ready while misconfigured (env vars bound to wrong names, deps resolving to nowhere). Confirm with get_resource_tree → get_resource_events / get_resource_logs and an actual endpoint hit.

Comments

Markdown supported