|
1 | | -import httpx |
2 | 1 | from fastmcp import FastMCP |
| 2 | +from fastmcp.tools import Tool |
3 | 3 |
|
4 | 4 | from . import __appname__ |
5 | | -from .knowledge import DocumentationIndex, Queries |
6 | | -from .settings import HTTP_URL, Settings |
7 | | -from .util.sql import sql_is_permitted |
8 | | - |
9 | | -# Load CrateDB documentation outline. |
10 | | -documentation_index = DocumentationIndex() |
| 5 | +from .tool import ( |
| 6 | + fetch_cratedb_docs, |
| 7 | + get_cluster_health, |
| 8 | + get_cratedb_documentation_index, |
| 9 | + get_table_metadata, |
| 10 | + query_sql, |
| 11 | +) |
11 | 12 |
|
12 | 13 | # Create FastMCP application object. |
13 | 14 | mcp: FastMCP = FastMCP(__appname__) |
14 | 15 |
|
15 | 16 |
|
16 | 17 | # ------------------------------------------ |
17 | | -# Text-to-SQL |
| 18 | +# Health / Status |
18 | 19 | # ------------------------------------------ |
19 | | - |
20 | | - |
21 | | -def query_cratedb(query: str) -> list[dict]: |
22 | | - """Sends a `query` to the set `$CRATEDB_CLUSTER_URL`""" |
23 | | - url = HTTP_URL |
24 | | - if url.endswith("/"): |
25 | | - url = url.removesuffix("/") |
26 | | - |
27 | | - return httpx.post(f"{url}/_sql", json={"stmt": query}, timeout=Settings.http_timeout()).json() |
28 | | - |
29 | | - |
30 | | -@mcp.tool(description="Send an SQL query to CrateDB. Only 'SELECT' queries are allowed.") |
31 | | -def query_sql(query: str): |
32 | | - if not sql_is_permitted(query): |
33 | | - raise PermissionError("Only queries that have a SELECT statement are allowed.") |
34 | | - return query_cratedb(query) |
35 | | - |
36 | | - |
37 | | -@mcp.tool(description="Return an aggregation of all CrateDB's schema, tables and their metadata.") |
38 | | -def get_table_metadata() -> list[dict]: |
39 | | - """ |
40 | | - Return an aggregation of schema:tables, e.g.: {'doc': [{name:'mytable', ...}, ...]} |
41 | | -
|
42 | | - The tables have metadata datapoints like replicas, shards, |
43 | | - name, version, total_shards, total_records. |
44 | | - """ |
45 | | - return query_cratedb(Queries.TABLES_METADATA) |
46 | | - |
47 | | - |
48 | | -@mcp.tool(description="Return the health of the CrateDB cluster.") |
49 | | -def get_cluster_health() -> list[dict]: |
50 | | - """Query sys.health ordered by severity.""" |
51 | | - return query_cratedb(Queries.HEALTH) |
| 20 | +mcp.add_tool( |
| 21 | + Tool.from_function( |
| 22 | + fn=get_cluster_health, |
| 23 | + description="Return the health of the CrateDB cluster.", |
| 24 | + tags={"health", "monitoring", "status"}, |
| 25 | + ) |
| 26 | +) |
52 | 27 |
|
53 | 28 |
|
54 | 29 | # ------------------------------------------ |
55 | | -# Documentation Inquiry |
| 30 | +# Text-to-SQL |
56 | 31 | # ------------------------------------------ |
57 | | - |
58 | | - |
59 | | -@mcp.tool( |
60 | | - description="Get an index of CrateDB documentation links for fetching. " |
61 | | - "Should download docs before answering questions. " |
62 | | - "Has documentation title, description, and link." |
| 32 | +mcp.add_tool( |
| 33 | + Tool.from_function( |
| 34 | + fn=query_sql, |
| 35 | + description="Send an SQL query to CrateDB. Only 'SELECT' queries are allowed.", |
| 36 | + tags={"text-to-sql"}, |
| 37 | + ) |
| 38 | +) |
| 39 | +mcp.add_tool( |
| 40 | + Tool.from_function( |
| 41 | + fn=get_table_metadata, |
| 42 | + description="Return an aggregation of all CrateDB's schema, tables and their metadata.", |
| 43 | + tags={"text-to-sql"}, |
| 44 | + ) |
63 | 45 | ) |
64 | | -def get_cratedb_documentation_index(): |
65 | | - return documentation_index.items() |
66 | 46 |
|
67 | 47 |
|
68 | | -@mcp.tool(description="Download individual CrateDB documentation pages by link.") |
69 | | -def fetch_cratedb_docs(link: str): |
70 | | - """Fetch a CrateDB documentation link.""" |
71 | | - if not documentation_index.url_permitted(link): |
72 | | - raise ValueError(f"Link is not permitted: {link}") |
73 | | - return documentation_index.client.get(link, timeout=Settings.http_timeout()).text |
| 48 | +# ------------------------------------------ |
| 49 | +# Documentation inquiry |
| 50 | +# ------------------------------------------ |
| 51 | +mcp.add_tool( |
| 52 | + Tool.from_function( |
| 53 | + fn=get_cratedb_documentation_index, |
| 54 | + description="Get an index of CrateDB documentation links for fetching. " |
| 55 | + "Should download docs before answering questions. " |
| 56 | + "Has documentation title, description, and link.", |
| 57 | + tags={"documentation"}, |
| 58 | + ) |
| 59 | +) |
| 60 | +mcp.add_tool( |
| 61 | + Tool.from_function( |
| 62 | + fn=fetch_cratedb_docs, |
| 63 | + description="Download individual CrateDB documentation pages by link.", |
| 64 | + tags={"documentation"}, |
| 65 | + ) |
| 66 | +) |
0 commit comments