2025-04-03 12:32:03 +03:00
# ! / u s r / b i n / e n v n o d e
2025-03-31 15:19:29 +03:00
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js" ;
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js" ;
import { z } from "zod" ;
2025-04-17 01:03:45 +03:00
import { searchLibraries , fetchLibraryDocumentation } from "./lib/api.js" ;
import { formatSearchResults } from "./lib/utils.js" ;
2025-05-01 20:27:03 +07:00
import dotenv from "dotenv" ;
2025-04-17 01:03:45 +03:00
2025-05-01 20:27:03 +07:00
// Load environment variables from .env file if present
dotenv . config ( ) ;
// Get DEFAULT_MINIMUM_TOKENS from environment variable or use default
2025-05-01 22:50:40 +03:00
let DEFAULT_MINIMUM_TOKENS = 10000 ;
2025-05-01 20:27:03 +07:00
if ( process . env . DEFAULT_MINIMUM_TOKENS ) {
const parsedValue = parseInt ( process . env . DEFAULT_MINIMUM_TOKENS , 10 ) ;
if ( ! isNaN ( parsedValue ) && parsedValue > 0 ) {
DEFAULT_MINIMUM_TOKENS = parsedValue ;
} else {
2025-05-01 22:50:40 +03:00
console . warn (
` Warning: Invalid DEFAULT_MINIMUM_TOKENS value provided in environment variable. Using default value of 10000 `
2025-05-01 20:27:03 +07:00
) ;
}
}
2025-03-31 15:19:29 +03:00
// Create server instance
const server = new McpServer ( {
2025-04-03 11:51:17 +03:00
name : "Context7" ,
2025-04-11 15:10:59 +02:00
description : "Retrieves up-to-date documentation and code examples for any library." ,
2025-04-23 20:02:53 +03:00
version : "1.0.6" ,
2025-03-31 15:19:29 +03:00
capabilities : {
resources : { } ,
tools : { } ,
} ,
} ) ;
2025-04-03 11:51:17 +03:00
// Register Context7 tools
2025-03-31 15:19:29 +03:00
server . tool (
2025-04-11 10:01:28 +02:00
"resolve-library-id" ,
2025-05-02 00:09:19 +03:00
` Resolves a package name to a Context7-compatible library ID and returns a list of matching libraries.
You MUST call this function before 'get-library-docs' to obtain a valid Context7 - compatible library ID .
When selecting the best match , consider :
- Name similarity to the query
- Description relevance
- Code Snippet count ( documentation coverage )
- GitHub Stars ( popularity )
Return the selected library ID and explain your choice . If there are multiple good matches , mention this but proceed with the most relevant one . ` ,
2025-04-04 20:29:10 +03:00
{
libraryName : z
. string ( )
2025-04-19 14:50:49 +03:00
. describe ( "Library name to search for and retrieve a Context7-compatible library ID." ) ,
2025-04-04 20:29:10 +03:00
} ,
async ( { libraryName } ) = > {
2025-04-19 14:50:49 +03:00
const searchResponse = await searchLibraries ( libraryName ) ;
2025-03-31 15:19:29 +03:00
2025-04-17 01:03:45 +03:00
if ( ! searchResponse || ! searchResponse . results ) {
2025-03-31 15:19:29 +03:00
return {
content : [
{
type : "text" ,
2025-04-04 18:20:07 +03:00
text : "Failed to retrieve library documentation data from Context7" ,
2025-03-31 15:19:29 +03:00
} ,
] ,
} ;
}
2025-04-17 01:03:45 +03:00
if ( searchResponse . results . length === 0 ) {
2025-03-31 15:19:29 +03:00
return {
content : [
{
type : "text" ,
2025-04-17 01:03:45 +03:00
text : "No documentation libraries available" ,
2025-03-31 15:19:29 +03:00
} ,
] ,
} ;
}
2025-04-17 01:03:45 +03:00
const resultsText = formatSearchResults ( searchResponse ) ;
2025-03-31 15:19:29 +03:00
return {
content : [
{
type : "text" ,
2025-05-02 00:09:19 +03:00
text : ` Available Libraries (top matches):
Each result includes :
- Library ID : Context7 - compatible identifier ( format : / o r g / r e p o )
- Name : Library or package name
- Description : Short summary
- Code Snippets : Number of available code examples
- GitHub Stars : Popularity indicator
For best results , select libraries based on name match , popularity ( stars ) , snippet coverage , and relevance to your use case .
-- -
$ { resultsText } ` ,
2025-03-31 15:19:29 +03:00
} ,
] ,
} ;
}
) ;
server . tool (
2025-04-11 10:01:28 +02:00
"get-library-docs" ,
"Fetches up-to-date documentation for a library. You must call 'resolve-library-id' first to obtain the exact Context7-compatible library ID required to use this tool." ,
2025-03-31 15:19:29 +03:00
{
2025-04-11 10:01:28 +02:00
context7CompatibleLibraryID : z
2025-04-03 11:51:17 +03:00
. string ( )
. describe (
2025-04-11 10:01:28 +02:00
"Exact Context7-compatible library ID (e.g., 'mongodb/docs', 'vercel/nextjs') retrieved from 'resolve-library-id'."
2025-04-03 11:51:17 +03:00
) ,
topic : z
. string ( )
2025-04-04 18:20:07 +03:00
. optional ( )
2025-04-11 10:01:28 +02:00
. describe ( "Topic to focus documentation on (e.g., 'hooks', 'routing')." ) ,
2025-04-03 11:51:17 +03:00
tokens : z
2025-04-19 16:14:24 +03:00
. preprocess ( ( val ) = > ( typeof val === "string" ? Number ( val ) : val ) , z . number ( ) )
2025-04-23 00:18:15 +03:00
. transform ( ( val ) = > ( val < DEFAULT_MINIMUM_TOKENS ? DEFAULT_MINIMUM_TOKENS : val ) )
2025-04-03 11:51:17 +03:00
. optional ( )
. describe (
2025-04-17 01:03:45 +03:00
` Maximum number of tokens of documentation to retrieve (default: ${ DEFAULT_MINIMUM_TOKENS } ). Higher values provide more context but consume more tokens. `
2025-04-03 11:51:17 +03:00
) ,
2025-03-31 15:19:29 +03:00
} ,
2025-04-17 01:03:45 +03:00
async ( { context7CompatibleLibraryID , tokens = DEFAULT_MINIMUM_TOKENS , topic = "" } ) = > {
// Extract folders parameter if present in the ID
let folders = "" ;
let libraryId = context7CompatibleLibraryID ;
if ( context7CompatibleLibraryID . includes ( "?folders=" ) ) {
const [ id , foldersParam ] = context7CompatibleLibraryID . split ( "?folders=" ) ;
libraryId = id ;
folders = foldersParam ;
}
const documentationText = await fetchLibraryDocumentation ( libraryId , {
2025-04-11 10:01:28 +02:00
tokens ,
2025-04-17 01:03:45 +03:00
topic ,
folders ,
} ) ;
2025-03-31 15:19:29 +03:00
2025-04-03 11:51:17 +03:00
if ( ! documentationText ) {
2025-03-31 15:19:29 +03:00
return {
content : [
{
type : "text" ,
2025-04-11 10:01:28 +02:00
text : "Documentation not found or not finalized for this library. This might have happened because you used an invalid Context7-compatible library ID. To get a valid Context7-compatible library ID, use the 'resolve-library-id' with the package name you wish to retrieve documentation for." ,
2025-03-31 15:19:29 +03:00
} ,
] ,
} ;
}
2025-04-03 11:51:17 +03:00
return {
content : [
{
type : "text" ,
text : documentationText ,
} ,
] ,
} ;
2025-03-31 15:19:29 +03:00
}
) ;
async function main() {
const transport = new StdioServerTransport ( ) ;
await server . connect ( transport ) ;
2025-04-03 11:51:17 +03:00
console . error ( "Context7 Documentation MCP Server running on stdio" ) ;
2025-03-31 15:19:29 +03:00
}
main ( ) . catch ( ( error ) = > {
console . error ( "Fatal error in main():" , error ) ;
process . exit ( 1 ) ;
} ) ;