Skip to content

feat(tekton): add Tekton toolset with pipeline and task management#892

Merged
nader-ziada merged 2 commits intocontainers:mainfrom
ksimon1:tekton-pipelines
Apr 7, 2026
Merged

feat(tekton): add Tekton toolset with pipeline and task management#892
nader-ziada merged 2 commits intocontainers:mainfrom
ksimon1:tekton-pipelines

Conversation

@ksimon1
Copy link
Copy Markdown
Contributor

@ksimon1 ksimon1 commented Mar 6, 2026

Summary

This PR introduces a new tekton toolset to kubernetes-mcp-server, exposing domain-specific Tekton operations that go beyond what the generic core toolset's resources_* tools provide. This functionality is required for new Kubevirt functionality.

Toolset (pkg/toolsets/tekton)

5 tools are exposed:

Tool Description
tekton_pipeline_start Start a Pipeline by creating a PipelineRun
tekton_pipelinerun_restart Restart a PipelineRun with the same spec
tekton_task_start Start a Task by creating a TaskRun
tekton_taskrun_restart Restart a TaskRun with the same spec
tekton_taskrun_logs Fetch logs from a TaskRun's underlying pod

The tekton_pipeline_start and tekton_task_start tools accept an optional params argument — a JSON object where values can be strings, arrays of strings, or objects (map of string to string), matching all three Tekton ParamType variants.

Generic CRUD operations (list, get, create, update, delete) for Tekton resources remain available via the core toolset's resources_* tools using apiVersion: tekton.dev/v1.

Eval tasks (evals/tasks/tekton)

9 declarative eval tasks validated against a live OpenShift cluster (9/9 passed, 27/27 assertions):

  • create-tekton-pipeline, create-tekton-task
  • get-tekton-pipeline, list-tekton-pipelines, list-tekton-pipelineruns
  • delete-tekton-pipelinerun, restart-tekton-pipelinerun
  • start-tekton-pipeline, start-tekton-task

Setup scripts handle a known OpenShift Pipelines quirk: the Tekton Results operator adds results.tekton.dev/taskrun finalizers to TaskRuns, which can block namespace termination between tasks. The scripts actively remove these finalizers to ensure clean teardown.

The tekton suite is registered in both claude-code and openai-agent eval configurations.

Test plan

  • Unit tests: go test ./pkg/toolsets/tekton/... — all pass
  • Snapshot tests: go test ./pkg/mcp/... — all pass
  • Eval tests: 9/9 tasks passed on a live OpenShift cluster with OpenShift Pipelines installed

@ksimon1
Copy link
Copy Markdown
Contributor Author

ksimon1 commented Mar 6, 2026

/hold Need reviews from tekton people

README.md Outdated
- **Uninstall** a Helm release in the current or provided namespace.
- **🔧 Tekton**: Tekton-specific operations that complement generic Kubernetes resource management.
- **Pipeline**: Start a Tekton Pipeline by creating a PipelineRun.
- **PipelineRun**: Restart a PipelineRun with the same spec, or bulk-delete PipelineRuns with selectors.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This PR does not have bulk-delete implemented, maybe a missed commit ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Many actions can be done with general tools which are already implemented in this MCP server. If you think we will need some special delete function, then we can add it 👍

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Maybe we can start here with an eval task to see if it is needed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@Cali0707 I created new PR #917

}

logs := ""
for _, step := range tr.Status.Steps {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

we should get logs for sidecars as well

README.md Outdated

<summary>tekton</summary>

> **Note**: Generic CRUD operations (list, get, create, update, delete) for Tekton resources (Pipeline, PipelineRun, Task, TaskRun) are available via the `core` toolset's `resources_list`, `resources_get`, `resources_create_or_update`, and `resources_delete` tools using `apiVersion: tekton.dev/v1`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

https://github.com/containers/kubernetes-mcp-server/blob/main/pkg/toolsets/core/resources.go#L115

don't think resources_delete supports bulk deletion using label selectors

"github.com/containers/kubernetes-mcp-server/pkg/toolsets/tekton"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

test should be grouped via testify/suite, like:

type TektonSuite struct {
	suite.Suite
}

@ksimon1
Copy link
Copy Markdown
Contributor Author

ksimon1 commented Mar 12, 2026

/hold #917 should be merged first

req := params.KubernetesClient.CoreV1().Pods(namespace).GetLogs(tr.Status.PodName, &corev1.PodLogOptions{
Container: step.Container,
})
stream, err := req.Stream(params.Context)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

io.ReadAll reads without bound. A chatty step could return hundreds of MB, hitting LLM context limits or OOMing the server.

Suggest capping per step:

const maxStepLogBytes = 1 << 20 // 1 MB per step
bytes, err := io.ReadAll(io.LimitReader(stream, maxStepLogBytes))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I didn't look at how it is done directly in the kubernetes mcp server though, but we could re-use code/way of doing.

@manusa
Copy link
Copy Markdown
Member

manusa commented Mar 18, 2026

#917 was merged, I think we need to rebase this one now.

@ksimon1
Copy link
Copy Markdown
Contributor Author

ksimon1 commented Mar 19, 2026

@manusa the PR is rebased

@ksimon1 ksimon1 force-pushed the tekton-pipelines branch 2 times, most recently from 8c4d0f2 to 55db285 Compare March 20, 2026 05:35
@manusa
Copy link
Copy Markdown
Member

manusa commented Mar 20, 2026

/run-mcpchecker tekton

@github-actions
Copy link
Copy Markdown
Contributor

mcpchecker MCP Evaluation Results

Commit: 55db285
Summary: 4/9 tasks passed (44.4%)

Metric Result
Tasks Passed 4/9
Assertions Passed 15/27
Overall ❌ Failed

View full results

@ksimon1
Copy link
Copy Markdown
Contributor Author

ksimon1 commented Mar 26, 2026

/run-mcpchecker tekton

1 similar comment
@manusa
Copy link
Copy Markdown
Member

manusa commented Mar 26, 2026

/run-mcpchecker tekton

@github-actions
Copy link
Copy Markdown
Contributor

mcpchecker MCP Evaluation Results

Commit: 55db285
Summary: 9/9 tasks passed (100.0%)

Metric Result
Tasks Passed 9/9
Assertions Passed 27/27
Overall ✅ Passed

View full results

req := params.CoreV1().Pods(namespace).GetLogs(podName, &corev1.PodLogOptions{
Container: container,
})
stream, err := req.Stream(params.Context)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The log stream should be closed with defer immediately after the error check:

stream, err := req.Stream(params.Context)
if err != nil {
    fmt.Fprintf(sb, "[%s: %s] error retrieving logs: %v\n", kind, name, err)
    return
}
defer stream.Close()

Currently stream.Close() is called manually after io.ReadAll (line 167), but if ReadAll panics the stream leaks. Using defer is the standard Go idiom and is safer.

Copy link
Copy Markdown
Member

@manusa manusa left a comment

Choose a reason for hiding this comment

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

Impressive results 🎉 ✅

I've added a few comments for your consideration

@waveywaves
Copy link
Copy Markdown

@ksimon1 can you check why the build is failing on this one ?

@ksimon1
Copy link
Copy Markdown
Contributor Author

ksimon1 commented Apr 2, 2026

@manusa, @Cali0707, @waveywaves, @vdemeester can you please review this PR?

Copy link
Copy Markdown
Member

@manusa manusa left a comment

Choose a reason for hiding this comment

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

LGTM, thx!

@manusa manusa added this to the 0.1.0 milestone Apr 2, 2026
@manusa manusa requested review from Cali0707 and nader-ziada April 2, 2026 13:55
Copy link
Copy Markdown
Collaborator

@nader-ziada nader-ziada left a comment

Choose a reason for hiding this comment

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

@ksimon1 great work, but one small comment:

When adding a new toolset, you also need to update internal/tools/update-readme/main.go to include the import:

_ "github.com/containers/kubernetes-mcp-server/pkg/toolsets/tekton"

so you can then run make update-readme-tools to regenerate the toolsets tables in README.md and docs/configuration.md.

ksimon1 added 2 commits April 7, 2026 09:51
the new tekton tool set will require its packages.
This commit add the tekton pipelines package

Code was assisted by Cursor AI.

Signed-off-by: Karel Simon <ksimon@redhat.com>
Introduces a new `tekton` toolset exposing 5 domain-specific tools:
- tekton_pipeline_start: start a Pipeline (with optional typed params)
- tekton_pipelinerun_restart: restart an existing PipelineRun
- tekton_task_start: start a Task (with optional typed params)
- tekton_taskrun_restart: restart an existing TaskRun
- tekton_taskrun_logs: fetch logs from a TaskRun's underlying pod

Generic CRUD operations for Tekton resources remain available via
the core toolset's resources_* tools. The params argument on start
tools supports string, array, and object Tekton parameter types.

Includes unit tests, snapshot tests, and README documentation.

Code was assisted by Cursor AI.

Signed-off-by: Karel Simon <ksimon@redhat.com>
@ksimon1 ksimon1 force-pushed the tekton-pipelines branch from f012e51 to 24a48c1 Compare April 7, 2026 08:15
@ksimon1
Copy link
Copy Markdown
Contributor Author

ksimon1 commented Apr 7, 2026

@nader-ziada it should be fixed now

@nader-ziada
Copy link
Copy Markdown
Collaborator

@nader-ziada it should be fixed now

thanks @ksimon1

LGTM

@nader-ziada nader-ziada merged commit 39442fb into containers:main Apr 7, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants