Merge pull request #221 from upstash/pr-207

feat: version support
This commit is contained in:
Enes Akar 2025-05-24 08:15:07 -07:00 committed by GitHub
commit b0352b17e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 14 additions and 19 deletions

1
.gitignore vendored
View File

@ -173,3 +173,4 @@ dist
# Finder (MacOS) folder config # Finder (MacOS) folder config
.DS_Store .DS_Store
package-lock.json

View File

@ -39,7 +39,7 @@ server.tool(
"resolve-library-id", "resolve-library-id",
`Resolves a package/product name to a Context7-compatible library ID and returns a list of matching libraries. `Resolves a package/product 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. You MUST call this function before 'get-library-docs' to obtain a valid Context7-compatible library ID UNLESS the user explicitly provides a library ID in the format '/org/project' or '/org/project/version' in their query.
Selection Process: Selection Process:
1. Analyze the query to understand what library/package the user is looking for 1. Analyze the query to understand what library/package the user is looking for
@ -95,11 +95,12 @@ For ambiguous queries, request clarification before proceeding with a best-guess
text: `Available Libraries (top matches): text: `Available Libraries (top matches):
Each result includes: Each result includes:
- Library ID: Context7-compatible identifier (format: /org/repo) - Library ID: Context7-compatible identifier (format: /org/project)
- Name: Library or package name - Name: Library or package name
- Description: Short summary - Description: Short summary
- Code Snippets: Number of available code examples - Code Snippets: Number of available code examples
- Trust Score: Authority indicator - Trust Score: Authority indicator
- Versions: List of versions if available. Use one of those versions if and only if the user explicitly provides a version in their query.
For best results, select libraries based on name match, trust score, snippet coverage, and relevance to your use case. For best results, select libraries based on name match, trust score, snippet coverage, and relevance to your use case.
@ -114,12 +115,12 @@ ${resultsText}`,
server.tool( server.tool(
"get-library-docs", "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.", "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, UNLESS the user explicitly provides a library ID in the format '/org/project' or '/org/project/version' in their query.",
{ {
context7CompatibleLibraryID: z context7CompatibleLibraryID: z
.string() .string()
.describe( .describe(
"Exact Context7-compatible library ID (e.g., 'mongodb/docs', 'vercel/nextjs') retrieved from 'resolve-library-id'." "Exact Context7-compatible library ID (e.g., '/mongodb/docs', '/vercel/next.js', '/supabase/supabase', '/vercel/next.js/v14.3.0-canary.87') retrieved from 'resolve-library-id' or directly from user query in the format '/org/project' or '/org/project/version'."
), ),
topic: z topic: z
.string() .string()
@ -134,20 +135,9 @@ server.tool(
), ),
}, },
async ({ context7CompatibleLibraryID, tokens = DEFAULT_MINIMUM_TOKENS, topic = "" }) => { async ({ context7CompatibleLibraryID, tokens = DEFAULT_MINIMUM_TOKENS, topic = "" }) => {
// Extract folders parameter if present in the ID const documentationText = await fetchLibraryDocumentation(context7CompatibleLibraryID, {
let folders = "";
let libraryId = context7CompatibleLibraryID;
if (context7CompatibleLibraryID.includes("?folders=")) {
const [id, foldersParam] = context7CompatibleLibraryID.split("?folders=");
libraryId = id;
folders = foldersParam;
}
const documentationText = await fetchLibraryDocumentation(libraryId, {
tokens, tokens,
topic, topic,
folders,
}); });
if (!documentationText) { if (!documentationText) {

View File

@ -35,7 +35,6 @@ export async function fetchLibraryDocumentation(
options: { options: {
tokens?: number; tokens?: number;
topic?: string; topic?: string;
folders?: string;
} = {} } = {}
): Promise<string | null> { ): Promise<string | null> {
try { try {
@ -45,7 +44,6 @@ export async function fetchLibraryDocumentation(
const url = new URL(`${CONTEXT7_API_BASE_URL}/v1/${libraryId}`); const url = new URL(`${CONTEXT7_API_BASE_URL}/v1/${libraryId}`);
if (options.tokens) url.searchParams.set("tokens", options.tokens.toString()); if (options.tokens) url.searchParams.set("tokens", options.tokens.toString());
if (options.topic) url.searchParams.set("topic", options.topic); if (options.topic) url.searchParams.set("topic", options.topic);
if (options.folders) url.searchParams.set("folders", options.folders);
url.searchParams.set("type", DEFAULT_TYPE); url.searchParams.set("type", DEFAULT_TYPE);
const response = await fetch(url, { const response = await fetch(url, {
headers: { headers: {

View File

@ -10,6 +10,7 @@ export interface SearchResult {
totalPages: number; totalPages: number;
stars?: number; stars?: number;
trustScore?: number; trustScore?: number;
versions?: string[];
} }
export interface SearchResponse { export interface SearchResponse {

View File

@ -25,6 +25,11 @@ export function formatSearchResult(result: SearchResult): string {
formattedResult.push(`- Trust Score: ${result.trustScore}`); formattedResult.push(`- Trust Score: ${result.trustScore}`);
} }
// Only add versions if it's a valid value
if (result.versions !== undefined && result.versions.length > 0) {
formattedResult.push(`- Versions: ${result.versions.join(", ")}`);
}
// Join all parts with newlines // Join all parts with newlines
return formattedResult.join("\n"); return formattedResult.join("\n");
} }