Skip to main content
Glama

Git MCP Server

git-clone.tool.ts3.91 kB
/** * @fileoverview Git clone tool - clone a repository from a remote URL * @module mcp-server/tools/definitions/git-clone */ import { z } from 'zod'; import type { ToolDefinition } from '../utils/toolDefinition.js'; import { withToolAuth } from '@/mcp-server/transports/auth/lib/withAuth.js'; import { DepthSchema } from '../schemas/common.js'; import { createToolHandler, type ToolLogicDependencies, } from '../utils/toolHandlerFactory.js'; import { createJsonFormatter, type VerbosityLevel, } from '../utils/json-response-formatter.js'; const TOOL_NAME = 'git_clone'; const TOOL_TITLE = 'Git Clone'; const TOOL_DESCRIPTION = 'Clone a repository from a remote URL to a local path. Supports HTTP/HTTPS and SSH URLs, with optional shallow cloning.'; const InputSchema = z.object({ url: z.string().url().describe('Remote repository URL to clone from.'), localPath: z .string() .min(1) .describe('Local path where the repository should be cloned.'), branch: z .string() .optional() .describe('Specific branch to clone (defaults to remote HEAD).'), depth: DepthSchema, bare: z .boolean() .default(false) .describe('Create a bare repository (no working directory).'), mirror: z .boolean() .default(false) .describe('Create a mirror clone (implies bare).'), }); const OutputSchema = z.object({ success: z.boolean().describe('Indicates if the operation was successful.'), remoteUrl: z.string().describe('The remote URL that was cloned.'), localPath: z.string().describe('Local path where repository was cloned.'), branch: z.string().describe('The branch that was checked out.'), commitHash: z.string().optional().describe('Current HEAD commit hash.'), }); type ToolInput = z.infer<typeof InputSchema>; type ToolOutput = z.infer<typeof OutputSchema>; async function gitCloneLogic( input: ToolInput, { provider, appContext }: ToolLogicDependencies, ): Promise<ToolOutput> { // Build options object with only defined properties const cloneOptions: { remoteUrl: string; localPath: string; branch?: string; depth?: number; bare?: boolean; mirror?: boolean; } = { remoteUrl: input.url, localPath: input.localPath, bare: input.bare, mirror: input.mirror, }; if (input.branch !== undefined) { cloneOptions.branch = input.branch; } if (input.depth !== undefined) { cloneOptions.depth = input.depth; } const result = await provider.clone(cloneOptions, { workingDirectory: input.localPath, requestContext: appContext, tenantId: appContext.tenantId || 'default-tenant', }); return { success: result.success, remoteUrl: result.remoteUrl, localPath: result.localPath, branch: result.branch, }; } /** * Filter git_clone output based on verbosity level. * * Verbosity levels: * - minimal: Success, local path, and remote URL only * - standard: Above + branch and commit hash (RECOMMENDED) * - full: Complete output */ function filterGitCloneOutput( result: ToolOutput, level: VerbosityLevel, ): Partial<ToolOutput> { // minimal: Essential info only if (level === 'minimal') { return { success: result.success, remoteUrl: result.remoteUrl, localPath: result.localPath, }; } // standard & full: Complete output return result; } // Create JSON response formatter with verbosity filtering const responseFormatter = createJsonFormatter<ToolOutput>({ filter: filterGitCloneOutput, }); export const gitCloneTool: ToolDefinition< typeof InputSchema, typeof OutputSchema > = { name: TOOL_NAME, title: TOOL_TITLE, description: TOOL_DESCRIPTION, inputSchema: InputSchema, outputSchema: OutputSchema, annotations: { readOnlyHint: false }, logic: withToolAuth( ['tool:git:write'], createToolHandler(gitCloneLogic, { skipPathResolution: true }), ), responseFormatter, };

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/cyanheads/git-mcp-server'

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