from typing import Dict, Any, List
from .trilium_client import TriliumClient
class ToolHandlers:
def __init__(self, client: TriliumClient):
self.client = client
def listTools(self) -> List[Dict[str, Any]]:
"""Return the list of tools available through the MCP server."""
return [
{
"name": "search_notes",
"description": "Search for notes in Trilium using its search syntax.",
"inputSchema": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Trilium search query."}
},
"required": ["query"]
}
},
{
"name": "get_note_content",
"description": "Fetch the raw content (HTML) of a specific note.",
"inputSchema": {
"type": "object",
"properties": {
"noteId": {"type": "string", "description": "Unique ID of the note."}
},
"required": ["noteId"]
}
},
{
"name": "get_note_metadata",
"description": "Fetch full metadata for a note including attributes and tags.",
"inputSchema": {
"type": "object",
"properties": {
"noteId": {"type": "string", "description": "Unique ID of the note."}
},
"required": ["noteId"]
}
},
{
"name": "get_note_children",
"description": "Fetch a list of child notes for a given parent note.",
"inputSchema": {
"type": "object",
"properties": {
"noteId": {"type": "string", "description": "Unique ID of the parent note."}
},
"required": ["noteId"]
}
},
{
"name": "create_note",
"description": "Create a new note in Trilium. Can optionally specify a template and attributes.",
"inputSchema": {
"type": "object",
"properties": {
"parentNoteId": {"type": "string", "description": "ID of parent note (default 'root')."},
"title": {"type": "string", "description": "Title of the note."},
"content": {"type": "string", "description": "HTML content for the note."},
"type": {"type": "string", "description": "Type of note (e.g., 'text').", "default": "text"},
"templateNoteId": {"type": "string", "description": "Optional: ID of a template note to inherit from."},
"attributes": {
"type": "array",
"description": "Optional: List of attributes (labels or relations) to add.",
"items": {
"type": "object",
"properties": {
"type": {"type": "string", "enum": ["label", "relation"]},
"name": {"type": "string"},
"value": {"type": "string"},
"isInheritable": {"type": "boolean", "default": False}
},
"required": ["type", "name", "value"]
}
}
},
"required": ["title", "content"]
}
},
{
"name": "create_attribute",
"description": "Create a new attribute (label or relation) for a note.",
"inputSchema": {
"type": "object",
"properties": {
"noteId": {"type": "string", "description": "ID of the note to add the attribute to."},
"type": {"type": "string", "enum": ["label", "relation"]},
"name": {"type": "string", "description": "Name of the attribute."},
"value": {"type": "string", "description": "Value of the attribute."},
"isInheritable": {"type": "boolean", "description": "Whether the attribute is inheritable.", "default": False}
},
"required": ["noteId", "type", "name", "value"]
}
},
{
"name": "update_note_content",
"description": "Update the content of an existing note.",
"inputSchema": {
"type": "object",
"properties": {
"noteId": {"type": "string", "description": "ID of the note to update."},
"content": {"type": "string", "description": "New HTML content."}
},
"required": ["noteId", "content"]
}
}
]
def callTool(self, name: str, params: Dict[str, Any]) -> Any:
"""Dispatcher for tool calls."""
if name == "search_notes":
return self.client.searchNotes(params["query"])
elif name == "get_note_content":
return self.client.getNoteContent(params["noteId"])
elif name == "get_note_metadata":
return self.client.getNoteMetadata(params["noteId"])
elif name == "get_note_children":
return self.client.getNoteChildren(params["noteId"])
elif name == "create_note":
parent_note_id = params.get("parentNoteId", "root")
note_data = self.client.createNote(
parent_note_id,
params["title"],
params["content"],
params.get("type", "text")
)
note_id = note_data["note"]["noteId"]
# Handle optional template inheritance
if params.get("templateNoteId"):
self.client.createAttribute(
note_id, "relation", "template", params["templateNoteId"]
)
# Handle additional attributes
if params.get("attributes"):
for attr in params["attributes"]:
self.client.createAttribute(
note_id,
attr["type"],
attr["name"],
attr["value"],
attr.get("isInheritable", False)
)
return note_data
elif name == "create_attribute":
return self.client.createAttribute(
params["noteId"],
params["type"],
params["name"],
params["value"],
params.get("isInheritable", False)
)
elif name == "update_note_content":
self.client.updateNoteContent(params["noteId"], params["content"])
return f"Successfully updated note content for {params['noteId']}."
else:
raise ValueError(f"Unknown tool: {name}")