get_docs_for_npm_package
Retrieve documentation for npm packages to access README files and API information directly within your IDE.
Instructions
Get the docs for an npm package
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| packageName | Yes | Name of the npm package |
Implementation Reference
- src/server.ts:116-185 (handler)The core handler function for the 'get_docs_for_npm_package' tool. It fetches the latest package metadata from the npm registry, attempts to retrieve the README.md from the GitHub repository (trying common branches: master, main, develop), and falls back to downloading and extracting the package tarball to locate README files if GitHub fails.async ({ packageName }) => { try { console.error(`Processing request for package: ${packageName}`); const npmPackage = await fetch(`https://registry.npmjs.org/${packageName}/latest`).then( res => res.json() as Promise<NpmRegistryResponse>); const tarball = npmPackage.dist.tarball; const repoUrl = npmPackage.repository?.url; let docTxt = ''; // First, try to get docs from GitHub repository if available if (repoUrl) { const repoPath = extractGitHubRepoPath(repoUrl); if (repoPath) { console.error("repoPath", repoPath); // Try multiple branch names to find the README const branches = ['master', 'main', 'develop']; for (const branch of branches) { try { const response = await fetch(`https://raw.githubusercontent.com/${repoPath}/refs/heads/${branch}/README.md`); if (response.ok) { docTxt = await response.text(); break; } } catch (error) { console.error(`Failed to fetch README from ${branch} branch:`, error); continue; } } } } // If no docs found from GitHub, try tarball fallback if (!docTxt) { try { docTxt = await extractTarballAndGetReadme(tarball, packageName); } catch (error) { console.error('Failed to extract tarball:', error); } } // Return the result if (docTxt) { return { content: [{ type: "text", text: docTxt }] }; } else { return { content: [{ type: "text", text: "No documentation found in any common branches or package tarball" }] }; } } catch (error) { console.error('Error in tool execution:', error); return { content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}` }], isError: true }; } }
- src/server.ts:109-115 (schema)Tool schema definition including title, description, and Zod-validated input schema requiring a 'packageName' string.{ title: 'Get docs for an npm package', description: 'Get the docs for an npm package', inputSchema: { packageName: z.string().describe("Name of the npm package") } },
- src/server.ts:107-186 (registration)Registration of the 'get_docs_for_npm_package' tool with the MCP server, including name, schema, and inline handler.server.registerTool( 'get_docs_for_npm_package', { title: 'Get docs for an npm package', description: 'Get the docs for an npm package', inputSchema: { packageName: z.string().describe("Name of the npm package") } }, async ({ packageName }) => { try { console.error(`Processing request for package: ${packageName}`); const npmPackage = await fetch(`https://registry.npmjs.org/${packageName}/latest`).then( res => res.json() as Promise<NpmRegistryResponse>); const tarball = npmPackage.dist.tarball; const repoUrl = npmPackage.repository?.url; let docTxt = ''; // First, try to get docs from GitHub repository if available if (repoUrl) { const repoPath = extractGitHubRepoPath(repoUrl); if (repoPath) { console.error("repoPath", repoPath); // Try multiple branch names to find the README const branches = ['master', 'main', 'develop']; for (const branch of branches) { try { const response = await fetch(`https://raw.githubusercontent.com/${repoPath}/refs/heads/${branch}/README.md`); if (response.ok) { docTxt = await response.text(); break; } } catch (error) { console.error(`Failed to fetch README from ${branch} branch:`, error); continue; } } } } // If no docs found from GitHub, try tarball fallback if (!docTxt) { try { docTxt = await extractTarballAndGetReadme(tarball, packageName); } catch (error) { console.error('Failed to extract tarball:', error); } } // Return the result if (docTxt) { return { content: [{ type: "text", text: docTxt }] }; } else { return { content: [{ type: "text", text: "No documentation found in any common branches or package tarball" }] }; } } catch (error) { console.error('Error in tool execution:', error); return { content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}` }], isError: true }; } } );
- src/server.ts:36-98 (helper)Helper function to download the npm package tarball, extract it to a temp directory, locate the package folder, find and read README files (various names/cases), and clean up.export async function extractTarballAndGetReadme(tarballUrl: string, packageName: string): Promise<string> { try { // Create a temporary directory for extraction const tempDir = path.join(os.tmpdir(), `npm-docs-${packageName}-${Date.now()}`); await fs.ensureDir(tempDir); // Download the tarball const response = await fetch(tarballUrl); if (!response.ok) { throw new Error(`Failed to download tarball: ${response.statusText}`); } const tarballBuffer = await response.arrayBuffer(); // Extract filename from tarball URL const urlParts = tarballUrl.split('/'); const tarballFilename = urlParts[urlParts.length - 1]; if (!tarballFilename) { throw new Error('Could not extract filename from tarball URL'); } const tarballPath = path.join(tempDir, tarballFilename); // Write tarball to file await fs.writeFile(tarballPath, Buffer.from(tarballBuffer)); // Extract the tarball await tar.extract({ file: tarballPath, cwd: tempDir }); // Find the package directory (usually named package-version) const extractedDirs = await fs.readdir(tempDir); const packageDir = extractedDirs.find(dir => dir.startsWith('package')); if (!packageDir) { throw new Error('Could not find package directory in tarball'); } const packagePath = path.join(tempDir, packageDir); // Look for README files (case insensitive) const readmeFiles = ['README.md', 'readme.md', 'README.txt', 'readme.txt', 'README']; let readmeContent = ''; for (const readmeFile of readmeFiles) { const readmePath = path.join(packagePath, readmeFile); if (await fs.pathExists(readmePath)) { readmeContent = await fs.readFile(readmePath, 'utf-8'); break; } } // Clean up temporary files await fs.remove(tempDir); return readmeContent || 'No README file found in package'; } catch (error) { console.error('Error extracting tarball:', error); throw error; } }
- src/server.ts:11-33 (helper)Helper function to parse GitHub repository URL (handling git+ prefix and .git suffix) and extract the owner/repo path for raw.githubusercontent.com access.function extractGitHubRepoPath(githubUrl: string): string | null { try { // Handle git+https:// URLs const cleanUrl = githubUrl.replace(/^git\+/, ''); // Parse the URL const url = new URL(cleanUrl); // Check if it's a GitHub URL if (url.hostname === 'github.com') { // Extract the pathname and remove leading slash const path = url.pathname.substring(1); // Remove .git extension if present return path.replace(/\.git$/, ''); } return null; } catch (error) { console.error('Error parsing GitHub URL:', error); return null; } }
- src/types/index.ts:1-10 (schema)TypeScript interface defining the structure of the npm registry response used in the handler for accessing repository URL and tarball.export interface NpmRegistryResponse{ name: string repository?:{ type?: "git" url: string } dist:{ tarball: string } }