API: Add parent-child task relationships and kelos-mcp-server for agent-initiated task spawning
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 331
- Forks
- 40
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 70
Description
Summary
Enable agents to dynamically create child tasks at runtime, transforming them from passive task executors into active orchestrators. This unlocks recursive problem decomposition, dynamic parallelism, and agent-to-agent delegation — capabilities that static pipelines (dependsOn, taskTemplates) cannot provide.
Problem
Today, all task orchestration in Kelos is statically defined at template time:
dependsOncreates fixed DAG pipelines (#710 proposestaskTemplatesfor static multi-step)TaskSpawnerdiscovers external items and creates one task per item- An agent that encounters a complex issue has no way to say "this needs 3 separate changes — let me delegate subtasks and aggregate results"
Real-world scenarios requiring dynamic task creation:
- Issue decomposition: A planning agent reads a complex issue, breaks it into 3 focused subtasks (API change, frontend update, test addition), spawns each as a child task, then creates a coordinating PR
- Multi-repo changes: An agent discovers that fixing a bug requires updating a shared library AND two consumer services — spawns child tasks per repo
- Exploratory parallelism: An agent needs to evaluate 3 competing approaches — spawns parallel child tasks and picks the best result
- Recursive delegation: An architect agent designs a system, spawns implementation tasks per component, each of which may spawn test-writing subtasks
None of the existing proposals address this:
- #710 (
taskTemplatesplural) — static, template-defined multi-step; the pipeline shape is fixed at TaskSpawner creation time - #747 (conditional dependencies) — static branching based on results; still pre-defined in the template
- #749 (
onCompletionhooks) — outbound notifications, not task creation - #792 (
historyContext) — injects past results into prompts, doesn't enable creating new tasks
Proposal
1. API changes to TaskSpec and TaskStatus
Add parentRef to TaskSpec so child tasks track their lineage:
type TaskSpec struct {
// ... existing fields ...
// ParentRef references the Task that spawned this child task.
// Set automatically by the kelos-mcp-server when an agent creates
// a child task. Enables parent-child relationship tracking and
// lifecycle management (e.g., cancelling children when parent fails).
// +optional
ParentRef *TaskReference `json:"parentRef,omitempty"`
}
type TaskReference struct {
// Name is the name of the referenced Task.
Name string `json:"name"`
}
Add childTasks to TaskStatus for observability:
type TaskStatus struct {
// ... existing fields ...
// ChildTasks lists tasks that were spawned by this task's agent
// via the kelos-mcp-server. Updated by the controller when child
// tasks with a matching parentRef are created.
// +optional
ChildTasks []ChildTaskStatus `json:"childTasks,omitempty"`
}
type ChildTaskStatus struct {
// Name of the child Task.
Name string `json:"name"`
// Phase of the child Task.
Phase TaskPhase `json:"phase,omitempty"`
}
2. kelos-mcp-server binary
A new MCP server that wraps the Kelos Kubernetes API, giving agents native tool access for task management. It runs as a stdio MCP server inside the agent pod.
Tools exposed:
| Tool | Description |
|---|---|
create_child_task |
Create a new Task with parentRef set to the current task. Accepts: prompt, branch (optional), model (optional). Inherits workspace, credentials, and agentConfig from parent. |
list_child_tasks |
List child tasks of the current task with their phases and results. |
get_task_status |
Get the status of a specific task by name (phase, results, outputs). |
wait_for_tasks |
Poll until specified tasks reach a terminal phase. Returns aggregated results. |
Implementation:
- Written in Go, ships as a binary in agent images (or as a sidecar)
- Uses in-cluster Kubernetes client (via ServiceAccount token) to create/read Task resources
- Reads
KELOS_TASK_NAMEandKELOS_TASK_NAMESPACEenv vars (injected by JobBuilder) to setparentRef - Child tasks inherit
workspaceRef,credentials,agentConfigReffrom the parent task unless overridden
Example MCP config in AgentConfig:
apiVersion: kelos.dev/v1alpha1
kind: AgentConfig
metadata:
name: orchestrator-agent
spec:
mcpServers:
- name: kelos
type: stdio
command: kelos-mcp-server
# No args needed — reads config from KELOS_* env vars
3. RBAC automation
When a Task has an AgentConfig with a kelos MCP server configured, the JobBuilder should:
- Create a Role granting
create,get,list,watchontasks.kelos.devin the task's namespace - Create a RoleBinding linking the task pod's ServiceAccount to this Role
- Clean up via ownerReferences when the Task is deleted
Alternatively, users can pre-create a ServiceAccount with appropriate permissions and reference it via podOverrides.serviceAccountName.
4. Controller enhancements
- Child task tracking: When a Task with
parentRefis created, update the parent'sstatus.childTasks - Lifecycle propagation (optional, future): When a parent task fails/is deleted, optionally cancel running children (controlled by a
childPolicyfield) - CLI integration:
kelos get taskscould show parent-child relationships in a tree view
Example: Dynamic issue decomposition
# AgentConfig for a planning agent that can spawn subtasks
apiVersion: kelos.dev/v1alpha1
kind: AgentConfig
metadata:
name: planner-with-delegation
spec:
agentsMD: |
You are a planning agent. For complex issues:
1. Analyze the issue and break it into focused subtasks
2. Use the `create_child_task` MCP tool to spawn a task for each subtask
3. Use `wait_for_tasks` to wait for all subtasks to complete
4. Aggregate results and create a coordinating PR or summary comment
mcpServers:
- name: kelos
type: stdio
command: kelos-mcp-server
An agent receiving a complex issue like "Migrate API from v1 to v2" could then:
Agent thinks: This requires changes to 3 packages. Let me delegate.
→ create_child_task(prompt="Update pkg/api/v1 to v2 types", branch="migrate-api-types")
→ create_child_task(prompt="Update pkg/handlers to use v2 API", branch="migrate-handlers")
→ create_child_task(prompt="Update test fixtures for v2 API", branch="migrate-tests")
→ wait_for_tasks(["migrate-api-types-task", "migrate-handlers-task", "migrate-tests-task"])
All succeeded → create coordinating PR that merges all branches
Why MCP server (not just kubectl/kelos CLI)?
- Agent-native: MCP tools appear as structured tools in the agent's tool palette — the agent can reason about parameters, get structured responses, and handle errors naturally
- Safe by default: The MCP server validates inputs, enforces parentRef, and limits scope to the task's namespace
- Portable: Works across all agent types (Claude Code, Codex, Gemini, Cursor) since Kelos already has MCP injection for all of them
- Declarative: No shell commands or YAML templating — the agent just calls
create_child_taskwith a prompt
Backward compatibility
parentRefandchildTasksare optional fields — existing Tasks are unaffected- The kelos-mcp-server is opt-in via AgentConfig
- No changes to existing TaskSpawner behavior
- The RBAC automation only activates when the MCP server is configured
Incremental adoption path
- Phase 1: Add
parentRefto TaskSpec andchildTasksto TaskStatus (API-only, no behavior change) - Phase 2: Build kelos-mcp-server with
create_child_taskandget_task_status - Phase 3: Add
wait_for_tasksand controller-side child tracking - Phase 4: Lifecycle propagation (cancel children on parent failure) and CLI tree view
/kind feature
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the TaskSpec and TaskStatus API definitions, then trace JobBuilder, controller reconciliation, and existing MCP injection. Review the proposed phases and Kubernetes RBAC behavior before deciding on an incremental scope. Done means the selected phase has implementation, API or controller coverage, and validation for parent-child task creation and status handling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, kubernetes
- Domain
- api, backend, cloud, infrastructure
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100