Skip to main content
Glama

Huawei CCE MCP Server

impl.ts9.94 kB
import fetch from "node-fetch"; import { z } from 'zod'; // src import { GITLAB_PERSONAL_ACCESS_TOKEN, GITLAB_API_URL } from './constants.js'; import { GitLabForkSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabIssueSchema, GitLabMergeRequestSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabSearchResponseSchema, GitLabTreeSchema, GitLabCommitSchema, CreateRepositoryOptionsSchema, CreateIssueOptionsSchema, CreateMergeRequestOptionsSchema, CreateBranchOptionsSchema, type GitLabFork, type GitLabReference, type GitLabRepository, type GitLabIssue, type GitLabMergeRequest, type GitLabContent, type GitLabCreateUpdateFileResponse, type GitLabSearchResponse, type GitLabTree, type GitLabCommit, type FileOperation, } from '../../schemas/index.js'; // each function gets the params, some are optional // each returns a primse or specific type export async function forkProject( projectId: string, namespace?: string ): Promise<GitLabFork> { const url = `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/fork`; const queryParams = namespace ? `?namespace=${encodeURIComponent(namespace)}` : ''; const response = await fetch(url + queryParams, { method: "POST", headers: { "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`, "Content-Type": "application/json" } }); if (!response.ok) { throw new Error(`GitLab API error: ${response.statusText}`); } // parse the response return GitLabForkSchema.parse(await response.json()); } export async function createBranch( projectId: string, options: z.infer<typeof CreateBranchOptionsSchema> ): Promise<GitLabReference> { const response = await fetch( `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/branches`, { method: "POST", headers: { "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`, "Content-Type": "application/json" }, // for body, use stringification body: JSON.stringify({ branch: options.name, ref: options.ref }) } ); if (!response.ok) { throw new Error(`GitLab API error: ${response.statusText}`); } return GitLabReferenceSchema.parse(await response.json()); } export async function getFileContents( projectId: string, filePath: string, ref?: string ): Promise<GitLabContent> { const encodedPath = encodeURIComponent(filePath); let url = `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/files/${encodedPath}`; if (ref) { url += `?ref=${encodeURIComponent(ref)}`; } else { url += '?ref=HEAD'; } const response = await fetch(url, { headers: { "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}` } }); if (!response.ok) { throw new Error(`GitLab API error: ${response.statusText}`); } const data = GitLabContentSchema.parse(await response.json()); if (!Array.isArray(data) && data.content) { data.content = Buffer.from(data.content, 'base64').toString('utf8'); } return data; } export async function createIssue( projectId: string, options: z.infer<typeof CreateIssueOptionsSchema> ): Promise<GitLabIssue> { const response = await fetch( `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/issues`, { method: "POST", headers: { "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`, "Content-Type": "application/json" }, body: JSON.stringify({ title: options.title, description: options.description, assignee_ids: options.assignee_ids, milestone_id: options.milestone_id, labels: options.labels?.join(',') }) } ); if (!response.ok) { throw new Error(`GitLab API error: ${response.statusText}`); } return GitLabIssueSchema.parse(await response.json()); } export async function createMergeRequest( projectId: string, options: z.infer<typeof CreateMergeRequestOptionsSchema> ): Promise<GitLabMergeRequest> { const response = await fetch( `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests`, { method: "POST", headers: { "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`, "Content-Type": "application/json" }, body: JSON.stringify({ title: options.title, description: options.description, source_branch: options.source_branch, target_branch: options.target_branch, allow_collaboration: options.allow_collaboration, draft: options.draft }) } ); if (!response.ok) { throw new Error(`GitLab API error: ${response.statusText}`); } return GitLabMergeRequestSchema.parse(await response.json()); } export async function createOrUpdateFile( projectId: string, filePath: string, content: string, commitMessage: string, branch: string, previousPath?: string ): Promise<GitLabCreateUpdateFileResponse> { const encodedPath = encodeURIComponent(filePath); const url = `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/files/${encodedPath}`; const body = { branch, content, commit_message: commitMessage, ...(previousPath ? { previous_path: previousPath } : {}) }; // Check if file exists let method = "POST"; try { await getFileContents(projectId, filePath, branch); method = "PUT"; } catch (error) { // File doesn't exist, use POST } const response = await fetch(url, { method, headers: { "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`, "Content-Type": "application/json" }, body: JSON.stringify(body) }); if (!response.ok) { throw new Error(`GitLab API error: ${response.statusText}`); } return GitLabCreateUpdateFileResponseSchema.parse(await response.json()); } export async function createTree( projectId: string, files: FileOperation[], ref?: string ): Promise<GitLabTree> { const response = await fetch( `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/tree`, { method: "POST", headers: { "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`, "Content-Type": "application/json" }, body: JSON.stringify({ files: files.map(file => ({ file_path: file.path, content: file.content })), ...(ref ? { ref } : {}) }) } ); if (!response.ok) { throw new Error(`GitLab API error: ${response.statusText}`); } return GitLabTreeSchema.parse(await response.json()); } export async function createCommit( projectId: string, message: string, branch: string, actions: FileOperation[] ): Promise<GitLabCommit> { const response = await fetch( `${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/commits`, { method: "POST", headers: { "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`, "Content-Type": "application/json" }, body: JSON.stringify({ branch, commit_message: message, actions: actions.map(action => ({ action: "create", file_path: action.path, content: action.content })) }) } ); if (!response.ok) { throw new Error(`GitLab API error: ${response.statusText}`); } return GitLabCommitSchema.parse(await response.json()); } export async function searchProjects( query: string, page: number = 1, perPage: number = 20 ): Promise<GitLabSearchResponse> { const url = new URL(`${GITLAB_API_URL}/projects`); url.searchParams.append("search", query); url.searchParams.append("page", page.toString()); url.searchParams.append("per_page", perPage.toString()); const response = await fetch(url.toString(), { headers: { "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}` } }); if (!response.ok) { throw new Error(`GitLab API error: ${response.statusText}`); } const projects = await response.json(); return GitLabSearchResponseSchema.parse({ count: parseInt(response.headers.get("X-Total") || "0"), items: projects }); } export async function createRepository( options: z.infer<typeof CreateRepositoryOptionsSchema> ): Promise<GitLabRepository> { const response = await fetch(`${GITLAB_API_URL}/projects`, { method: "POST", headers: { "Authorization": `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`, "Content-Type": "application/json" }, body: JSON.stringify({ name: options.name, description: options.description, visibility: options.visibility, initialize_with_readme: options.initialize_with_readme }) }); if (!response.ok) { throw new Error(`GitLab API error: ${response.statusText}`); } return GitLabRepositorySchema.parse(await response.json()); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TehilaTheStudent/try-cce-gitlab'

If you have feedback or need assistance with the MCP directory API, please join our Discord server