Merge pull request #35 from BobMerkus/feat/list-repository
feat: Gitlab list repository tree tool
This commit is contained in:
56
index.ts
56
index.ts
@ -113,6 +113,10 @@ import {
|
||||
type UpdateWikiPageOptions,
|
||||
type DeleteWikiPageOptions,
|
||||
type GitLabWikiPage,
|
||||
GitLabTreeItemSchema,
|
||||
GetRepositoryTreeSchema,
|
||||
type GitLabTreeItem,
|
||||
type GetRepositoryTreeOptions,
|
||||
} from "./schemas.js";
|
||||
|
||||
/**
|
||||
@ -389,6 +393,11 @@ const allTools = [
|
||||
description: "Delete a wiki page from a GitLab project",
|
||||
inputSchema: zodToJsonSchema(DeleteWikiPageSchema),
|
||||
},
|
||||
{
|
||||
name: "get_repository_tree",
|
||||
description: "Get the repository tree for a GitLab project (list files and directories)",
|
||||
inputSchema: zodToJsonSchema(GetRepositoryTreeSchema),
|
||||
},
|
||||
];
|
||||
|
||||
// Define which tools are read-only
|
||||
@ -2000,6 +2009,45 @@ async function deleteWikiPage(projectId: string, slug: string): Promise<void> {
|
||||
await handleGitLabError(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the repository tree for a project
|
||||
* @param {string} projectId - The ID or URL-encoded path of the project
|
||||
* @param {GetRepositoryTreeOptions} options - Options for the tree
|
||||
* @returns {Promise<GitLabTreeItem[]>}
|
||||
*/
|
||||
async function getRepositoryTree(
|
||||
options: GetRepositoryTreeOptions
|
||||
): Promise<GitLabTreeItem[]> {
|
||||
const queryParams = new URLSearchParams();
|
||||
if (options.path) queryParams.append("path", options.path);
|
||||
if (options.ref) queryParams.append("ref", options.ref);
|
||||
if (options.recursive) queryParams.append("recursive", "true");
|
||||
if (options.per_page) queryParams.append("per_page", options.per_page.toString());
|
||||
if (options.page_token) queryParams.append("page_token", options.page_token);
|
||||
if (options.pagination) queryParams.append("pagination", options.pagination);
|
||||
|
||||
const response = await fetch(
|
||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(options.project_id)}/repository/tree?${queryParams.toString()}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (response.status === 404) {
|
||||
throw new Error("Repository or path not found");
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to get repository tree: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return z.array(GitLabTreeItemSchema).parse(data);
|
||||
}
|
||||
|
||||
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
||||
// Apply read-only filter first
|
||||
const tools0 = GITLAB_READ_ONLY_MODE
|
||||
@ -2579,6 +2627,14 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||
};
|
||||
}
|
||||
|
||||
case "get_repository_tree": {
|
||||
const args = GetRepositoryTreeSchema.parse(request.params.arguments);
|
||||
const tree = await getRepositoryTree(args);
|
||||
return {
|
||||
content: [{ type: "text", text: JSON.stringify(tree, null, 2) }],
|
||||
};
|
||||
}
|
||||
|
||||
default:
|
||||
throw new Error(`Unknown tool: ${request.params.name}`);
|
||||
}
|
||||
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@zereight/mcp-gitlab",
|
||||
"version": "1.0.32",
|
||||
"version": "1.0.33",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@zereight/mcp-gitlab",
|
||||
"version": "1.0.32",
|
||||
"version": "1.0.33",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "1.8.0",
|
||||
|
20
schemas.ts
20
schemas.ts
@ -160,17 +160,27 @@ export const FileOperationSchema = z.object({
|
||||
});
|
||||
|
||||
// Tree and commit schemas
|
||||
export const GitLabTreeEntrySchema = z.object({
|
||||
id: z.string(), // Changed from sha to match GitLab API
|
||||
export const GitLabTreeItemSchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
type: z.enum(["blob", "tree"]),
|
||||
type: z.enum(["tree", "blob"]),
|
||||
path: z.string(),
|
||||
mode: z.string(),
|
||||
});
|
||||
|
||||
export const GetRepositoryTreeSchema = z.object({
|
||||
project_id: z.string().describe("The ID or URL-encoded path of the project"),
|
||||
path: z.string().optional().describe("The path inside the repository"),
|
||||
ref: z.string().optional().describe("The name of a repository branch or tag. Defaults to the default branch."),
|
||||
recursive: z.boolean().optional().describe("Boolean value to get a recursive tree"),
|
||||
per_page: z.number().optional().describe("Number of results to show per page"),
|
||||
page_token: z.string().optional().describe("The tree record ID for pagination"),
|
||||
pagination: z.string().optional().describe("Pagination method (keyset)")
|
||||
});
|
||||
|
||||
export const GitLabTreeSchema = z.object({
|
||||
id: z.string(), // Changed from sha to match GitLab API
|
||||
tree: z.array(GitLabTreeEntrySchema),
|
||||
tree: z.array(GitLabTreeItemSchema),
|
||||
});
|
||||
|
||||
export const GitLabCommitSchema = z.object({
|
||||
@ -1033,3 +1043,5 @@ export type CreateWikiPageOptions = z.infer<typeof CreateWikiPageSchema>;
|
||||
export type UpdateWikiPageOptions = z.infer<typeof UpdateWikiPageSchema>;
|
||||
export type DeleteWikiPageOptions = z.infer<typeof DeleteWikiPageSchema>;
|
||||
export type GitLabWikiPage = z.infer<typeof GitLabWikiPageSchema>;
|
||||
export type GitLabTreeItem = z.infer<typeof GitLabTreeItemSchema>;
|
||||
export type GetRepositoryTreeOptions = z.infer<typeof GetRepositoryTreeSchema>;
|
||||
|
Reference in New Issue
Block a user