feat: implement list_merge_requests functionality

- Add ListMergeRequestsSchema with comprehensive filtering options
- Implement listMergeRequests function following GitLab API
- Add tool definition and switch case handler
- Include in readOnlyTools array
- Update README.md with new tool documentation
This commit is contained in:
Jiaqi Wang
2025-05-28 16:54:30 +02:00
parent f8b1444afd
commit cc847772f1
4 changed files with 137 additions and 2 deletions

View File

@ -134,6 +134,7 @@ import {
type GetRepositoryTreeOptions,
UpdateIssueNoteSchema,
CreateIssueNoteSchema,
ListMergeRequestsSchema,
} from "./schemas.js";
/**
@ -466,6 +467,11 @@ const allTools = [
description: "Get the output/trace of a GitLab pipeline job number",
inputSchema: zodToJsonSchema(GetPipelineJobOutputSchema),
},
{
name: "list_merge_requests",
description: "List merge requests in a GitLab project with filtering options",
inputSchema: zodToJsonSchema(ListMergeRequestsSchema),
},
];
// Define which tools are read-only
@ -476,6 +482,7 @@ const readOnlyTools = [
"get_merge_request_diffs",
"mr_discussions",
"list_issues",
"list_merge_requests",
"get_issue",
"list_issue_links",
"list_issue_discussions",
@ -791,6 +798,43 @@ async function listIssues(
return z.array(GitLabIssueSchema).parse(data);
}
/**
* List merge requests in a GitLab project with optional filtering
*
* @param {string} projectId - The ID or URL-encoded path of the project
* @param {Object} options - Optional filtering parameters
* @returns {Promise<GitLabMergeRequest[]>} List of merge requests
*/
async function listMergeRequests(
projectId: string,
options: Omit<z.infer<typeof ListMergeRequestsSchema>, "project_id"> = {}
): Promise<GitLabMergeRequest[]> {
projectId = decodeURIComponent(projectId); // Decode project ID
const url = new URL(
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests`
);
// Add all query parameters
Object.entries(options).forEach(([key, value]) => {
if (value !== undefined) {
if (key === "labels" && Array.isArray(value)) {
// Handle array of labels
url.searchParams.append(key, value.join(","));
} else {
url.searchParams.append(key, value.toString());
}
}
});
const response = await fetch(url.toString(), {
...DEFAULT_FETCH_CONFIG,
});
await handleGitLabError(response);
const data = await response.json();
return z.array(GitLabMergeRequestSchema).parse(data);
}
/**
* Get a single issue from a GitLab project
* 단일 이슈 조회
@ -3300,6 +3344,14 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
};
}
case "list_merge_requests": {
const args = ListMergeRequestsSchema.parse(request.params.arguments);
const mergeRequests = await listMergeRequests(args.project_id, args);
return {
content: [{ type: "text", text: JSON.stringify(mergeRequests, null, 2) }],
};
}
default:
throw new Error(`Unknown tool: ${request.params.name}`);
}