feat: Decode project_id for GitLab API calls
- Decode project_id using decodeURIComponent() in relevant helper functions. - This resolves API call issues related to project ID encoding differences between models. - Updated CHANGELOG for 1.0.36 and added thanks to Aubermean.
This commit is contained in:
5
CHANGELOG.md
Normal file
5
CHANGELOG.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
## [Released] - 2025-05-13
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **GitLab MCP Server:** Modified GitLab API helper functions to decode the `project_id` using `decodeURIComponent()` before processing. This resolves API call failures caused by differences in project ID encoding between Gemini and other AI models. API requests are now handled consistently regardless of the model.
|
71
index.ts
71
index.ts
@ -395,7 +395,8 @@ const allTools = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "get_repository_tree",
|
name: "get_repository_tree",
|
||||||
description: "Get the repository tree for a GitLab project (list files and directories)",
|
description:
|
||||||
|
"Get the repository tree for a GitLab project (list files and directories)",
|
||||||
inputSchema: zodToJsonSchema(GetRepositoryTreeSchema),
|
inputSchema: zodToJsonSchema(GetRepositoryTreeSchema),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -506,6 +507,7 @@ async function forkProject(
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
namespace?: string
|
namespace?: string
|
||||||
): Promise<GitLabFork> {
|
): Promise<GitLabFork> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/fork`
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/fork`
|
||||||
);
|
);
|
||||||
@ -541,6 +543,7 @@ async function createBranch(
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
options: z.infer<typeof CreateBranchOptionsSchema>
|
options: z.infer<typeof CreateBranchOptionsSchema>
|
||||||
): Promise<GitLabReference> {
|
): Promise<GitLabReference> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
projectId
|
projectId
|
||||||
@ -568,6 +571,7 @@ async function createBranch(
|
|||||||
* @returns {Promise<string>} The name of the default branch
|
* @returns {Promise<string>} The name of the default branch
|
||||||
*/
|
*/
|
||||||
async function getDefaultBranchRef(projectId: string): Promise<string> {
|
async function getDefaultBranchRef(projectId: string): Promise<string> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}`
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}`
|
||||||
);
|
);
|
||||||
@ -595,6 +599,7 @@ async function getFileContents(
|
|||||||
filePath: string,
|
filePath: string,
|
||||||
ref?: string
|
ref?: string
|
||||||
): Promise<GitLabContent> {
|
): Promise<GitLabContent> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const encodedPath = encodeURIComponent(filePath);
|
const encodedPath = encodeURIComponent(filePath);
|
||||||
|
|
||||||
// ref가 없는 경우 default branch를 가져옴
|
// ref가 없는 경우 default branch를 가져옴
|
||||||
@ -646,6 +651,7 @@ async function createIssue(
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
options: z.infer<typeof CreateIssueOptionsSchema>
|
options: z.infer<typeof CreateIssueOptionsSchema>
|
||||||
): Promise<GitLabIssue> {
|
): Promise<GitLabIssue> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues`
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues`
|
||||||
);
|
);
|
||||||
@ -685,6 +691,7 @@ async function listIssues(
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
options: Omit<z.infer<typeof ListIssuesSchema>, "project_id"> = {}
|
options: Omit<z.infer<typeof ListIssuesSchema>, "project_id"> = {}
|
||||||
): Promise<GitLabIssue[]> {
|
): Promise<GitLabIssue[]> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues`
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues`
|
||||||
);
|
);
|
||||||
@ -722,6 +729,7 @@ async function getIssue(
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
issueIid: number
|
issueIid: number
|
||||||
): Promise<GitLabIssue> {
|
): Promise<GitLabIssue> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
projectId
|
projectId
|
||||||
@ -751,6 +759,7 @@ async function updateIssue(
|
|||||||
issueIid: number,
|
issueIid: number,
|
||||||
options: Omit<z.infer<typeof UpdateIssueSchema>, "project_id" | "issue_iid">
|
options: Omit<z.infer<typeof UpdateIssueSchema>, "project_id" | "issue_iid">
|
||||||
): Promise<GitLabIssue> {
|
): Promise<GitLabIssue> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
projectId
|
projectId
|
||||||
@ -783,6 +792,7 @@ async function updateIssue(
|
|||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async function deleteIssue(projectId: string, issueIid: number): Promise<void> {
|
async function deleteIssue(projectId: string, issueIid: number): Promise<void> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
projectId
|
projectId
|
||||||
@ -809,6 +819,7 @@ async function listIssueLinks(
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
issueIid: number
|
issueIid: number
|
||||||
): Promise<GitLabIssueWithLinkDetails[]> {
|
): Promise<GitLabIssueWithLinkDetails[]> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
projectId
|
projectId
|
||||||
@ -838,6 +849,7 @@ async function getIssueLink(
|
|||||||
issueIid: number,
|
issueIid: number,
|
||||||
issueLinkId: number
|
issueLinkId: number
|
||||||
): Promise<GitLabIssueLink> {
|
): Promise<GitLabIssueLink> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
projectId
|
projectId
|
||||||
@ -871,6 +883,8 @@ async function createIssueLink(
|
|||||||
targetIssueIid: number,
|
targetIssueIid: number,
|
||||||
linkType: "relates_to" | "blocks" | "is_blocked_by" = "relates_to"
|
linkType: "relates_to" | "blocks" | "is_blocked_by" = "relates_to"
|
||||||
): Promise<GitLabIssueLink> {
|
): Promise<GitLabIssueLink> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
|
targetProjectId = decodeURIComponent(targetProjectId); // Decode target project ID as well
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
projectId
|
projectId
|
||||||
@ -906,6 +920,7 @@ async function deleteIssueLink(
|
|||||||
issueIid: number,
|
issueIid: number,
|
||||||
issueLinkId: number
|
issueLinkId: number
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
projectId
|
projectId
|
||||||
@ -932,6 +947,7 @@ async function createMergeRequest(
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
options: z.infer<typeof CreateMergeRequestOptionsSchema>
|
options: z.infer<typeof CreateMergeRequestOptionsSchema>
|
||||||
): Promise<GitLabMergeRequest> {
|
): Promise<GitLabMergeRequest> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests`
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests`
|
||||||
);
|
);
|
||||||
@ -977,6 +993,7 @@ async function listMergeRequestDiscussions(
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
mergeRequestIid: number
|
mergeRequestIid: number
|
||||||
): Promise<GitLabDiscussion[]> {
|
): Promise<GitLabDiscussion[]> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
projectId
|
projectId
|
||||||
@ -1013,6 +1030,7 @@ async function updateMergeRequestNote(
|
|||||||
body: string,
|
body: string,
|
||||||
resolved?: boolean
|
resolved?: boolean
|
||||||
): Promise<GitLabDiscussionNote> {
|
): Promise<GitLabDiscussionNote> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
projectId
|
projectId
|
||||||
@ -1057,6 +1075,7 @@ async function createOrUpdateFile(
|
|||||||
last_commit_id?: string,
|
last_commit_id?: string,
|
||||||
commit_id?: string
|
commit_id?: string
|
||||||
): Promise<GitLabCreateUpdateFileResponse> {
|
): Promise<GitLabCreateUpdateFileResponse> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const encodedPath = encodeURIComponent(filePath);
|
const encodedPath = encodeURIComponent(filePath);
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
@ -1139,6 +1158,7 @@ async function createTree(
|
|||||||
files: FileOperation[],
|
files: FileOperation[],
|
||||||
ref?: string
|
ref?: string
|
||||||
): Promise<GitLabTree> {
|
): Promise<GitLabTree> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
projectId
|
projectId
|
||||||
@ -1193,6 +1213,7 @@ async function createCommit(
|
|||||||
branch: string,
|
branch: string,
|
||||||
actions: FileOperation[]
|
actions: FileOperation[]
|
||||||
): Promise<GitLabCommit> {
|
): Promise<GitLabCommit> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
projectId
|
projectId
|
||||||
@ -1325,6 +1346,7 @@ async function getMergeRequest(
|
|||||||
mergeRequestIid?: number,
|
mergeRequestIid?: number,
|
||||||
branchName?: string
|
branchName?: string
|
||||||
): Promise<GitLabMergeRequest> {
|
): Promise<GitLabMergeRequest> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
let url: URL;
|
let url: URL;
|
||||||
|
|
||||||
if (mergeRequestIid) {
|
if (mergeRequestIid) {
|
||||||
@ -1375,6 +1397,7 @@ async function getMergeRequestDiffs(
|
|||||||
branchName?: string,
|
branchName?: string,
|
||||||
view?: "inline" | "parallel"
|
view?: "inline" | "parallel"
|
||||||
): Promise<GitLabMergeRequestDiff[]> {
|
): Promise<GitLabMergeRequestDiff[]> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
if (!mergeRequestIid && !branchName) {
|
if (!mergeRequestIid && !branchName) {
|
||||||
throw new Error("Either mergeRequestIid or branchName must be provided");
|
throw new Error("Either mergeRequestIid or branchName must be provided");
|
||||||
}
|
}
|
||||||
@ -1426,6 +1449,7 @@ async function updateMergeRequest(
|
|||||||
mergeRequestIid?: number,
|
mergeRequestIid?: number,
|
||||||
branchName?: string
|
branchName?: string
|
||||||
): Promise<GitLabMergeRequest> {
|
): Promise<GitLabMergeRequest> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
if (!mergeRequestIid && !branchName) {
|
if (!mergeRequestIid && !branchName) {
|
||||||
throw new Error("Either mergeRequestIid or branchName must be provided");
|
throw new Error("Either mergeRequestIid or branchName must be provided");
|
||||||
}
|
}
|
||||||
@ -1472,6 +1496,7 @@ async function createNote(
|
|||||||
noteableIid: number,
|
noteableIid: number,
|
||||||
body: string
|
body: string
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
// ⚙️ 응답 타입은 GitLab API 문서에 따라 조정 가능
|
// ⚙️ 응답 타입은 GitLab API 문서에 따라 조정 가능
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
@ -1600,6 +1625,7 @@ async function getProject(
|
|||||||
with_custom_attributes?: boolean;
|
with_custom_attributes?: boolean;
|
||||||
} = {}
|
} = {}
|
||||||
): Promise<GitLabProject> {
|
): Promise<GitLabProject> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}`
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}`
|
||||||
);
|
);
|
||||||
@ -1674,6 +1700,7 @@ async function listLabels(
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
options: Omit<z.infer<typeof ListLabelsSchema>, "project_id"> = {}
|
options: Omit<z.infer<typeof ListLabelsSchema>, "project_id"> = {}
|
||||||
): Promise<GitLabLabel[]> {
|
): Promise<GitLabLabel[]> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
// Construct the URL with project path
|
// Construct the URL with project path
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels`
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels`
|
||||||
@ -1716,6 +1743,7 @@ async function getLabel(
|
|||||||
labelId: number | string,
|
labelId: number | string,
|
||||||
includeAncestorGroups?: boolean
|
includeAncestorGroups?: boolean
|
||||||
): Promise<GitLabLabel> {
|
): Promise<GitLabLabel> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
projectId
|
projectId
|
||||||
@ -1754,6 +1782,7 @@ async function createLabel(
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
options: Omit<z.infer<typeof CreateLabelSchema>, "project_id">
|
options: Omit<z.infer<typeof CreateLabelSchema>, "project_id">
|
||||||
): Promise<GitLabLabel> {
|
): Promise<GitLabLabel> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
// Make the API request
|
// Make the API request
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels`,
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels`,
|
||||||
@ -1785,6 +1814,7 @@ async function updateLabel(
|
|||||||
labelId: number | string,
|
labelId: number | string,
|
||||||
options: Omit<z.infer<typeof UpdateLabelSchema>, "project_id" | "label_id">
|
options: Omit<z.infer<typeof UpdateLabelSchema>, "project_id" | "label_id">
|
||||||
): Promise<GitLabLabel> {
|
): Promise<GitLabLabel> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
// Make the API request
|
// Make the API request
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
@ -1815,6 +1845,7 @@ async function deleteLabel(
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
labelId: number | string
|
labelId: number | string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
// Make the API request
|
// Make the API request
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
@ -1908,6 +1939,7 @@ async function listWikiPages(
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
options: Omit<z.infer<typeof ListWikiPagesSchema>, "project_id"> = {}
|
options: Omit<z.infer<typeof ListWikiPagesSchema>, "project_id"> = {}
|
||||||
): Promise<GitLabWikiPage[]> {
|
): Promise<GitLabWikiPage[]> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/wikis`
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/wikis`
|
||||||
);
|
);
|
||||||
@ -1929,6 +1961,7 @@ async function getWikiPage(
|
|||||||
projectId: string,
|
projectId: string,
|
||||||
slug: string
|
slug: string
|
||||||
): Promise<GitLabWikiPage> {
|
): Promise<GitLabWikiPage> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
projectId
|
projectId
|
||||||
@ -1949,6 +1982,7 @@ async function createWikiPage(
|
|||||||
content: string,
|
content: string,
|
||||||
format?: string
|
format?: string
|
||||||
): Promise<GitLabWikiPage> {
|
): Promise<GitLabWikiPage> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const body: Record<string, any> = { title, content };
|
const body: Record<string, any> = { title, content };
|
||||||
if (format) body.format = format;
|
if (format) body.format = format;
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
@ -1974,6 +2008,7 @@ async function updateWikiPage(
|
|||||||
content?: string,
|
content?: string,
|
||||||
format?: string
|
format?: string
|
||||||
): Promise<GitLabWikiPage> {
|
): Promise<GitLabWikiPage> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const body: Record<string, any> = {};
|
const body: Record<string, any> = {};
|
||||||
if (title) body.title = title;
|
if (title) body.title = title;
|
||||||
if (content) body.content = content;
|
if (content) body.content = content;
|
||||||
@ -1997,6 +2032,7 @@ async function updateWikiPage(
|
|||||||
* Delete a wiki page
|
* Delete a wiki page
|
||||||
*/
|
*/
|
||||||
async function deleteWikiPage(projectId: string, slug: string): Promise<void> {
|
async function deleteWikiPage(projectId: string, slug: string): Promise<void> {
|
||||||
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
projectId
|
projectId
|
||||||
@ -2018,16 +2054,20 @@ async function deleteWikiPage(projectId: string, slug: string): Promise<void> {
|
|||||||
async function getRepositoryTree(
|
async function getRepositoryTree(
|
||||||
options: GetRepositoryTreeOptions
|
options: GetRepositoryTreeOptions
|
||||||
): Promise<GitLabTreeItem[]> {
|
): Promise<GitLabTreeItem[]> {
|
||||||
|
options.project_id = decodeURIComponent(options.project_id); // Decode project_id within options
|
||||||
const queryParams = new URLSearchParams();
|
const queryParams = new URLSearchParams();
|
||||||
if (options.path) queryParams.append("path", options.path);
|
if (options.path) queryParams.append("path", options.path);
|
||||||
if (options.ref) queryParams.append("ref", options.ref);
|
if (options.ref) queryParams.append("ref", options.ref);
|
||||||
if (options.recursive) queryParams.append("recursive", "true");
|
if (options.recursive) queryParams.append("recursive", "true");
|
||||||
if (options.per_page) queryParams.append("per_page", options.per_page.toString());
|
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.page_token) queryParams.append("page_token", options.page_token);
|
||||||
if (options.pagination) queryParams.append("pagination", options.pagination);
|
if (options.pagination) queryParams.append("pagination", options.pagination);
|
||||||
|
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(options.project_id)}/repository/tree?${queryParams.toString()}`,
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
|
options.project_id
|
||||||
|
)}/repository/tree?${queryParams.toString()}`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
|
||||||
@ -2054,12 +2094,33 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|||||||
? allTools.filter((tool) => readOnlyTools.includes(tool.name))
|
? allTools.filter((tool) => readOnlyTools.includes(tool.name))
|
||||||
: allTools;
|
: allTools;
|
||||||
// Toggle wiki tools by USE_GITLAB_WIKI flag
|
// Toggle wiki tools by USE_GITLAB_WIKI flag
|
||||||
const tools = USE_GITLAB_WIKI
|
let tools = USE_GITLAB_WIKI
|
||||||
? tools0
|
? tools0
|
||||||
: tools0.filter((tool) => !wikiToolNames.includes(tool.name));
|
: tools0.filter((tool) => !wikiToolNames.includes(tool.name));
|
||||||
|
|
||||||
|
// <<< START: Gemini 호환성을 위해 $schema 제거 >>>
|
||||||
|
tools = tools.map((tool) => {
|
||||||
|
// inputSchema가 존재하고 객체인지 확인
|
||||||
|
if (
|
||||||
|
tool.inputSchema &&
|
||||||
|
typeof tool.inputSchema === "object" &&
|
||||||
|
tool.inputSchema !== null
|
||||||
|
) {
|
||||||
|
// $schema 키가 존재하면 삭제
|
||||||
|
if ("$schema" in tool.inputSchema) {
|
||||||
|
// 불변성을 위해 새로운 객체 생성 (선택적이지만 권장)
|
||||||
|
const modifiedSchema = { ...tool.inputSchema };
|
||||||
|
delete modifiedSchema.$schema;
|
||||||
|
return { ...tool, inputSchema: modifiedSchema };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 변경이 필요 없으면 그대로 반환
|
||||||
|
return tool;
|
||||||
|
});
|
||||||
|
// <<< END: Gemini 호환성을 위해 $schema 제거 >>>
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tools,
|
tools, // $schema가 제거된 도구 목록 반환
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@zereight/mcp-gitlab",
|
"name": "@zereight/mcp-gitlab",
|
||||||
"version": "1.0.35",
|
"version": "1.0.36",
|
||||||
"description": "MCP server for using the GitLab API",
|
"description": "MCP server for using the GitLab API",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "zereight",
|
"author": "zereight",
|
||||||
|
Reference in New Issue
Block a user