chore: bump version to 1.0.27 and update deploy script for public access
This commit is contained in:
277
index.ts
277
index.ts
@ -10,7 +10,7 @@ import fetch from "node-fetch";
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { zodToJsonSchema } from "zod-to-json-schema";
|
import { zodToJsonSchema } from "zod-to-json-schema";
|
||||||
import { fileURLToPath } from "url";
|
import { fileURLToPath } from "url";
|
||||||
import { dirname, resolve } from "path";
|
import { dirname } from "path";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import {
|
import {
|
||||||
@ -100,11 +100,11 @@ import {
|
|||||||
*/
|
*/
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = dirname(__filename);
|
const __dirname = dirname(__filename);
|
||||||
const packageJsonPath = path.resolve(__dirname, '../package.json');
|
const packageJsonPath = path.resolve(__dirname, "../package.json");
|
||||||
let SERVER_VERSION = "unknown";
|
let SERVER_VERSION = "unknown";
|
||||||
try {
|
try {
|
||||||
if (fs.existsSync(packageJsonPath)) {
|
if (fs.existsSync(packageJsonPath)) {
|
||||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
||||||
SERVER_VERSION = packageJson.version || SERVER_VERSION;
|
SERVER_VERSION = packageJson.version || SERVER_VERSION;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -124,7 +124,7 @@ const server = new Server(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const GITLAB_PERSONAL_ACCESS_TOKEN = process.env.GITLAB_PERSONAL_ACCESS_TOKEN;
|
const GITLAB_PERSONAL_ACCESS_TOKEN = process.env.GITLAB_PERSONAL_ACCESS_TOKEN;
|
||||||
const GITLAB_READ_ONLY_MODE = process.env.GITLAB_READ_ONLY_MODE === 'true';
|
const GITLAB_READ_ONLY_MODE = process.env.GITLAB_READ_ONLY_MODE === "true";
|
||||||
|
|
||||||
// Define all available tools
|
// Define all available tools
|
||||||
const allTools = [
|
const allTools = [
|
||||||
@ -151,8 +151,7 @@ const allTools = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "push_files",
|
name: "push_files",
|
||||||
description:
|
description: "Push multiple files to a GitLab project in a single commit",
|
||||||
"Push multiple files to a GitLab project in a single commit",
|
|
||||||
inputSchema: zodToJsonSchema(PushFilesSchema),
|
inputSchema: zodToJsonSchema(PushFilesSchema),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -167,8 +166,7 @@ const allTools = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "fork_repository",
|
name: "fork_repository",
|
||||||
description:
|
description: "Fork a GitLab project to your account or specified namespace",
|
||||||
"Fork a GitLab project to your account or specified namespace",
|
|
||||||
inputSchema: zodToJsonSchema(ForkRepositorySchema),
|
inputSchema: zodToJsonSchema(ForkRepositorySchema),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -321,7 +319,7 @@ const readOnlyTools = [
|
|||||||
"list_projects",
|
"list_projects",
|
||||||
"list_labels",
|
"list_labels",
|
||||||
"get_label",
|
"get_label",
|
||||||
"list_group_projects"
|
"list_group_projects",
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -336,10 +334,13 @@ function normalizeGitLabApiUrl(url?: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove trailing slash if present
|
// Remove trailing slash if present
|
||||||
let normalizedUrl = url.endsWith('/') ? url.slice(0, -1) : url;
|
let normalizedUrl = url.endsWith("/") ? url.slice(0, -1) : url;
|
||||||
|
|
||||||
// Check if URL already has /api/v4
|
// Check if URL already has /api/v4
|
||||||
if (!normalizedUrl.endsWith('/api/v4') && !normalizedUrl.endsWith('/api/v4/')) {
|
if (
|
||||||
|
!normalizedUrl.endsWith("/api/v4") &&
|
||||||
|
!normalizedUrl.endsWith("/api/v4/")
|
||||||
|
) {
|
||||||
// Append /api/v4 if not already present
|
// Append /api/v4 if not already present
|
||||||
normalizedUrl = `${normalizedUrl}/api/v4`;
|
normalizedUrl = `${normalizedUrl}/api/v4`;
|
||||||
}
|
}
|
||||||
@ -582,9 +583,9 @@ async function listIssues(
|
|||||||
// Add all query parameters
|
// Add all query parameters
|
||||||
Object.entries(options).forEach(([key, value]) => {
|
Object.entries(options).forEach(([key, value]) => {
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
if (key === 'label_name' && Array.isArray(value)) {
|
if (key === "label_name" && Array.isArray(value)) {
|
||||||
// Handle array of labels
|
// Handle array of labels
|
||||||
url.searchParams.append(key, value.join(','));
|
url.searchParams.append(key, value.join(","));
|
||||||
} else {
|
} else {
|
||||||
url.searchParams.append(key, value.toString());
|
url.searchParams.append(key, value.toString());
|
||||||
}
|
}
|
||||||
@ -613,7 +614,9 @@ async function getIssue(
|
|||||||
issueIid: number
|
issueIid: number
|
||||||
): Promise<GitLabIssue> {
|
): Promise<GitLabIssue> {
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}`
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
|
projectId
|
||||||
|
)}/issues/${issueIid}`
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await fetch(url.toString(), {
|
const response = await fetch(url.toString(), {
|
||||||
@ -640,13 +643,15 @@ async function updateIssue(
|
|||||||
options: Omit<z.infer<typeof UpdateIssueSchema>, "project_id" | "issue_iid">
|
options: Omit<z.infer<typeof UpdateIssueSchema>, "project_id" | "issue_iid">
|
||||||
): Promise<GitLabIssue> {
|
): Promise<GitLabIssue> {
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}`
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
|
projectId
|
||||||
|
)}/issues/${issueIid}`
|
||||||
);
|
);
|
||||||
|
|
||||||
// Convert labels array to comma-separated string if present
|
// Convert labels array to comma-separated string if present
|
||||||
const body: Record<string, any> = { ...options };
|
const body: Record<string, any> = { ...options };
|
||||||
if (body.labels && Array.isArray(body.labels)) {
|
if (body.labels && Array.isArray(body.labels)) {
|
||||||
body.labels = body.labels.join(',');
|
body.labels = body.labels.join(",");
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(url.toString(), {
|
const response = await fetch(url.toString(), {
|
||||||
@ -668,12 +673,11 @@ async function updateIssue(
|
|||||||
* @param {number} issueIid - The internal ID of the project issue
|
* @param {number} issueIid - The internal ID of the project issue
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async function deleteIssue(
|
async function deleteIssue(projectId: string, issueIid: number): Promise<void> {
|
||||||
projectId: string,
|
|
||||||
issueIid: number
|
|
||||||
): Promise<void> {
|
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}`
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
|
projectId
|
||||||
|
)}/issues/${issueIid}`
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await fetch(url.toString(), {
|
const response = await fetch(url.toString(), {
|
||||||
@ -697,7 +701,9 @@ async function listIssueLinks(
|
|||||||
issueIid: number
|
issueIid: number
|
||||||
): Promise<GitLabIssueWithLinkDetails[]> {
|
): Promise<GitLabIssueWithLinkDetails[]> {
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links`
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
|
projectId
|
||||||
|
)}/issues/${issueIid}/links`
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await fetch(url.toString(), {
|
const response = await fetch(url.toString(), {
|
||||||
@ -724,7 +730,9 @@ async function getIssueLink(
|
|||||||
issueLinkId: number
|
issueLinkId: number
|
||||||
): Promise<GitLabIssueLink> {
|
): Promise<GitLabIssueLink> {
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links/${issueLinkId}`
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
|
projectId
|
||||||
|
)}/issues/${issueIid}/links/${issueLinkId}`
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await fetch(url.toString(), {
|
const response = await fetch(url.toString(), {
|
||||||
@ -752,10 +760,12 @@ async function createIssueLink(
|
|||||||
issueIid: number,
|
issueIid: number,
|
||||||
targetProjectId: string,
|
targetProjectId: string,
|
||||||
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> {
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links`
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
|
projectId
|
||||||
|
)}/issues/${issueIid}/links`
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await fetch(url.toString(), {
|
const response = await fetch(url.toString(), {
|
||||||
@ -764,7 +774,7 @@ async function createIssueLink(
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
target_project_id: targetProjectId,
|
target_project_id: targetProjectId,
|
||||||
target_issue_iid: targetIssueIid,
|
target_issue_iid: targetIssueIid,
|
||||||
link_type: linkType
|
link_type: linkType,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -788,7 +798,9 @@ async function deleteIssueLink(
|
|||||||
issueLinkId: number
|
issueLinkId: number
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues/${issueIid}/links/${issueLinkId}`
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
|
projectId
|
||||||
|
)}/issues/${issueIid}/links/${issueLinkId}`
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await fetch(url.toString(), {
|
const response = await fetch(url.toString(), {
|
||||||
@ -812,9 +824,7 @@ async function createMergeRequest(
|
|||||||
options: z.infer<typeof CreateMergeRequestOptionsSchema>
|
options: z.infer<typeof CreateMergeRequestOptionsSchema>
|
||||||
): Promise<GitLabMergeRequest> {
|
): Promise<GitLabMergeRequest> {
|
||||||
const url = new URL(
|
const url = new URL(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests`
|
||||||
projectId
|
|
||||||
)}/merge_requests`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await fetch(url.toString(), {
|
const response = await fetch(url.toString(), {
|
||||||
@ -1417,7 +1427,9 @@ async function verifyNamespaceExistence(
|
|||||||
namespacePath: string,
|
namespacePath: string,
|
||||||
parentId?: number
|
parentId?: number
|
||||||
): Promise<GitLabNamespaceExistsResponse> {
|
): Promise<GitLabNamespaceExistsResponse> {
|
||||||
const url = new URL(`${GITLAB_API_URL}/namespaces/${encodeURIComponent(namespacePath)}/exists`);
|
const url = new URL(
|
||||||
|
`${GITLAB_API_URL}/namespaces/${encodeURIComponent(namespacePath)}/exists`
|
||||||
|
);
|
||||||
|
|
||||||
if (parentId) {
|
if (parentId) {
|
||||||
url.searchParams.append("parent_id", parentId.toString());
|
url.searchParams.append("parent_id", parentId.toString());
|
||||||
@ -1451,7 +1463,9 @@ async function getProject(
|
|||||||
with_custom_attributes?: boolean;
|
with_custom_attributes?: boolean;
|
||||||
} = {}
|
} = {}
|
||||||
): Promise<GitLabProject> {
|
): Promise<GitLabProject> {
|
||||||
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}`);
|
const url = new URL(
|
||||||
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}`
|
||||||
|
);
|
||||||
|
|
||||||
if (options.license) {
|
if (options.license) {
|
||||||
url.searchParams.append("license", "true");
|
url.searchParams.append("license", "true");
|
||||||
@ -1481,7 +1495,9 @@ async function getProject(
|
|||||||
* @param {Object} options - Options for listing projects
|
* @param {Object} options - Options for listing projects
|
||||||
* @returns {Promise<GitLabProject[]>} List of projects
|
* @returns {Promise<GitLabProject[]>} List of projects
|
||||||
*/
|
*/
|
||||||
async function listProjects(options: z.infer<typeof ListProjectsSchema> = {}): Promise<GitLabProject[]> {
|
async function listProjects(
|
||||||
|
options: z.infer<typeof ListProjectsSchema> = {}
|
||||||
|
): Promise<GitLabProject[]> {
|
||||||
// Construct the query parameters
|
// Construct the query parameters
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
for (const [key, value] of Object.entries(options)) {
|
for (const [key, value] of Object.entries(options)) {
|
||||||
@ -1523,7 +1539,9 @@ async function listLabels(
|
|||||||
options: Omit<z.infer<typeof ListLabelsSchema>, "project_id"> = {}
|
options: Omit<z.infer<typeof ListLabelsSchema>, "project_id"> = {}
|
||||||
): Promise<GitLabLabel[]> {
|
): Promise<GitLabLabel[]> {
|
||||||
// Construct the URL with project path
|
// Construct the URL with project path
|
||||||
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels`);
|
const url = new URL(
|
||||||
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels`
|
||||||
|
);
|
||||||
|
|
||||||
// Add query parameters
|
// Add query parameters
|
||||||
Object.entries(options).forEach(([key, value]) => {
|
Object.entries(options).forEach(([key, value]) => {
|
||||||
@ -1562,11 +1580,18 @@ async function getLabel(
|
|||||||
labelId: number | string,
|
labelId: number | string,
|
||||||
includeAncestorGroups?: boolean
|
includeAncestorGroups?: boolean
|
||||||
): Promise<GitLabLabel> {
|
): Promise<GitLabLabel> {
|
||||||
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels/${encodeURIComponent(String(labelId))}`);
|
const url = new URL(
|
||||||
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
|
projectId
|
||||||
|
)}/labels/${encodeURIComponent(String(labelId))}`
|
||||||
|
);
|
||||||
|
|
||||||
// Add query parameters
|
// Add query parameters
|
||||||
if (includeAncestorGroups !== undefined) {
|
if (includeAncestorGroups !== undefined) {
|
||||||
url.searchParams.append("include_ancestor_groups", includeAncestorGroups ? "true" : "false");
|
url.searchParams.append(
|
||||||
|
"include_ancestor_groups",
|
||||||
|
includeAncestorGroups ? "true" : "false"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the API request
|
// Make the API request
|
||||||
@ -1626,7 +1651,9 @@ async function updateLabel(
|
|||||||
): Promise<GitLabLabel> {
|
): Promise<GitLabLabel> {
|
||||||
// Make the API request
|
// Make the API request
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels/${encodeURIComponent(String(labelId))}`,
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
|
projectId
|
||||||
|
)}/labels/${encodeURIComponent(String(labelId))}`,
|
||||||
{
|
{
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
headers: DEFAULT_HEADERS,
|
headers: DEFAULT_HEADERS,
|
||||||
@ -1654,7 +1681,9 @@ async function deleteLabel(
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// Make the API request
|
// Make the API request
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/labels/${encodeURIComponent(String(labelId))}`,
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(
|
||||||
|
projectId
|
||||||
|
)}/labels/${encodeURIComponent(String(labelId))}`,
|
||||||
{
|
{
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
headers: DEFAULT_HEADERS,
|
headers: DEFAULT_HEADERS,
|
||||||
@ -1679,22 +1708,52 @@ async function listGroupProjects(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Add optional parameters to URL
|
// Add optional parameters to URL
|
||||||
if (options.include_subgroups) url.searchParams.append('include_subgroups', 'true');
|
if (options.include_subgroups)
|
||||||
if (options.search) url.searchParams.append('search', options.search);
|
url.searchParams.append("include_subgroups", "true");
|
||||||
if (options.order_by) url.searchParams.append('order_by', options.order_by);
|
if (options.search) url.searchParams.append("search", options.search);
|
||||||
if (options.sort) url.searchParams.append('sort', options.sort);
|
if (options.order_by) url.searchParams.append("order_by", options.order_by);
|
||||||
if (options.page) url.searchParams.append('page', options.page.toString());
|
if (options.sort) url.searchParams.append("sort", options.sort);
|
||||||
if (options.per_page) url.searchParams.append('per_page', options.per_page.toString());
|
if (options.page) url.searchParams.append("page", options.page.toString());
|
||||||
if (options.archived !== undefined) url.searchParams.append('archived', options.archived.toString());
|
if (options.per_page)
|
||||||
if (options.visibility) url.searchParams.append('visibility', options.visibility);
|
url.searchParams.append("per_page", options.per_page.toString());
|
||||||
if (options.with_issues_enabled !== undefined) url.searchParams.append('with_issues_enabled', options.with_issues_enabled.toString());
|
if (options.archived !== undefined)
|
||||||
if (options.with_merge_requests_enabled !== undefined) url.searchParams.append('with_merge_requests_enabled', options.with_merge_requests_enabled.toString());
|
url.searchParams.append("archived", options.archived.toString());
|
||||||
if (options.min_access_level !== undefined) url.searchParams.append('min_access_level', options.min_access_level.toString());
|
if (options.visibility)
|
||||||
if (options.with_programming_language) url.searchParams.append('with_programming_language', options.with_programming_language);
|
url.searchParams.append("visibility", options.visibility);
|
||||||
if (options.starred !== undefined) url.searchParams.append('starred', options.starred.toString());
|
if (options.with_issues_enabled !== undefined)
|
||||||
if (options.statistics !== undefined) url.searchParams.append('statistics', options.statistics.toString());
|
url.searchParams.append(
|
||||||
if (options.with_custom_attributes !== undefined) url.searchParams.append('with_custom_attributes', options.with_custom_attributes.toString());
|
"with_issues_enabled",
|
||||||
if (options.with_security_reports !== undefined) url.searchParams.append('with_security_reports', options.with_security_reports.toString());
|
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(), {
|
const response = await fetch(url.toString(), {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
@ -1709,7 +1768,7 @@ async function listGroupProjects(
|
|||||||
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
||||||
// If read-only mode is enabled, filter out write operations
|
// If read-only mode is enabled, filter out write operations
|
||||||
const tools = GITLAB_READ_ONLY_MODE
|
const tools = GITLAB_READ_ONLY_MODE
|
||||||
? allTools.filter(tool => readOnlyTools.includes(tool.name))
|
? allTools.filter((tool) => readOnlyTools.includes(tool.name))
|
||||||
: allTools;
|
: allTools;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -1727,9 +1786,14 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|||||||
case "fork_repository": {
|
case "fork_repository": {
|
||||||
const forkArgs = ForkRepositorySchema.parse(request.params.arguments);
|
const forkArgs = ForkRepositorySchema.parse(request.params.arguments);
|
||||||
try {
|
try {
|
||||||
const forkedProject = await forkProject(forkArgs.project_id, forkArgs.namespace);
|
const forkedProject = await forkProject(
|
||||||
|
forkArgs.project_id,
|
||||||
|
forkArgs.namespace
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
content: [{ type: "text", text: JSON.stringify(forkedProject, null, 2) }],
|
content: [
|
||||||
|
{ type: "text", text: JSON.stringify(forkedProject, null, 2) },
|
||||||
|
],
|
||||||
};
|
};
|
||||||
} catch (forkError) {
|
} catch (forkError) {
|
||||||
console.error("Error forking repository:", forkError);
|
console.error("Error forking repository:", forkError);
|
||||||
@ -1738,7 +1802,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|||||||
forkErrorMessage = `${forkErrorMessage}: ${forkError.message}`;
|
forkErrorMessage = `${forkErrorMessage}: ${forkError.message}`;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
content: [{ type: "text", text: JSON.stringify({ error: forkErrorMessage }, null, 2) }],
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: JSON.stringify({ error: forkErrorMessage }, null, 2),
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1845,7 +1914,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "update_merge_request_note": {
|
case "update_merge_request_note": {
|
||||||
const args = UpdateMergeRequestNoteSchema.parse(request.params.arguments);
|
const args = UpdateMergeRequestNoteSchema.parse(
|
||||||
|
request.params.arguments
|
||||||
|
);
|
||||||
const note = await updateMergeRequestNote(
|
const note = await updateMergeRequestNote(
|
||||||
args.project_id,
|
args.project_id,
|
||||||
args.merge_request_iid,
|
args.merge_request_iid,
|
||||||
@ -1900,7 +1971,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "list_merge_request_discussions": {
|
case "list_merge_request_discussions": {
|
||||||
const args = ListMergeRequestDiscussionsSchema.parse(request.params.arguments);
|
const args = ListMergeRequestDiscussionsSchema.parse(
|
||||||
|
request.params.arguments
|
||||||
|
);
|
||||||
const discussions = await listMergeRequestDiscussions(
|
const discussions = await listMergeRequestDiscussions(
|
||||||
args.project_id,
|
args.project_id,
|
||||||
args.merge_request_iid
|
args.merge_request_iid
|
||||||
@ -1938,13 +2011,19 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|||||||
const namespaces = z.array(GitLabNamespaceSchema).parse(data);
|
const namespaces = z.array(GitLabNamespaceSchema).parse(data);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
content: [{ type: "text", text: JSON.stringify(namespaces, null, 2) }],
|
content: [
|
||||||
|
{ type: "text", text: JSON.stringify(namespaces, null, 2) },
|
||||||
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
case "get_namespace": {
|
case "get_namespace": {
|
||||||
const args = GetNamespaceSchema.parse(request.params.arguments);
|
const args = GetNamespaceSchema.parse(request.params.arguments);
|
||||||
const url = new URL(`${GITLAB_API_URL}/namespaces/${encodeURIComponent(args.namespace_id)}`);
|
const url = new URL(
|
||||||
|
`${GITLAB_API_URL}/namespaces/${encodeURIComponent(
|
||||||
|
args.namespace_id
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
|
||||||
const response = await fetch(url.toString(), {
|
const response = await fetch(url.toString(), {
|
||||||
headers: DEFAULT_HEADERS,
|
headers: DEFAULT_HEADERS,
|
||||||
@ -1961,7 +2040,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|||||||
|
|
||||||
case "verify_namespace": {
|
case "verify_namespace": {
|
||||||
const args = VerifyNamespaceSchema.parse(request.params.arguments);
|
const args = VerifyNamespaceSchema.parse(request.params.arguments);
|
||||||
const url = new URL(`${GITLAB_API_URL}/namespaces/${encodeURIComponent(args.path)}/exists`);
|
const url = new URL(
|
||||||
|
`${GITLAB_API_URL}/namespaces/${encodeURIComponent(args.path)}/exists`
|
||||||
|
);
|
||||||
|
|
||||||
const response = await fetch(url.toString(), {
|
const response = await fetch(url.toString(), {
|
||||||
headers: DEFAULT_HEADERS,
|
headers: DEFAULT_HEADERS,
|
||||||
@ -1972,13 +2053,17 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|||||||
const namespaceExists = GitLabNamespaceExistsResponseSchema.parse(data);
|
const namespaceExists = GitLabNamespaceExistsResponseSchema.parse(data);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
content: [{ type: "text", text: JSON.stringify(namespaceExists, null, 2) }],
|
content: [
|
||||||
|
{ type: "text", text: JSON.stringify(namespaceExists, null, 2) },
|
||||||
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
case "get_project": {
|
case "get_project": {
|
||||||
const args = GetProjectSchema.parse(request.params.arguments);
|
const args = GetProjectSchema.parse(request.params.arguments);
|
||||||
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(args.project_id)}`);
|
const url = new URL(
|
||||||
|
`${GITLAB_API_URL}/projects/${encodeURIComponent(args.project_id)}`
|
||||||
|
);
|
||||||
|
|
||||||
const response = await fetch(url.toString(), {
|
const response = await fetch(url.toString(), {
|
||||||
headers: DEFAULT_HEADERS,
|
headers: DEFAULT_HEADERS,
|
||||||
@ -2047,7 +2132,16 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|||||||
const args = DeleteIssueSchema.parse(request.params.arguments);
|
const args = DeleteIssueSchema.parse(request.params.arguments);
|
||||||
await deleteIssue(args.project_id, args.issue_iid);
|
await deleteIssue(args.project_id, args.issue_iid);
|
||||||
return {
|
return {
|
||||||
content: [{ type: "text", text: JSON.stringify({ status: "success", message: "Issue deleted successfully" }, null, 2) }],
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: JSON.stringify(
|
||||||
|
{ status: "success", message: "Issue deleted successfully" },
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2061,7 +2155,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|||||||
|
|
||||||
case "get_issue_link": {
|
case "get_issue_link": {
|
||||||
const args = GetIssueLinkSchema.parse(request.params.arguments);
|
const args = GetIssueLinkSchema.parse(request.params.arguments);
|
||||||
const link = await getIssueLink(args.project_id, args.issue_iid, args.issue_link_id);
|
const link = await getIssueLink(
|
||||||
|
args.project_id,
|
||||||
|
args.issue_iid,
|
||||||
|
args.issue_link_id
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
content: [{ type: "text", text: JSON.stringify(link, null, 2) }],
|
content: [{ type: "text", text: JSON.stringify(link, null, 2) }],
|
||||||
};
|
};
|
||||||
@ -2069,7 +2167,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|||||||
|
|
||||||
case "create_issue_link": {
|
case "create_issue_link": {
|
||||||
const args = CreateIssueLinkSchema.parse(request.params.arguments);
|
const args = CreateIssueLinkSchema.parse(request.params.arguments);
|
||||||
const link = await createIssueLink(args.project_id, args.issue_iid, args.target_project_id, args.target_issue_iid, args.link_type);
|
const link = await createIssueLink(
|
||||||
|
args.project_id,
|
||||||
|
args.issue_iid,
|
||||||
|
args.target_project_id,
|
||||||
|
args.target_issue_iid,
|
||||||
|
args.link_type
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
content: [{ type: "text", text: JSON.stringify(link, null, 2) }],
|
content: [{ type: "text", text: JSON.stringify(link, null, 2) }],
|
||||||
};
|
};
|
||||||
@ -2077,9 +2181,25 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|||||||
|
|
||||||
case "delete_issue_link": {
|
case "delete_issue_link": {
|
||||||
const args = DeleteIssueLinkSchema.parse(request.params.arguments);
|
const args = DeleteIssueLinkSchema.parse(request.params.arguments);
|
||||||
await deleteIssueLink(args.project_id, args.issue_iid, args.issue_link_id);
|
await deleteIssueLink(
|
||||||
|
args.project_id,
|
||||||
|
args.issue_iid,
|
||||||
|
args.issue_link_id
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
content: [{ type: "text", text: JSON.stringify({ status: "success", message: "Issue link deleted successfully" }, null, 2) }],
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: JSON.stringify(
|
||||||
|
{
|
||||||
|
status: "success",
|
||||||
|
message: "Issue link deleted successfully",
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2093,7 +2213,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|||||||
|
|
||||||
case "get_label": {
|
case "get_label": {
|
||||||
const args = GetLabelSchema.parse(request.params.arguments);
|
const args = GetLabelSchema.parse(request.params.arguments);
|
||||||
const label = await getLabel(args.project_id, args.label_id, args.include_ancestor_groups);
|
const label = await getLabel(
|
||||||
|
args.project_id,
|
||||||
|
args.label_id,
|
||||||
|
args.include_ancestor_groups
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
content: [{ type: "text", text: JSON.stringify(label, null, 2) }],
|
content: [{ type: "text", text: JSON.stringify(label, null, 2) }],
|
||||||
};
|
};
|
||||||
@ -2120,7 +2244,16 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|||||||
const args = DeleteLabelSchema.parse(request.params.arguments);
|
const args = DeleteLabelSchema.parse(request.params.arguments);
|
||||||
await deleteLabel(args.project_id, args.label_id);
|
await deleteLabel(args.project_id, args.label_id);
|
||||||
return {
|
return {
|
||||||
content: [{ type: "text", text: JSON.stringify({ status: "success", message: "Label deleted successfully" }, null, 2) }],
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: JSON.stringify(
|
||||||
|
{ status: "success", message: "Label deleted successfully" },
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@zereight/mcp-gitlab",
|
"name": "@zereight/mcp-gitlab",
|
||||||
"version": "1.0.25",
|
"version": "1.0.27",
|
||||||
"description": "MCP server for using the GitLab API",
|
"description": "MCP server for using the GitLab API",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "zereight",
|
"author": "zereight",
|
||||||
@ -19,7 +19,7 @@
|
|||||||
"build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
|
"build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
|
||||||
"prepare": "npm run build",
|
"prepare": "npm run build",
|
||||||
"watch": "tsc --watch",
|
"watch": "tsc --watch",
|
||||||
"deploy": "npm run build && npm publish"
|
"deploy": "npm publish --access public"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "1.8.0",
|
"@modelcontextprotocol/sdk": "1.8.0",
|
||||||
|
Reference in New Issue
Block a user