-
Notifications
You must be signed in to change notification settings - Fork 8
📦 NEW: Docs MCP Server #96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
b17280c
📦 NEW: Docs MCP Server
arre-ankit 112dc18
👌 IMPROVE: README.md updated
arre-ankit b8c7181
🐛 FIX: formating
arre-ankit ac35659
👌 IMPROVE: Review by SI
msaaddev a795308
🐛 FIX: utils functions
arre-ankit 9225cc0
👌 IMPROVE: Review by SI
msaaddev 4263cac
👌 IMPROVE: Readme
msaaddev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,63 @@ | ||
| ## Langbase CLI | ||
| # Langbase CLI | ||
|
|
||
| Langbase CLI is a command line interface for Langbase. It allows you to interact with Langbase from the command line. | ||
| The Langbase CLI is a command-line interface for Langbase. It provides a set of commands to interact with the Langbase SDK and perform various tasks related to AI development. | ||
|
|
||
| ## Documentation | ||
| ## Usage | ||
|
|
||
| Please follow the [Langbase documentation](https://langbase.com/docs) for the latest information. | ||
| ### Langbase Docs MCP Server | ||
|
|
||
| Integrate the Langbase Docs MCP server into your IDEs and Claude Desktop. | ||
|
|
||
| #### Cursor | ||
| - Open Cursor settings | ||
| - Navigate to the MCP settings | ||
| - Click on the `+` button to add a new global MCP server | ||
| - Paste the following configuration in the `mcp.json` file: | ||
| ```json | ||
| { | ||
| "mcpServers": { | ||
| "Langbase": { | ||
| "command": "npx", | ||
| "args": ["@langbase/cli","docs-mcp-server"] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| #### Windsurf | ||
| - Navigate to Windsurf - Settings > Advanced Settings | ||
| - You will find the option to Add Server | ||
| - Click “Add custom server +” | ||
| - Paste the following configuration in the `mcp_config.json` file: | ||
| ```json | ||
| { | ||
| "mcpServers": { | ||
| "Langbase": { | ||
| "command": "npx", | ||
| "args": ["@langbase/cli", "docs-mcp-server"] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| #### Claude Desktop | ||
| - Open Claude Desktop File Menu | ||
| - Navigate to the settings | ||
| - Go to Developer Tab | ||
| - Click on the Edit Config button | ||
| - Paste the following configuration in the `claude_desktop_config.json` file: | ||
| ```json | ||
| { | ||
| "mcpServers": { | ||
| "Langbase": { | ||
| "command": "npx", | ||
| "args": ["@langbase/cli", "docs-mcp-server"] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Next steps | ||
|
|
||
| - Read the [Langbase SDK documentation](https://langbase.com/docs/sdk) for more details | ||
| - Join our [Discord](https://langbase.com/discord) community for feedback, requests, and support | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| import { JSDOM } from 'jsdom'; | ||
|
|
||
| /** | ||
| * Fetches a list of all the docs on the langbase website | ||
| * | ||
| * | ||
| * @returns {Promise<string>} A promise that resolves to a string of all the docs on the langbase website | ||
| */ | ||
| export async function fetchDocsList() { | ||
| try { | ||
| const response = await fetch('https://langbase.com/docs/llms.txt'); | ||
| if (!response.ok) { | ||
| throw new Error('Failed to fetch docs'); | ||
| } | ||
|
|
||
| const text = await response.text(); | ||
| return text; | ||
| } catch (error) { | ||
| throw new Error('Failed to fetch docs ' + JSON.stringify(error)); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Fetches and converts a blog post to markdown | ||
| * | ||
| * | ||
| * @param {string} url - The URL of the blog post to fetch | ||
| * @returns {Promise<string>} A promise that resolves to a string of the blog post in markdown format | ||
| */ | ||
| export async function fetchDocsPost(url: string): Promise<string> { | ||
| try { | ||
| const response = await fetch(url); | ||
| if (!response.ok) { | ||
| throw new Error('Failed to fetch blog post'); | ||
| } | ||
|
|
||
| const html = await response.text(); | ||
|
|
||
| const dom = new JSDOM(html); | ||
| const document = dom.window.document; | ||
|
|
||
| // Remove Next.js initialization code | ||
| const scripts = document.querySelectorAll('script'); | ||
| scripts.forEach(script => script.remove()); | ||
|
|
||
| // Get the main content | ||
| const content = document.body.textContent?.trim() || ''; | ||
| if (!content) { | ||
| throw new Error('No content found in docs'); | ||
| } | ||
|
|
||
| return content; | ||
| } catch (error) { | ||
| throw new Error( | ||
| `Failed to fetch docs: ${error instanceof Error ? error.message : 'Something went wrong. Please try again.'}` | ||
| ); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,181 @@ | ||
| import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; | ||
| import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; | ||
| import { z } from 'zod'; | ||
| import { fetchDocsList, fetchDocsPost } from './docs'; | ||
| import { getRelevanceScore } from '@/utils/get-score'; | ||
|
|
||
| export async function docsMcpServer() { | ||
| const server = new McpServer({ | ||
| name: 'langbase-docs-server', | ||
| version: '0.1.0' | ||
| }); | ||
|
|
||
| server.tool( | ||
| 'docs-route-finder', | ||
| "Searches through all available documentation routes and returns relevant paths based on the user's query. This tool helps navigate the documentation by finding the most appropriate sections that match the search criteria.", | ||
| { | ||
| query: z.string() | ||
| .describe(`A refined search term extracted from the user's question. | ||
| For example, if user asks 'How do I create a pipe?', the query would be 'SDK Pipe'. | ||
| This should be the specific concept or topic to search for in the documentation. | ||
| Treat keyword add as create if user ask for Eg. 'How do I add memory to pipe?' the query should be 'create memory'`) | ||
| }, | ||
| async ({ query }) => { | ||
| const docs = await fetchDocsList(); | ||
| // search through the docs and return the most relevent path based on the query | ||
| const docLines = docs.split('\n').filter(line => line.trim()); | ||
|
|
||
| // Score and sort the documentation entries | ||
| const scoredDocs = docLines | ||
| .map(line => ({ | ||
| line, | ||
| score: getRelevanceScore(line, query) | ||
| })) | ||
| .sort((a, b) => b.score - a.score) | ||
| .filter(doc => doc.score > 0) | ||
| .slice(0, 3); // Get top 3 most relevant results | ||
|
|
||
| const hasRelevantDocs = scoredDocs.length === 0; | ||
|
|
||
| if (hasRelevantDocs) { | ||
| return { | ||
| content: [ | ||
| { | ||
| type: 'text', | ||
| text: | ||
| 'No relevant documentation found for the query: ' + | ||
| query | ||
| } | ||
| ] | ||
| }; | ||
| } | ||
|
|
||
| const results = scoredDocs.map(doc => doc.line).join('\n'); | ||
|
|
||
| return { | ||
| content: [ | ||
| { | ||
| type: 'text', | ||
| text: results | ||
| } | ||
| ] | ||
| }; | ||
| } | ||
| ); | ||
|
|
||
| server.tool( | ||
| 'sdk-documentation-fetcher', | ||
| 'Fetches detailed SDK documentation, specializing in implementation guides for core features like pipes, memory, and tools. This is the primary source for the latest SDK documentation and should be consulted first for questions about creating or implementing SDK components. Use this tool for detailed step-by-step instructions on building pipes, configuring memory systems, and developing custom tools.', | ||
| { | ||
| url: z | ||
| .string() | ||
| .describe( | ||
| 'URL of a specific SDK page to fetch. Format: /sdk/...' | ||
| ) | ||
| }, | ||
| async ({ url }) => { | ||
| const content = await fetchDocsPost( | ||
| `https://langbase.com/docs${url}` | ||
| ); | ||
| return { | ||
| content: [ | ||
| { | ||
| type: 'text', | ||
| text: content | ||
| } | ||
| ] | ||
| }; | ||
| } | ||
| ); | ||
|
|
||
| server.tool( | ||
| 'examples-tool', | ||
| 'Fetches code examples and sample implementations from the documentation. Use this tool when users specifically request examples, sample code, or implementation demonstrations. This tool provides practical code snippets and complete working examples that demonstrate how to implement various features.', | ||
| { | ||
| url: z | ||
| .string() | ||
| .describe( | ||
| 'URL of a specific examples page to fetch. Format: /examples/...' | ||
| ) | ||
| }, | ||
| async ({ url }) => { | ||
| const content = await fetchDocsPost( | ||
| `https://langbase.com/docs${url}` | ||
| ); | ||
| return { | ||
| content: [ | ||
| { | ||
| type: 'text', | ||
| text: content | ||
| } | ||
| ] | ||
| }; | ||
arre-ankit marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| ); | ||
|
|
||
| server.tool( | ||
| 'guide-tool', | ||
| 'Fetches detailed guides and tutorials from the documentation. Use this tool when users explicitly request guides, tutorials, or how-to content. This tool provides step-by-step instructions and practical examples for implementing various features.', | ||
| { | ||
| url: z | ||
| .string() | ||
| .describe( | ||
| 'URL of a specific guide page to fetch. Format: /guides/...' | ||
| ) | ||
| }, | ||
| async ({ url }) => { | ||
| const content = await fetchDocsPost( | ||
| `https://langbase.com/docs${url}` | ||
| ); | ||
| return { | ||
| content: [ | ||
| { | ||
| type: 'text', | ||
| text: content | ||
| } | ||
| ] | ||
| }; | ||
| } | ||
| ); | ||
|
|
||
| server.tool( | ||
| 'api-reference-tool', | ||
| 'Fetches API reference documentation. Use this tool ONLY when the user explicitly asks about API endpoints, REST API calls, or programmatically creating/updating/deleting resources (like pipes, memory, etc.) through the API interface. For general SDK implementation questions, use the sdk-documentation-fetcher instead.', | ||
| { | ||
| url: z | ||
| .string() | ||
| .describe( | ||
| 'URL of a specific api-reference page to fetch. Format: /api-reference/...' | ||
| ) | ||
| }, | ||
| async ({ url }) => { | ||
| const content = await fetchDocsPost( | ||
| `https://langbase.com/docs${url}` | ||
| ); | ||
| return { | ||
| content: [ | ||
| { | ||
| type: 'text', | ||
| text: content | ||
| } | ||
| ] | ||
| }; | ||
| } | ||
| ); | ||
|
|
||
| async function main() { | ||
| const transport = new StdioServerTransport(); | ||
|
|
||
| try { | ||
| await server.connect(transport); | ||
| } catch (error) { | ||
| console.error('Error connecting to transport:', error); | ||
| process.exit(1); | ||
| } | ||
| } | ||
|
|
||
| main().catch(error => { | ||
| console.error('Something went wrong:', error); | ||
| process.exit(1); | ||
| }); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.