-
Notifications
You must be signed in to change notification settings - Fork 3
MCP docs: Use resource index from cratedb-about
#8
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,21 +2,24 @@ | |||||||||||||||||||||||
| import httpx | ||||||||||||||||||||||||
| from mcp.server.fastmcp import FastMCP | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| from .knowledge import DOCUMENTATION_INDEX, Queries | ||||||||||||||||||||||||
| from .settings import DOCS_CACHE_TTL, HTTP_URL | ||||||||||||||||||||||||
| from .knowledge import DocumentationIndex, Queries, documentation_url_permitted | ||||||||||||||||||||||||
| from .settings import DOCS_CACHE_TTL, HTTP_TIMEOUT, HTTP_URL | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| # Configure Hishel, an httpx client with caching. | ||||||||||||||||||||||||
| # Define one hour of caching time. | ||||||||||||||||||||||||
| controller = hishel.Controller(allow_stale=True) | ||||||||||||||||||||||||
| storage = hishel.SQLiteStorage(ttl=DOCS_CACHE_TTL) | ||||||||||||||||||||||||
| client = hishel.CacheClient(controller=controller, storage=storage) | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| # Load CrateDB documentation outline. | ||||||||||||||||||||||||
| documentation_index = DocumentationIndex() | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| # Create FastMCP application object. | ||||||||||||||||||||||||
| mcp = FastMCP("cratedb-mcp") | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| def query_cratedb(query: str) -> list[dict]: | ||||||||||||||||||||||||
| return httpx.post(f'{HTTP_URL}/_sql', json={'stmt': query}).json() | ||||||||||||||||||||||||
| return httpx.post(f'{HTTP_URL}/_sql', json={'stmt': query}, timeout=HTTP_TIMEOUT).json() | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| @mcp.tool(description="Send a SQL query to CrateDB, only 'SELECT' queries are allows, queries that" | ||||||||||||||||||||||||
|
|
@@ -27,17 +30,17 @@ def query_sql(query: str): | |||||||||||||||||||||||
| return query_cratedb(query) | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| @mcp.tool(description='Gets an index with CrateDB documentation links to fetch, should download docs' | ||||||||||||||||||||||||
| ' before answering questions. Has documentation name, description and link.') | ||||||||||||||||||||||||
| ' before answering questions. Has documentation title, description, and link.') | ||||||||||||||||||||||||
| def get_cratedb_documentation_index(): | ||||||||||||||||||||||||
| return DOCUMENTATION_INDEX | ||||||||||||||||||||||||
| return documentation_index.items() | ||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add error handling when accessing documentation items. If the outline couldn't be loaded or if there's an error during access, the application would crash. Consider adding error handling to gracefully handle potential issues. def get_cratedb_documentation_index():
- return documentation_index.items()
+ try:
+ return documentation_index.items()
+ except Exception as e:
+ import logging
+ logging.error(f"Failed to access documentation index: {e}")
+ # Return a minimal fallback
+ return []📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| @mcp.tool(description='Downloads the latest CrateDB documentation piece by link.' | ||||||||||||||||||||||||
| ' Only used to download CrateDB docs.') | ||||||||||||||||||||||||
| def fetch_cratedb_docs(link: str): | ||||||||||||||||||||||||
| """Fetches a CrateDB documentation link from GitHub raw content.""" | ||||||||||||||||||||||||
| if 'https://raw.githubusercontent.com/crate/crate/' not in link: | ||||||||||||||||||||||||
| raise ValueError('Only github cratedb links can be fetched.') | ||||||||||||||||||||||||
| return client.get(link).text | ||||||||||||||||||||||||
| """Fetches a CrateDB documentation link.""" | ||||||||||||||||||||||||
| if not documentation_url_permitted(link): | ||||||||||||||||||||||||
| raise ValueError(f'Link is not permitted: {link}') | ||||||||||||||||||||||||
| return client.get(link, timeout=HTTP_TIMEOUT).text | ||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add error handling for HTTP requests. The HTTP GET request doesn't include error handling for timeouts or connection failures, which could cause the application to crash if the documentation source is unavailable. - return client.get(link, timeout=HTTP_TIMEOUT).text
+ try:
+ response = client.get(link, timeout=HTTP_TIMEOUT)
+ response.raise_for_status() # Raise an exception for 4XX/5XX responses
+ return response.text
+ except httpx.TimeoutException:
+ raise ValueError(f"Request timed out after {HTTP_TIMEOUT} seconds: {link}")
+ except httpx.HTTPStatusError as e:
+ raise ValueError(f"HTTP error {e.response.status_code} while fetching: {link}")
+ except httpx.RequestError as e:
+ raise ValueError(f"Request error while fetching: {link} - {str(e)}")📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| @mcp.tool(description="Returns an aggregation of all CrateDB's schema, tables and their metadata") | ||||||||||||||||||||||||
| def get_table_metadata() -> list[dict]: | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error handling for the database query.
Similar to the documentation fetching, the database query doesn't include error handling for timeouts or connection failures.
📝 Committable suggestion
🤖 Prompt for AI Agents