add_git_repository
Add a Git repository to the MCP Docs RAG Server for retrieval-augmented generation. Specify a repository URL, optional custom document name, and subdirectory for sparse checkout to organize and access specific content efficiently.
Instructions
Add a git repository to the docs directory with optional sparse checkout. Please do not use 'docs' in the document name.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| document_name | No | Optional: Custom name for the document (defaults to repository name). Use a simple, descriptive name without '-docs' suffix. For example, use 'react' instead of 'react-docs'. | |
| repository_url | Yes | URL of the git repository to clone | |
| subdirectory | No | Optional: Specific subdirectory to sparse checkout (e.g. 'path/to/specific/dir'). This uses Git's sparse-checkout feature to only download the specified directory. |
Input Schema (JSON Schema)
{
"properties": {
"document_name": {
"description": "Optional: Custom name for the document (defaults to repository name). Use a simple, descriptive name without '-docs' suffix. For example, use 'react' instead of 'react-docs'.",
"type": "string"
},
"repository_url": {
"description": "URL of the git repository to clone",
"type": "string"
},
"subdirectory": {
"description": "Optional: Specific subdirectory to sparse checkout (e.g. 'path/to/specific/dir'). This uses Git's sparse-checkout feature to only download the specified directory.",
"type": "string"
}
},
"required": [
"repository_url"
],
"type": "object"
}
Implementation Reference
- src/index.ts:513-551 (handler)MCP CallTool handler case for 'add_git_repository': validates input, invokes cloneRepository helper, handles existing document check and formats success/error responses.case "add_git_repository": { const repositoryUrl = String(request.params.arguments?.repository_url); const subdirectory = request.params.arguments?.subdirectory ? String(request.params.arguments?.subdirectory) : undefined; const documentName = request.params.arguments?.document_name ? String(request.params.arguments?.document_name) : undefined; if (!repositoryUrl) { throw new Error("Repository URL is required"); } const result = await cloneRepository(repositoryUrl, subdirectory, documentName); // If document already exists, inform the user without updating if (result.exists) { return { content: [{ type: "text", text: `Document '${result.name}' already exists. Please use list_documents to view existing documents.` }] }; } // Prepare response message for new document let responseText = `Added git repository: ${result.name}`; if (subdirectory) { responseText += ` (sparse checkout of '${subdirectory}')`; } if (documentName) { responseText += ` with custom name '${documentName}'`; } return { content: [{ type: "text", text: `${responseText}. The index will be created when you query this document for the first time.` }] }; }
- src/index.ts:389-410 (schema)Schema definition for add_git_repository tool in ListTools response, defining parameters: repository_url (required), document_name (optional), subdirectory (optional).{ name: "add_git_repository", description: "Add a git repository to the docs directory with optional sparse checkout. Please do not use 'docs' in the document name.", inputSchema: { type: "object", properties: { repository_url: { type: "string", description: "URL of the git repository to clone" }, document_name: { type: "string", description: "Optional: Custom name for the document (defaults to repository name). Use a simple, descriptive name without '-docs' suffix. For example, use 'react' instead of 'react-docs'." }, subdirectory: { type: "string", description: "Optional: Specific subdirectory to sparse checkout (e.g. 'path/to/specific/dir'). This uses Git's sparse-checkout feature to only download the specified directory." } }, required: ["repository_url"] } },
- src/index.ts:230-256 (helper)Core helper function implementing git clone logic: normal clone or sparse-checkout for subdirectory, checks for existing repos, normalizes name.export async function cloneRepository(repoUrl: string, subdirectory?: string, documentName?: string): Promise<{ name: string; exists: boolean }> { // Use custom document name if provided, otherwise normalize repo name const repoName = documentName || normalizeRepoName(repoUrl); const repoPath = path.join(DOCS_PATH, repoName); // Check if repository already exists if (fs.existsSync(repoPath)) { // Document already exists, don't update it return { name: repoName, exists: true }; } else { if (subdirectory) { // Clone with sparse-checkout for specific subdirectory await execAsync(`mkdir -p "${repoPath}" && cd "${repoPath}" && \ git init && \ git remote add origin ${repoUrl} && \ git config core.sparseCheckout true && \ git config --local core.autocrlf false && \ echo "${subdirectory}/*" >> .git/info/sparse-checkout && \ git pull --depth=1 origin main || git pull --depth=1 origin master`); } else { // Normal clone for the entire repository await execAsync(`cd "${DOCS_PATH}" && git clone ${repoUrl}`); } } return { name: repoName, exists: false }; }
- src/index.ts:64-67 (helper)Utility function to derive document name from repository URL by taking basename and stripping .git.export function normalizeRepoName(repoUrl: string): string { const parts = repoUrl.split('/'); return parts[parts.length - 1].replace('.git', ''); }