Documentation
¶
Overview ¶
Package pipelines implements MCP tools for GitLab pipeline operations.
It supports listing, retrieving, creating, canceling, retrying, deleting, and waiting for pipelines. The wait tool polls server-side and emits MCP progress notifications while a pipeline moves toward a terminal state. The package wraps the GitLab Pipelines service from client-go v2 and provides Markdown rendering for pipeline responses.
Runtime Behavior ¶
Wait operations respect context cancellation and keep long-running polling visible through MCP progress notifications. Mutating operations are annotated through ActionSpecs so read-only, safe mode, and destructive confirmation behavior stay consistent across individual, meta, and dynamic surfaces.
The latest pipeline of a ref is GitLab's answer for the commit at its head, and GitLab answers 403 both when that commit has no pipeline and when the caller may not read pipelines. GetLatest answers the first from the pipeline list of the same ref, saying beside the pipeline that it ran for an earlier commit, and lets the list's own refusal report the second.
GitLab API References ¶
The package wraps the GitLab Pipelines API:
Index ¶
- func ActionSpecs(client *gitlabclient.Client) []toolutil.ActionSpec
- func Delete(ctx context.Context, client *gitlabclient.Client, input DeleteInput) error
- func DeleteOutput(ctx context.Context, client *gitlabclient.Client, input DeleteInput) (toolutil.DeleteOutput, error)
- func FormatDetailMarkdown(p DetailOutput) string
- func FormatLatestMarkdown(out LatestOutput) string
- func FormatListMarkdown(out ListOutput) string
- func FormatTestReportMarkdown(out TestReportOutput) string
- func FormatTestReportSummaryMarkdown(out TestReportSummaryOutput) string
- func FormatVariablesMarkdown(out VariablesOutput) string
- func FormatWaitMarkdown(out WaitOutput) string
- type ActionInput
- type CreateInput
- type DeleteInput
- type DetailOutput
- func Cancel(ctx context.Context, client *gitlabclient.Client, input ActionInput) (DetailOutput, error)
- func Create(ctx context.Context, client *gitlabclient.Client, input CreateInput) (DetailOutput, error)
- func DetailToOutput(p *gl.Pipeline, extra toolutil.PipelineExtra) DetailOutput
- func Get(ctx context.Context, client *gitlabclient.Client, input GetInput) (DetailOutput, error)
- func Retry(ctx context.Context, client *gitlabclient.Client, input ActionInput) (DetailOutput, error)
- func UpdateMetadata(ctx context.Context, client *gitlabclient.Client, input UpdateMetadataInput) (DetailOutput, error)
- type GetInput
- type GetLatestInput
- type IllustrationOutput
- type LatestOutput
- type ListInput
- type ListOutput
- type Output
- type StatusOutput
- type TestReportOutput
- type TestReportSummaryOutput
- type TestSuiteOutput
- type TestSuiteSummaryOutput
- type UpdateMetadataInput
- type VariableOptionInput
- type VariableOutput
- type VariablesOutput
- type WaitInput
- type WaitOutput
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ActionSpecs ¶
func ActionSpecs(client *gitlabclient.Client) []toolutil.ActionSpec
ActionSpecs returns canonical specs for CI/CD pipeline actions.
func Delete ¶
func Delete(ctx context.Context, client *gitlabclient.Client, input DeleteInput) error
Delete permanently deletes a pipeline and all its jobs.
func DeleteOutput ¶
func DeleteOutput(ctx context.Context, client *gitlabclient.Client, input DeleteInput) (toolutil.DeleteOutput, error)
DeleteOutput deletes a pipeline and returns the legacy success message shape.
func FormatDetailMarkdown ¶
func FormatDetailMarkdown(p DetailOutput) string
FormatDetailMarkdown renders one pipeline as the card of a single object.
func FormatLatestMarkdown ¶ added in v3.2.0
func FormatLatestMarkdown(out LatestOutput) string
FormatLatestMarkdown renders the answer of pipeline.latest as the card of its pipeline. When the pipeline is the one the list fell back to, the head commit of the ref is written beside the pipeline's own and the note saying why after the rows, so a reader never takes it for GitLab's latest.
func FormatListMarkdown ¶
func FormatListMarkdown(out ListOutput) string
FormatListMarkdown renders a page of pipelines as a Markdown table: a collection of objects that share columns.
The heading counts what the response can vouch for rather than Pagination.TotalItems alone, which keyset pagination never sends: "Pipelines (0)" above a table of rows was what a reader saw on every keyset page.
func FormatTestReportMarkdown ¶
func FormatTestReportMarkdown(out TestReportOutput) string
FormatTestReportMarkdown renders a pipeline's test report as the card of one object: the totals as rows, the suites as the nested collection they are.
The report carries no individual test case, so the hints name the jobs and their logs rather than promising per-test detail this rendering cannot show.
func FormatTestReportSummaryMarkdown ¶
func FormatTestReportSummaryMarkdown(out TestReportSummaryOutput) string
FormatTestReportSummaryMarkdown renders a pipeline's test report summary as the card of one object.
The full report shows the same per-suite totals and no test cases, so the hint says that rather than offering "full test details".
func FormatVariablesMarkdown ¶
func FormatVariablesMarkdown(out VariablesOutput) string
FormatVariablesMarkdown renders a pipeline's variables as a Markdown table.
func FormatWaitMarkdown ¶
func FormatWaitMarkdown(out WaitOutput) string
FormatWaitMarkdown renders the wait result as the card of the pipeline that was waited for: the wait's own rows, then the pipeline's fields under one H3, and one guidance section at the end.
The pipeline used to be embedded by calling FormatDetailMarkdown, which wrote a second H2 under the H3 and a guidance section in the middle of the response, where ExtractHints never looked.
Types ¶
type ActionInput ¶
type ActionInput struct {
ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
PipelineID int64 `json:"pipeline_id" jsonschema:"Pipeline ID to act on,required"`
}
ActionInput defines parameters for pipeline cancel/retry actions.
type CreateInput ¶
type CreateInput struct {
ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
Ref string `json:"ref" jsonschema:"Branch or tag name to run the pipeline for"`
Variables []VariableOptionInput `json:"variables,omitempty" jsonschema:"Pipeline variables to set"`
Inputs map[string]any `` /* 203-byte string literal not displayed */
}
CreateInput defines parameters for creating a new pipeline.
type DeleteInput ¶
type DeleteInput struct {
ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
PipelineID int64 `json:"pipeline_id" jsonschema:"Pipeline ID to delete,required"`
}
DeleteInput defines parameters for deleting a pipeline.
type DetailOutput ¶
type DetailOutput struct {
toolutil.HintableOutput
ID int64 `json:"id"`
IID int64 `json:"iid"`
ProjectID int64 `json:"project_id"`
Status string `json:"status"`
Source string `json:"source"`
Ref string `json:"ref"`
SHA string `json:"sha"`
BeforeSHA string `json:"before_sha,omitempty"`
Name string `json:"name,omitempty"`
Tag bool `json:"tag"`
Archived bool `json:"archived"`
YamlErrors string `json:"yaml_errors,omitempty"`
Duration int64 `json:"duration"`
QueuedDuration int64 `json:"queued_duration"`
Coverage string `json:"coverage,omitempty"`
User *toolutil.BasicUserOutput `json:"user,omitempty"`
DetailedStatus *StatusOutput `json:"detailed_status,omitempty"`
WebURL string `json:"web_url"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
StartedAt string `json:"started_at,omitempty"`
FinishedAt string `json:"finished_at,omitempty"`
CommittedAt string `json:"committed_at,omitempty"`
}
DetailOutput represents a single pipeline with full details: what gl.Pipeline decodes, plus whether it is archived, which lib/api/entities/ci/pipeline.rb sends on every pipeline rendered whole and the SDK does not carry, read from the captured response (ADR-0021).
Name is omitted when empty: the single GET, the latest pipeline and the metadata update present PipelineWithMetadata, which sends it, while creation, cancellation and retry present Pipeline, which does not.
func Cancel ¶
func Cancel(ctx context.Context, client *gitlabclient.Client, input ActionInput) (DetailOutput, error)
Cancel cancels a running pipeline's jobs.
func Create ¶
func Create(ctx context.Context, client *gitlabclient.Client, input CreateInput) (DetailOutput, error)
Create creates a new pipeline for the given ref with optional variables.
func DetailToOutput ¶
func DetailToOutput(p *gl.Pipeline, extra toolutil.PipelineExtra) DetailOutput
DetailToOutput converts a GitLab API gl.Pipeline to MCP output, and takes the field the capture read beside the SDK.
func Get ¶
func Get(ctx context.Context, client *gitlabclient.Client, input GetInput) (DetailOutput, error)
Get retrieves a single pipeline by ID from a GitLab project.
func Retry ¶
func Retry(ctx context.Context, client *gitlabclient.Client, input ActionInput) (DetailOutput, error)
Retry retries failed jobs in a pipeline.
func UpdateMetadata ¶
func UpdateMetadata(ctx context.Context, client *gitlabclient.Client, input UpdateMetadataInput) (DetailOutput, error)
UpdateMetadata updates the metadata (name) of a pipeline.
type GetInput ¶
type GetInput struct {
ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
PipelineID int64 `json:"pipeline_id" jsonschema:"Pipeline ID to retrieve,required"`
}
GetInput defines parameters for retrieving a single pipeline.
type GetLatestInput ¶
type GetLatestInput struct {
ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
Ref string `` /* 135-byte string literal not displayed */
Scope string `` /* 135-byte string literal not displayed */
Status string `` /* 207-byte string literal not displayed */
Source string `` /* 314-byte string literal not displayed */
SHA string `json:"sha,omitempty" jsonschema:"Filter by commit SHA. Applies to the list fallback."`
Name string `json:"name,omitempty" jsonschema:"Filter by pipeline name. Applies to the list fallback."`
Username string `json:"username,omitempty" jsonschema:"Filter by username that triggered the pipeline. Applies to the list fallback."`
YamlErrors bool `json:"yaml_errors,omitempty" jsonschema:"Return only pipelines with YAML errors. Applies to the list fallback."`
OrderBy string `` /* 128-byte string literal not displayed */
Sort string `json:"sort,omitempty" jsonschema:"Sort direction (asc, desc). Applies to the list fallback."`
CreatedAfter string `` /* 128-byte string literal not displayed */
CreatedBefore string `` /* 130-byte string literal not displayed */
UpdatedAfter string `` /* 128-byte string literal not displayed */
UpdatedBefore string `` /* 130-byte string literal not displayed */
toolutil.PaginationInput
toolutil.KeysetPaginationInput
}
GetLatestInput defines parameters for getting the latest pipeline.
GET /projects/:id/pipelines/latest takes ref alone. The filters below mirror gl.ListProjectPipelinesOptions and apply only to the list that answers when that route has no pipeline for the head of the ref, see GetLatest; GitLab's own answer is never filtered.
type IllustrationOutput ¶
type IllustrationOutput struct {
Image string `json:"image,omitempty"`
}
IllustrationOutput mirrors gl.DetailedStatusIllustration (the optional status illustration embedded in detailed_status).
type LatestOutput ¶ added in v3.2.0
type LatestOutput struct {
DetailOutput
HeadSHA string `` /* 184-byte string literal not displayed */
FallbackNote string `` /* 131-byte string literal not displayed */
}
LatestOutput is what pipeline.latest answers: the pipeline in full, and, when it is not GitLab's latest pipeline of the ref but the one the list fell back to, what tells the two apart.
HeadSHA and FallbackNote are this server's own and no route sends them. Both are empty when GitLab answered the latest route itself, and when the pipeline the list returned did run for the commit at the head.
func GetLatest ¶
func GetLatest(ctx context.Context, client *gitlabclient.Client, input GetLatestInput) (LatestOutput, error)
GetLatest retrieves the latest pipeline of a ref, the project's default branch when no ref is given: the newest pipeline GitLab has for the commit at the head of that ref, which is what Project#latest_pipeline returns.
GitLab answers that route 403 for two reasons it does not tell apart. The route authorizes read_pipeline on the pipeline it found, and when the head commit has none it found nil and authorizing nil fails, which pipelines.md documents ("If no pipeline exists for the commit, a 403 status code is returned"): a push still being processed, or a commit workflow:rules kept from creating one. A caller who may not read the project's pipelines gets the same 403. A plain 403 is therefore answered from the pipeline list of the same ref, see [getLatestFallback], whose own refusal is the one that says it was the second. A 403 carrying an OAuth error code refuses the token itself and is neither, so it is reported as it came.
type ListInput ¶
type ListInput struct {
ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
Scope string `json:"scope,omitempty" jsonschema:"Filter by scope (running, pending, finished, branches, tags)"`
Status string `` /* 176-byte string literal not displayed */
Source string `` /* 283-byte string literal not displayed */
Ref string `json:"ref,omitempty" jsonschema:"Filter by branch or tag name"`
SHA string `json:"sha,omitempty" jsonschema:"Filter by commit SHA"`
Name string `json:"name,omitempty" jsonschema:"Filter by pipeline name"`
Username string `json:"username,omitempty" jsonschema:"Filter by username that triggered the pipeline"`
YamlErrors bool `json:"yaml_errors,omitempty" jsonschema:"Return only pipelines with YAML errors"`
OrderBy string `json:"order_by,omitempty" jsonschema:"Order by field (id, status, ref, updated_at, user_id)"`
Sort string `json:"sort,omitempty" jsonschema:"Sort direction (asc, desc)"`
CreatedAfter string `json:"created_after,omitempty" jsonschema:"Return pipelines created after date (ISO 8601 format, e.g. 2025-01-01T00:00:00Z)"`
CreatedBefore string `` /* 126-byte string literal not displayed */
UpdatedAfter string `json:"updated_after,omitempty" jsonschema:"Return pipelines updated after date (ISO 8601 format, e.g. 2025-01-01T00:00:00Z)"`
UpdatedBefore string `` /* 126-byte string literal not displayed */
toolutil.PaginationInput
toolutil.KeysetPaginationInput
}
ListInput defines parameters for listing pipelines in a GitLab project.
type ListOutput ¶
type ListOutput struct {
toolutil.HintableOutput
Pipelines []Output `json:"pipelines"`
Pagination toolutil.PaginationOutput `json:"pagination"`
}
ListOutput holds a paginated list of pipelines.
func List ¶
func List(ctx context.Context, client *gitlabclient.Client, input ListInput) (ListOutput, error)
List retrieves a paginated list of pipelines for a GitLab project. Supports filtering by scope, status, source, ref, SHA, username, and date ranges.
type Output ¶
type Output struct {
toolutil.HintableOutput
ID int64 `json:"id"`
IID int64 `json:"iid"`
ProjectID int64 `json:"project_id"`
Status string `json:"status"`
Source string `json:"source"`
Ref string `json:"ref"`
SHA string `json:"sha"`
Name string `json:"name,omitempty"`
WebURL string `json:"web_url"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
BeforeSHA string `json:"before_sha,omitempty"`
Tag bool `json:"tag,omitempty"`
YamlErrors string `json:"yaml_errors,omitempty"`
User *toolutil.UserBasicOutput `json:"user,omitempty"`
StartedAt string `json:"started_at,omitempty"`
FinishedAt string `json:"finished_at,omitempty"`
CommittedAt string `json:"committed_at,omitempty"`
Duration int64 `json:"duration,omitempty"`
QueuedDuration int64 `json:"queued_duration,omitempty"`
Coverage string `json:"coverage,omitempty"`
DetailedStatus *StatusOutput `json:"detailed_status,omitempty"`
Archived bool `json:"archived,omitempty"`
}
Output represents a single pipeline in the list response.
The block after the SDK's own fields is what `API::Entities::Ci::Pipeline` adds to the basic entity and client-go's PipelineInfo declares on no field, read from the captured response (ADR-0021) and described on [infoExtra]. The two pipeline lists present the basic entity and send none of them; the merge request pipeline creation presents the full one and sends all twelve, so each is omitted when the route that filled this type did not send it.
Name is omitted on the same terms: the project list presents PipelineBasicWithMetadata, which adds it, while the merge request list and the merge request pipeline creation present PipelineBasic and Pipeline, which do not.
func CapturedOutput ¶ added in v3.1.0
func CapturedOutput(op string, p *gl.PipelineInfo, captured *gitlabclient.ResponseCapture) (Output, error)
CapturedOutput converts one pipeline together with the keys its captured answer carries beside the SDK's decode, or reports the answer the type cannot hold.
It is exported because the route that sends them is not in this package: `POST /projects/:id/merge_requests/:iid/pipelines` is served by internal/tools/mergerequests and answers with this package's type.
func ToOutput ¶
func ToOutput(p *gl.PipelineInfo) Output
ToOutput converts a GitLab API gl.PipelineInfo to MCP output format.
It is what the two pipeline lists use, whose entity sends nothing beyond what the SDK models. A route presenting the full pipeline entity goes through CapturedOutput instead.
type StatusOutput ¶
type StatusOutput struct {
Icon string `json:"icon"`
Text string `json:"text"`
Label string `json:"label"`
Group string `json:"group"`
Tooltip string `json:"tooltip"`
HasDetails bool `json:"has_details"`
DetailsPath string `json:"details_path,omitempty"`
Illustration *IllustrationOutput `json:"illustration,omitempty"`
Favicon string `json:"favicon,omitempty"`
}
StatusOutput mirrors gl.DetailedStatus (the pipeline detailed_status object).
type TestReportOutput ¶
type TestReportOutput struct {
toolutil.HintableOutput
TotalTime float64 `json:"total_time"`
TotalCount int64 `json:"total_count"`
SuccessCount int64 `json:"success_count"`
FailedCount int64 `json:"failed_count"`
SkippedCount int64 `json:"skipped_count"`
ErrorCount int64 `json:"error_count"`
TestSuites []TestSuiteOutput `json:"test_suites"`
}
TestReportOutput represents a pipeline test report.
func GetTestReport ¶
func GetTestReport(ctx context.Context, client *gitlabclient.Client, input GetInput) (TestReportOutput, error)
GetTestReport retrieves the test report for a specific pipeline.
type TestReportSummaryOutput ¶
type TestReportSummaryOutput struct {
toolutil.HintableOutput
TotalTime float64 `json:"total_time"`
TotalCount int64 `json:"total_count"`
SuccessCount int64 `json:"success_count"`
FailedCount int64 `json:"failed_count"`
SkippedCount int64 `json:"skipped_count"`
ErrorCount int64 `json:"error_count"`
TestSuites []TestSuiteSummaryOutput `json:"test_suites"`
}
TestReportSummaryOutput represents a pipeline test report summary.
func GetTestReportSummary ¶
func GetTestReportSummary(ctx context.Context, client *gitlabclient.Client, input GetInput) (TestReportSummaryOutput, error)
GetTestReportSummary retrieves the test report summary for a specific pipeline.
type TestSuiteOutput ¶
type TestSuiteOutput struct {
Name string `json:"name"`
TotalTime float64 `json:"total_time"`
TotalCount int64 `json:"total_count"`
SuccessCount int64 `json:"success_count"`
FailedCount int64 `json:"failed_count"`
SkippedCount int64 `json:"skipped_count"`
ErrorCount int64 `json:"error_count"`
}
TestSuiteOutput represents a test suite within a test report.
type TestSuiteSummaryOutput ¶
type TestSuiteSummaryOutput struct {
Name string `json:"name"`
TotalTime float64 `json:"total_time"`
TotalCount int64 `json:"total_count"`
SuccessCount int64 `json:"success_count"`
FailedCount int64 `json:"failed_count"`
SkippedCount int64 `json:"skipped_count"`
ErrorCount int64 `json:"error_count"`
BuildIDs []int64 `json:"build_ids"`
}
TestSuiteSummaryOutput represents a test suite summary.
type UpdateMetadataInput ¶
type UpdateMetadataInput struct {
ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
PipelineID int64 `json:"pipeline_id" jsonschema:"Pipeline ID to update,required"`
Name string `json:"name" jsonschema:"New pipeline name,required"`
}
UpdateMetadataInput defines parameters for updating pipeline metadata.
type VariableOptionInput ¶
type VariableOptionInput struct {
Key string `json:"key" jsonschema:"Variable key,required"`
Value string `json:"value" jsonschema:"Variable value"`
VariableType string `json:"variable_type,omitempty" jsonschema:"Variable type (env_var or file, default: env_var)"`
}
VariableOptionInput represents a variable to pass when creating a pipeline.
type VariableOutput ¶
type VariableOutput struct {
Key string `json:"key"`
Value string `json:"value"`
VariableType string `json:"variable_type"`
Raw *bool `json:"raw,omitempty"`
}
VariableOutput represents a single pipeline variable: every key lib/api/entities/ci/variable.rb sends for a Ci::PipelineVariable. Raw says whether GitLab leaves variable references in the value unexpanded; the entity sends it because the model has a raw column, and client-go's PipelineVariable has no field for it, so it is read off the captured response (ADR-0021). The entity's hidden, protected, masked, environment_scope and description wait on the presented object responding to them, which a pipeline variable does not, so GitLab never sends them here. Raw is a pointer, omitted when the answer carried no raw key, so that it says what GitLab said and nothing it did not; a pipeline schedule's variables publish it under the same rule.
type VariablesOutput ¶
type VariablesOutput struct {
toolutil.HintableOutput
Variables []VariableOutput `json:"variables"`
}
VariablesOutput holds a list of pipeline variables.
func GetVariables ¶
func GetVariables(ctx context.Context, client *gitlabclient.Client, input GetInput) (VariablesOutput, error)
GetVariables retrieves the variables for a specific pipeline.
type WaitInput ¶
type WaitInput struct {
ProjectID toolutil.StringOrInt `json:"project_id" jsonschema:"Project ID or URL-encoded path,required"`
PipelineID int64 `json:"pipeline_id" jsonschema:"Pipeline ID to wait for,required"`
IntervalSeconds int `json:"interval_seconds,omitempty" jsonschema:"Polling interval in seconds (5-60, default 10)"`
TimeoutSeconds int `json:"timeout_seconds,omitempty" jsonschema:"Maximum wait time in seconds (1-3600, default 300)"`
FailOnError *bool `json:"fail_on_error,omitempty" jsonschema:"Return isError when pipeline ends in failed/canceled status (default true)"`
}
WaitInput defines parameters for waiting on a pipeline to complete.
type WaitOutput ¶
type WaitOutput struct {
toolutil.HintableOutput
Pipeline DetailOutput `json:"pipeline"`
WaitedFor string `json:"waited_for"`
PollCount int `json:"poll_count"`
FinalStatus string `json:"final_status"`
TimedOut bool `json:"timed_out"`
}
WaitOutput holds the result of waiting for a pipeline.
func Wait ¶
func Wait(ctx context.Context, req *mcp.CallToolRequest, client *gitlabclient.Client, input WaitInput) (WaitOutput, error)
Wait polls a pipeline until it reaches a terminal state or the timeout is reached. It sends MCP progress notifications to keep the client informed during polling.