Add list_group_projects tool

- Implemented `list_group_projects` function to list all projects in a GitLab group with various filtering options.
- Updated package dependencies, including `@modelcontextprotocol/sdk` to version 1.8.0 and `zod` to version 3.24.2.
This commit is contained in:
Thomas
2025-03-29 20:08:27 +01:00
parent 422eb8a4bc
commit 6b8d40bea2
7 changed files with 1183 additions and 40 deletions

View File

@ -9,7 +9,7 @@ import { fileURLToPath } from "url";
import { dirname } from "path";
import fs from "fs";
import path from "path";
import { GitLabForkSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabIssueSchema, GitLabMergeRequestSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabSearchResponseSchema, GitLabTreeSchema, GitLabCommitSchema, GitLabNamespaceSchema, GitLabNamespaceExistsResponseSchema, GitLabProjectSchema, CreateOrUpdateFileSchema, SearchRepositoriesSchema, CreateRepositorySchema, GetFileContentsSchema, PushFilesSchema, CreateIssueSchema, CreateMergeRequestSchema, ForkRepositorySchema, CreateBranchSchema, GitLabMergeRequestDiffSchema, GetMergeRequestSchema, GetMergeRequestDiffsSchema, UpdateMergeRequestSchema, ListIssuesSchema, GetIssueSchema, UpdateIssueSchema, DeleteIssueSchema, GitLabIssueLinkSchema, GitLabIssueWithLinkDetailsSchema, ListIssueLinksSchema, GetIssueLinkSchema, CreateIssueLinkSchema, DeleteIssueLinkSchema, ListNamespacesSchema, GetNamespaceSchema, VerifyNamespaceSchema, GetProjectSchema, ListProjectsSchema, ListLabelsSchema, GetLabelSchema, CreateLabelSchema, UpdateLabelSchema, DeleteLabelSchema, CreateNoteSchema, } from "./schemas.js";
import { GitLabForkSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabIssueSchema, GitLabMergeRequestSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabSearchResponseSchema, GitLabTreeSchema, GitLabCommitSchema, GitLabNamespaceSchema, GitLabNamespaceExistsResponseSchema, GitLabProjectSchema, CreateOrUpdateFileSchema, SearchRepositoriesSchema, CreateRepositorySchema, GetFileContentsSchema, PushFilesSchema, CreateIssueSchema, CreateMergeRequestSchema, ForkRepositorySchema, CreateBranchSchema, GitLabMergeRequestDiffSchema, GetMergeRequestSchema, GetMergeRequestDiffsSchema, UpdateMergeRequestSchema, ListIssuesSchema, GetIssueSchema, UpdateIssueSchema, DeleteIssueSchema, GitLabIssueLinkSchema, GitLabIssueWithLinkDetailsSchema, ListIssueLinksSchema, GetIssueLinkSchema, CreateIssueLinkSchema, DeleteIssueLinkSchema, ListNamespacesSchema, GetNamespaceSchema, VerifyNamespaceSchema, GetProjectSchema, ListProjectsSchema, ListLabelsSchema, GetLabelSchema, CreateLabelSchema, UpdateLabelSchema, DeleteLabelSchema, CreateNoteSchema, ListGroupProjectsSchema, } from "./schemas.js";
/**
* Read version from package.json
*/
@ -960,6 +960,55 @@ async function deleteLabel(projectId, labelId) {
// Handle errors
await handleGitLabError(response);
}
/**
* List all projects in a GitLab group
*
* @param {z.infer<typeof ListGroupProjectsSchema>} options - Options for listing group projects
* @returns {Promise<GitLabProject[]>} Array of projects in the group
*/
async function listGroupProjects(options) {
const url = new URL(`${GITLAB_API_URL}/groups/${encodeURIComponent(options.group_id)}/projects`);
// Add optional parameters to URL
if (options.include_subgroups)
url.searchParams.append('include_subgroups', 'true');
if (options.search)
url.searchParams.append('search', options.search);
if (options.order_by)
url.searchParams.append('order_by', options.order_by);
if (options.sort)
url.searchParams.append('sort', options.sort);
if (options.page)
url.searchParams.append('page', options.page.toString());
if (options.per_page)
url.searchParams.append('per_page', options.per_page.toString());
if (options.archived !== undefined)
url.searchParams.append('archived', options.archived.toString());
if (options.visibility)
url.searchParams.append('visibility', options.visibility);
if (options.with_issues_enabled !== undefined)
url.searchParams.append('with_issues_enabled', options.with_issues_enabled.toString());
if (options.with_merge_requests_enabled !== undefined)
url.searchParams.append('with_merge_requests_enabled', options.with_merge_requests_enabled.toString());
if (options.min_access_level !== undefined)
url.searchParams.append('min_access_level', options.min_access_level.toString());
if (options.with_programming_language)
url.searchParams.append('with_programming_language', options.with_programming_language);
if (options.starred !== undefined)
url.searchParams.append('starred', options.starred.toString());
if (options.statistics !== undefined)
url.searchParams.append('statistics', options.statistics.toString());
if (options.with_custom_attributes !== undefined)
url.searchParams.append('with_custom_attributes', options.with_custom_attributes.toString());
if (options.with_security_reports !== undefined)
url.searchParams.append('with_security_reports', options.with_security_reports.toString());
const response = await fetch(url.toString(), {
method: "GET",
headers: DEFAULT_HEADERS,
});
await handleGitLabError(response);
const projects = await response.json();
return GitLabProjectSchema.array().parse(projects);
}
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
@ -1118,6 +1167,11 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
description: "Delete a label from a project",
inputSchema: zodToJsonSchema(DeleteLabelSchema),
},
{
name: "list_group_projects",
description: "List projects in a GitLab group with filtering options",
inputSchema: zodToJsonSchema(ListGroupProjectsSchema),
},
],
};
});
@ -1414,6 +1468,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
content: [{ type: "text", text: JSON.stringify({ status: "success", message: "Label deleted successfully" }, null, 2) }],
};
}
case "list_group_projects": {
const args = ListGroupProjectsSchema.parse(request.params.arguments);
const projects = await listGroupProjects(args);
return {
content: [{ type: "text", text: JSON.stringify(projects, null, 2) }],
};
}
default:
throw new Error(`Unknown tool: ${request.params.name}`);
}