feat: add direct database access for scripts (v0.2.0)
Implement persistent SQLite database feature that allows scripts to query schedule data directly via SQL after loading XER files through MCP. Key changes: - Extend load_xer with db_path parameter for persistent database - Add get_database_info tool to retrieve database connection details - Add schema introspection with tables, columns, primary/foreign keys - Support WAL mode for concurrent read access - Use atomic write pattern to prevent corruption New features: - db_path=None: in-memory database (default, backward compatible) - db_path="": auto-generate path from XER filename (.sqlite extension) - db_path="/path/to/db": explicit persistent database path Response includes complete DatabaseInfo: - db_path: absolute path (or :memory:) - is_persistent: boolean - source_file: loaded XER path - loaded_at: ISO timestamp - schema: tables with columns, primary keys, foreign keys, row counts Closes: User Story 1, 2, 3 from 002-direct-db-access spec
This commit is contained in:
@@ -50,6 +50,12 @@ async def list_tools() -> list[Tool]:
|
||||
"type": "string",
|
||||
"description": "Project ID to select (required for multi-project files)",
|
||||
},
|
||||
"db_path": {
|
||||
"type": "string",
|
||||
"description": "Path for persistent SQLite database file. "
|
||||
"If omitted, uses in-memory database. "
|
||||
"If empty string, auto-generates path from XER filename (same directory, .sqlite extension).",
|
||||
},
|
||||
},
|
||||
"required": ["file_path"],
|
||||
},
|
||||
@@ -183,6 +189,15 @@ async def list_tools() -> list[Tool]:
|
||||
"properties": {},
|
||||
},
|
||||
),
|
||||
Tool(
|
||||
name="get_database_info",
|
||||
description="Get information about the currently loaded database including file path and schema. "
|
||||
"Use this to get connection details for direct SQL access.",
|
||||
inputSchema={
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
},
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
@@ -197,6 +212,7 @@ async def call_tool(name: str, arguments: dict) -> list[TextContent]:
|
||||
result = await load_xer(
|
||||
file_path=arguments["file_path"],
|
||||
project_id=arguments.get("project_id"),
|
||||
db_path=arguments.get("db_path"),
|
||||
)
|
||||
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
||||
|
||||
@@ -258,6 +274,12 @@ async def call_tool(name: str, arguments: dict) -> list[TextContent]:
|
||||
result = await get_critical_path()
|
||||
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
||||
|
||||
if name == "get_database_info":
|
||||
from xer_mcp.tools.get_database_info import get_database_info
|
||||
|
||||
result = await get_database_info()
|
||||
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
||||
|
||||
raise ValueError(f"Unknown tool: {name}")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user