Coverage for src \ truenex_memory \ mcp \ __init__.py: 70%

27 statements  

« prev     ^ index     » next       coverage.py v7.14.0, created at 2026-05-19 10:21 +0200

1"""Local MCP-style tool registry. 

2 

3This module intentionally does not start an MCP server. It exposes local tool 

4operations as plain Python callables so tests and local automation can invoke 

5them without network or cloud dependencies. The stdio MCP server exposes a 

6smaller explicit agent-facing subset in `truenex_memory.mcp.server`. 

7""" 

8 

9from __future__ import annotations 

10 

11from pathlib import Path 

12from typing import Any, Callable 

13 

14from truenex_memory.adapters import render_agents_md, render_claude_md, write_agent_docs 

15from truenex_memory.diagnostics import run_diagnostics 

16from truenex_memory.export import export_json, import_json 

17from truenex_memory.mcp.tools import global_project_context, global_status, memory_add, memory_search 

18 

19Tool = Callable[..., Any] 

20 

21 

22def _tool_export_json(records: list[dict[str, Any]], destination: str, metadata: dict[str, Any] | None = None) -> dict[str, Any]: 

23 payload = export_json(records, destination, metadata=metadata) 

24 return {"destination": str(Path(destination)), "records": len(payload["records"]), "payload": payload} 

25 

26 

27def _tool_import_json(source: str) -> dict[str, Any]: 

28 payload = import_json(source) 

29 return {"source": str(Path(source)), "records": len(payload["records"]), "payload": payload} 

30 

31 

32def _tool_write_agent_docs(directory: str, project_name: str = "Truenex Memory", overwrite: bool = False) -> dict[str, str]: 

33 written = write_agent_docs(directory, project_name=project_name, overwrite=overwrite) 

34 return {name: str(path) for name, path in written.items()} 

35 

36 

37TOOLS: dict[str, Tool] = { 

38 "global_project_context": global_project_context, 

39 "global_status": global_status, 

40 "memory_add": memory_add, 

41 "memory_search": memory_search, 

42 "diagnostics.run": run_diagnostics, 

43 "export.json": _tool_export_json, 

44 "import.json": _tool_import_json, 

45 "adapters.render_agents_md": render_agents_md, 

46 "adapters.render_claude_md": render_claude_md, 

47 "adapters.write_agent_docs": _tool_write_agent_docs, 

48} 

49 

50 

51def list_tools() -> list[dict[str, str]]: 

52 """List local MCP-style tools.""" 

53 

54 return [{"name": name, "description": (tool.__doc__ or "").strip()} for name, tool in sorted(TOOLS.items())] 

55 

56 

57def call_tool(name: str, arguments: dict[str, Any] | None = None) -> Any: 

58 """Invoke a local MCP-style tool by name.""" 

59 

60 try: 

61 tool = TOOLS[name] 

62 except KeyError as exc: 

63 raise KeyError(f"unknown tool: {name}") from exc 

64 return tool(**(arguments or {})) 

65 

66 

67__all__ = ["TOOLS", "call_tool", "list_tools"]