Documentation
¶
Overview ¶
Package workitems implements MCP tools for GitLab work item operations exposed through issue workflows.
The package wraps GitLab Work items GraphQL fields:
Index ¶
- func ActionSpecs(client *gitlabclient.Client) []toolutil.ActionSpec
- func Delete(ctx context.Context, client *gitlabclient.Client, input DeleteInput) error
- func FormatGetMarkdown(out GetOutput) *mcp.CallToolResult
- func FormatListMarkdown(out ListOutput) *mcp.CallToolResult
- func FormatWorkItemTypeListMarkdown(out WorkItemTypeListOutput) *mcp.CallToolResult
- type ChildItem
- type CreateInput
- type CreateLinkedItems
- type DeleteInput
- type GetInput
- type GetOutput
- type LinkedItem
- type ListInput
- type ListOutput
- type ListWorkItemTypesInput
- type UpdateInput
- type WorkItemItem
- type WorkItemTypeListOutput
- type WorkItemTypeOutput
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 work item actions exposed through gitlab_issue.
func Delete ¶
func Delete(ctx context.Context, client *gitlabclient.Client, input DeleteInput) error
Delete permanently removes a work item by IID.
func FormatGetMarkdown ¶
func FormatGetMarkdown(out GetOutput) *mcp.CallToolResult
FormatGetMarkdown formats a single work item as markdown.
func FormatListMarkdown ¶
func FormatListMarkdown(out ListOutput) *mcp.CallToolResult
FormatListMarkdown formats a list of work items as markdown.
The empty result carries its own hint because GitLab answers a namespace that does not exist, or that the token cannot see, with a null namespace rather than an error: the list handler cannot tell that apart from a namespace with no matching work items, so the reader is told to check the path.
func FormatWorkItemTypeListMarkdown ¶
func FormatWorkItemTypeListMarkdown(out WorkItemTypeListOutput) *mcp.CallToolResult
FormatWorkItemTypeListMarkdown formats a list of work item types as a Markdown table.
Types ¶
type ChildItem ¶
type ChildItem struct {
IID int64 `json:"iid" jsonschema:"Internal ID (IID) of the child work item"`
Path string `json:"path,omitempty" jsonschema:"Namespace full path of the child work item"`
}
ChildItem is a summary reference to a child work item in the hierarchy.
type CreateInput ¶
type CreateInput struct {
FullPath string `json:"full_path" jsonschema:"Full path of the project or group,required"`
WorkItemTypeID string `json:"work_item_type_id" jsonschema:"Global ID of work item type (e.g. gid://gitlab/WorkItems::Type/1 for Issue),required"`
Title string `json:"title" jsonschema:"Title of the work item,required"`
Description string `json:"description,omitempty" jsonschema:"Description of the work item"`
Confidential *bool `json:"confidential,omitempty" jsonschema:"Whether the work item is confidential"`
AssigneeIDs []int64 `json:"assignee_ids,omitempty" jsonschema:"Global IDs of assignees"`
MilestoneID *int64 `json:"milestone_id,omitempty" jsonschema:"Global ID of the milestone"`
LabelIDs []int64 `json:"label_ids,omitempty" jsonschema:"Global IDs of labels"`
CRMContactIDs []int64 `json:"crm_contact_ids,omitempty" jsonschema:"CRM contact IDs to attach to the new work item"`
ParentID *int64 `` /* 170-byte string literal not displayed */
IterationID *int64 `json:"iteration_id,omitempty" tier:"premium" jsonschema:"Global ID of the iteration"`
Weight *int64 `json:"weight,omitempty" tier:"premium" jsonschema:"Weight of the work item"`
HealthStatus string `json:"health_status,omitempty" tier:"ultimate" jsonschema:"Health status (onTrack/needsAttention/atRisk)"`
Color string `json:"color,omitempty" tier:"premium" jsonschema:"Color hex code (e.g. #fefefe)"`
Status string `json:"status,omitempty" tier:"premium" jsonschema:"Work item status: TODO, IN_PROGRESS, DONE, WONT_DO, or DUPLICATE"`
DueDate string `json:"due_date,omitempty" jsonschema:"Due date (YYYY-MM-DD)"`
StartDate string `json:"start_date,omitempty" jsonschema:"Start date (YYYY-MM-DD)"`
CreatedAt string `` /* 205-byte string literal not displayed */
CreateSource string `` /* 146-byte string literal not displayed */
LinkedItems *CreateLinkedItems `json:"linked_items,omitempty" jsonschema:"Linked work items to add on creation"`
}
CreateInput is the input for creating a work item.
type CreateLinkedItems ¶
type CreateLinkedItems struct {
WorkItemIDs []int64 `json:"work_item_ids" jsonschema:"Global IDs of work items to link,required"`
LinkType string `json:"link_type" jsonschema:"Link type: BLOCKS, BLOCKED_BY, or RELATED,required"`
}
CreateLinkedItems specifies work items to link during creation.
type DeleteInput ¶
type DeleteInput struct {
FullPath string `json:"full_path" jsonschema:"Full path of the project or group (e.g. my-group/my-project),required"`
IID int64 `json:"work_item_iid" jsonschema:"Work item IID,required"`
}
DeleteInput is the input for deleting a work item.
type GetInput ¶
type GetInput struct {
FullPath string `json:"full_path" jsonschema:"Full path of the project or group (e.g. my-group/my-project),required"`
IID int64 `json:"work_item_iid" jsonschema:"Work item IID,required"`
}
GetInput is the input for getting a single work item.
type GetOutput ¶
type GetOutput struct {
toolutil.HintableOutput
WorkItem WorkItemItem `json:"work_item"`
}
GetOutput is the output for getting a single work item.
func Create ¶
func Create(ctx context.Context, client *gitlabclient.Client, input CreateInput) (GetOutput, error)
Create creates a new work item.
func Update ¶
func Update(ctx context.Context, client *gitlabclient.Client, input UpdateInput) (GetOutput, error)
Update modifies an existing work item.
type LinkedItem ¶
type LinkedItem struct {
IID int64 `json:"iid"`
LinkType string `json:"link_type"`
Path string `json:"path,omitempty"`
}
LinkedItem represents a linked work item summary.
type ListInput ¶
type ListInput struct {
FullPath string `json:"full_path" jsonschema:"Full path of the project or group,required"`
State string `json:"state,omitempty" jsonschema:"Filter by state (opened/closed/all)"`
Search string `json:"search,omitempty" jsonschema:"Search in title and description"`
In []string `` /* 134-byte string literal not displayed */
Types []string `json:"types,omitempty" jsonschema:"Filter by work item types, IssueType enum values such as ISSUE or TASK"`
AuthorUsername string `json:"author_username,omitempty" jsonschema:"Filter by author username"`
AssigneeUsernames []string `json:"assignee_usernames,omitempty" jsonschema:"Filter by assignee usernames"`
AssigneeWildcardID string `json:"assignee_wildcard_id,omitempty" jsonschema:"Assignee wildcard filter: ANY, ME or NONE"`
MyReactionEmoji string `json:"my_reaction_emoji,omitempty" jsonschema:"Filter by the emoji the authenticated user reacted with"`
Subscribed string `` /* 138-byte string literal not displayed */
// GitLab types both arguments String and compares the value against a
// numeric column without parsing it, so a gid:// form casts to 0 and
// silently matches nothing.
CRMContactID string `json:"crm_contact_id,omitempty" jsonschema:"Filter by CRM contact numeric ID as a string, e.g. 1. Not a global ID"`
CRMOrganizationID string `json:"crm_organization_id,omitempty" jsonschema:"Filter by CRM organization numeric ID as a string, e.g. 1. Not a global ID"`
// The two identifier filters are deliberately different shapes because
// GitLab types them differently: ids takes full global IDs and iids takes
// the numbers shown in the UI, as strings.
IDs []string `json:"ids,omitempty" jsonschema:"Filter by work item global IDs, each the full gid://gitlab/WorkItem/<id> form"`
IIDs []string `json:"iids,omitempty" jsonschema:"Filter by work item internal IDs (IIDs) as strings, e.g. 12"`
ParentIDs []string `` /* 157-byte string literal not displayed */
LabelName []string `json:"label_name,omitempty" jsonschema:"Filter by label names"`
MilestoneTitle []string `` /* 130-byte string literal not displayed */
MilestoneWildcardID string `json:"milestone_wildcard_id,omitempty" jsonschema:"Milestone wildcard filter: ANY, NONE, STARTED or UPCOMING"`
ReleaseTag []string `json:"release_tag,omitempty" jsonschema:"Filter by release tags"`
ReleaseTagWildcardID string `json:"release_tag_wildcard_id,omitempty" jsonschema:"Release tag wildcard filter: ANY or NONE"`
IterationID []string `` /* 250-byte string literal not displayed */
IterationCadenceID []string `` /* 162-byte string literal not displayed */
IterationWildcardID string `json:"iteration_wildcard_id,omitempty" tier:"premium" jsonschema:"Iteration wildcard filter: ANY, CURRENT or NONE"`
Weight string `` /* 148-byte string literal not displayed */
WeightWildcardID string `json:"weight_wildcard_id,omitempty" tier:"premium" jsonschema:"Weight wildcard filter: ANY or NONE"`
HealthStatusFilter string `` /* 152-byte string literal not displayed */
ClosedAfter string `` /* 173-byte string literal not displayed */
ClosedBefore string `` /* 175-byte string literal not displayed */
CreatedAfter string `` /* 175-byte string literal not displayed */
CreatedBefore string `` /* 177-byte string literal not displayed */
DueAfter string `` /* 167-byte string literal not displayed */
DueBefore string `` /* 169-byte string literal not displayed */
UpdatedAfter string `` /* 175-byte string literal not displayed */
UpdatedBefore string `` /* 177-byte string literal not displayed */
Confidential *bool `json:"confidential,omitempty" jsonschema:"Filter by confidentiality"`
Sort string `json:"sort,omitempty" jsonschema:"Sort order, a WorkItemSort enum value such as CREATED_DESC or TITLE_ASC"`
IncludeAncestors *bool `json:"include_ancestors,omitempty" jsonschema:"Include ancestor work items"`
IncludeDescendants *bool `json:"include_descendants,omitempty" jsonschema:"Include descendant work items"`
// ReturnedFields selects the GraphQL fragment, not the result set: it
// decides which fields of each matching work item come back, and no work
// item is included or excluded by it. Naming a subset makes a listing
// smaller and cheaper; naming none asks for the per-tier default set.
ReturnedFields []string `` /* 501-byte string literal not displayed */
toolutil.GraphQLCursorPaginationInput
}
ListInput is the input for listing work items.
The cursor parameters come from the shared type because this connection is one GitLab really does page in both directions: the SDK's own document declares first, after, last and before, and the output reports a previous page and a start cursor. Publishing only the forward half named a cursor no parameter here could spend.
type ListOutput ¶
type ListOutput struct {
toolutil.HintableOutput
WorkItems []WorkItemItem `json:"work_items"`
Pagination toolutil.GraphQLPaginationOutput `json:"pagination"`
}
ListOutput is the output for listing work items.
func List ¶
func List(ctx context.Context, client *gitlabclient.Client, input ListInput) (ListOutput, error)
List retrieves work items for a project or group.
The SDK's CE-safe default field set is a superset of the query this handler used to send: assignees, labels and linked items come back on every listed item instead of only on Get. The five Enterprise-only widgets are asked for on top of it when the instance can answer them: see [listReturnedFields].
type ListWorkItemTypesInput ¶
type ListWorkItemTypesInput struct {
FullPath string `json:"full_path" jsonschema:"Project or group full path (namespace path),required"`
Name string `json:"name,omitempty" jsonschema:"Filter by work item type name, an IssueType enum value such as ISSUE or TASK"`
OnlyAvailable bool `json:"only_available,omitempty" jsonschema:"Return only available work item types"`
toolutil.GraphQLCursorPaginationInput
}
ListWorkItemTypesInput defines parameters for listing work item types.
The cursor parameters come from the shared type so that this connection, which the SDK query pages in both directions, answers a backward request the way every other cursor-paginated list here does.
type UpdateInput ¶
type UpdateInput struct {
FullPath string `json:"full_path" jsonschema:"Full path of the project or group (e.g. my-group/my-project),required"`
IID int64 `json:"work_item_iid" jsonschema:"Work item IID,required"`
Title string `json:"title,omitempty" jsonschema:"New title"`
StateEvent string `json:"state_event,omitempty" jsonschema:"State event: CLOSE or REOPEN"`
Description string `json:"description,omitempty" jsonschema:"New description"`
AssigneeIDs []int64 `` /* 192-byte string literal not displayed */
MilestoneID *int64 `json:"milestone_id,omitempty" jsonschema:"Global ID of the milestone"`
CRMContactIDs []int64 `` /* 184-byte string literal not displayed */
ParentID *int64 `json:"parent_id,omitempty" jsonschema:"Global ID of the parent work item"`
AddLabelIDs []int64 `json:"add_label_ids,omitempty" jsonschema:"Global IDs of labels to add"`
RemoveLabelIDs []int64 `json:"remove_label_ids,omitempty" jsonschema:"Global IDs of labels to remove"`
StartDate string `json:"start_date,omitempty" jsonschema:"Start date (YYYY-MM-DD)"`
DueDate string `json:"due_date,omitempty" jsonschema:"Due date (YYYY-MM-DD)"`
Weight *int64 `json:"weight,omitempty" tier:"premium" jsonschema:"Weight of the work item"`
HealthStatus string `json:"health_status,omitempty" tier:"ultimate" jsonschema:"Health status (onTrack/needsAttention/atRisk)"`
IterationID *int64 `json:"iteration_id,omitempty" tier:"premium" jsonschema:"Global ID of the iteration"`
Color string `json:"color,omitempty" tier:"premium" jsonschema:"Color hex code (e.g. #fefefe)"`
Status string `json:"status,omitempty" tier:"premium" jsonschema:"Work item status: TODO, IN_PROGRESS, DONE, WONT_DO, or DUPLICATE"`
// Confirm is declared so the input schema advertises the reserved confirm
// key and strict validation accepts it. Its value is never populated:
// toolutil strips reserved keys before unmarshalling, so the handler reads
// the caller's confirmation from the raw request instead.
Confirm bool `` /* 199-byte string literal not displayed */
}
UpdateInput is the input for updating a work item.
type WorkItemItem ¶
type WorkItemItem struct {
ID int64 `json:"id"`
IID int64 `json:"iid"`
Type string `json:"type"`
State string `json:"state"`
Status string `json:"status,omitempty" tier:"premium" jsonschema:"Name of the work item status in the namespace's lifecycle"`
Title string `json:"title"`
Description string `json:"description,omitempty"`
WebURL string `json:"web_url,omitempty"`
Author *toolutil.BasicUserOutput `json:"author,omitempty" jsonschema:"User who created the work item"`
Assignees []*toolutil.BasicUserOutput `json:"assignees,omitempty" jsonschema:"Users assigned to the work item"`
Labels []*toolutil.LabelDetailsOutput `` /* 127-byte string literal not displayed */
LinkedItems []LinkedItem `json:"linked_items,omitempty"`
Parent *ChildItem `json:"parent,omitempty" jsonschema:"Parent work item in the hierarchy (namespace path and IID)"`
Children []ChildItem `json:"children,omitempty" jsonschema:"Child work items in the hierarchy (each with namespace path and IID)"`
Color string `json:"color,omitempty" tier:"premium" jsonschema:"Color of the work item as a hex code (e.g. #fefefe)"`
MilestoneID int64 `json:"milestone_id,omitempty" jsonschema:"Numeric ID of the milestone the work item belongs to"`
IterationID int64 `json:"iteration_id,omitempty" tier:"premium" jsonschema:"Numeric ID of the iteration the work item belongs to"`
Weight *int64 `json:"weight,omitempty" tier:"premium" jsonschema:"Weight of the work item"`
HealthStatus string `json:"health_status,omitempty" tier:"ultimate" jsonschema:"Health status (onTrack/needsAttention/atRisk)"`
StartDate string `json:"start_date,omitempty" jsonschema:"Start date (YYYY-MM-DD)"`
DueDate string `json:"due_date,omitempty" jsonschema:"Due date (YYYY-MM-DD)"`
Confidential bool `json:"confidential,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
ClosedAt string `json:"closed_at,omitempty"`
}
WorkItemItem is a summary of a work item.
The widget-backed fields below (color, dates, health status, iteration, milestone, parent, status, weight) arrive on every get, create and update, because the static fragment client-go uses for those three selects them unconditionally. On the list path they arrive only when the query asked for them: see [listReturnedFields].
Author, assignees and labels carry the whole object client-go carries rather than a name, because the fragment already pays for the whole object: the UserCoreBasic fragment fetches id, username, name, state, avatarUrl, webUrl and createdAt, and the labels fragment fetches id, title, color, description, descriptionHtml and textColor. Publishing the name alone threw away every other field the request had already spent. The Markdown formatter still prints names, which is what a reader of the rendered text wants.
Status and color are tagged Premium for the reason the list path already gated them: client-go groups both with health status, iteration and weight as fields that exist only in the Enterprise schema, and GitLab documents work item status at "Tier: Premium, Ultimate" (https://docs.gitlab.com/user/work_items/status/) and the epic the color widget belongs to at the same pair (https://docs.gitlab.com/user/group/epics/manage_epics/), both read on 2026-09-07. Until now the two were advertised to every tier while being asked for only on Enterprise instances.
type WorkItemTypeListOutput ¶
type WorkItemTypeListOutput struct {
toolutil.HintableOutput
Types []WorkItemTypeOutput `json:"types"`
Pagination toolutil.GraphQLPaginationOutput `json:"pagination"`
}
WorkItemTypeListOutput holds a list of work item types.
func ListWorkItemTypes ¶
func ListWorkItemTypes(ctx context.Context, client *gitlabclient.Client, input ListWorkItemTypesInput) (WorkItemTypeListOutput, error)
ListWorkItemTypes lists work item types (system-defined and custom) for a namespace.
type WorkItemTypeOutput ¶
type WorkItemTypeOutput struct {
ID string `json:"id"`
Name string `json:"name"`
Enabled bool `json:"enabled"`
}
WorkItemTypeOutput represents a work item type.