diff options
| author | tanaka takashi <isazaka@gmail.com> | 2026-07-01 00:17:40 +0900 |
|---|---|---|
| committer | tanaka takashi <isazaka@gmail.com> | 2026-07-01 00:17:40 +0900 |
| commit | 34e00404e9561dcaf8d2d99df7470757a4fee915 (patch) | |
| tree | b16e2fd6a5f9b0eb1f7019cb7967b4edcd97cc13 | |
| parent | a44fd4cf3a0c3d7ae33b7664341a0a9bff07aaaa (diff) | |
tool description最適化
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | README.md | 12 | ||||
| -rw-r--r-- | src/mcp/tools/delete_message.c | 20 | ||||
| -rw-r--r-- | src/mcp/tools/get_system_health.c | 7 | ||||
| -rw-r--r-- | src/mcp/tools/read_messages.c | 26 | ||||
| -rw-r--r-- | src/mcp/tools/rebuild_index.c | 7 | ||||
| -rw-r--r-- | src/mcp/tools/search_messages.c | 26 | ||||
| -rw-r--r-- | src/mcp/tools/write_message.c | 18 | ||||
| -rw-r--r-- | tests/mcp_protocol_test.py | 34 |
9 files changed, 128 insertions, 25 deletions
@@ -85,3 +85,6 @@ __pycache__/ .DS_Store Thumbs.db Desktop.ini + +# other +data/ @@ -54,12 +54,12 @@ stdoutはMCP JSON-RPC専用、stderrは診断専用です。 ## MCP tools -- `write_message`: サーバ生成ULID・UTC timestamp付きメッセージを同期永続化 -- `read_messages`: sessionの有効メッセージを時系列順にpagination取得(既定100件、最大1000件) -- `search_messages`: contentとtagsをUTF-8コードポイントの2/3-gramで検索 -- `delete_message`: DELレコードを同期永続化して即時不可視化 -- `rebuild_index`: 有効PUTだけにcompactionしsnapshotを再生成 -- `get_system_health`: ログ、snapshot、復旧状態、件数を報告 +- `write_message`: 再起動後も利用する会話メッセージを同期永続化 +- `read_messages`: 既知のsessionの会話履歴を時系列順にpagination取得 +- `search_messages`: 全sessionまたは特定sessionからcontent・tagsに一致する記憶を検索 +- `delete_message`: メッセージをread/searchから即時除外(物理除去はrebuild後) +- `rebuild_index`: 保守時にStoreをcompactし、snapshotとメモリindexを再構築 +- `get_system_health`: 永続化・復旧問題の診断に必要なStore状態と件数を取得 ツール結果はMCP TextContent内のJSON文字列です。入力schema、サイズ制限、エラーコード および物理フォーマットは[architecture](docs/architecture.md)を参照してください。 diff --git a/src/mcp/tools/delete_message.c b/src/mcp/tools/delete_message.c index 8b6e8f9..f90bbe3 100644 --- a/src/mcp/tools/delete_message.c +++ b/src/mcp/tools/delete_message.c @@ -43,8 +43,22 @@ call_delete_message(const mcpc_tool_t *tool, mcpc_ucbr_t *result) bool tiny_mcp_register_delete_message(mcpc_server_t *server) { - mcpc_tool_t *tool = tiny_mcp_tool_new("delete_message", "Delete a message", call_delete_message); - return tool && tiny_mcp_tool_add_property(tool, "message_id", "Message ULID", MCPC_U8STR, true) - && tiny_mcp_tool_add_property(tool, "session_id", "Optional session ID", MCPC_U8STR, false) + mcpc_tool_t *tool = tiny_mcp_tool_new( + "delete_message", + "Delete a persisted message so it is immediately excluded from reads and " + "searches. Physical removal occurs after rebuild_index compacts the store.", + call_delete_message); + return tool + && tiny_mcp_tool_add_property(tool, + "message_id", + "Canonical 26-character ULID of the message to delete.", + MCPC_U8STR, + true) + && tiny_mcp_tool_add_property(tool, + "session_id", + "Optional session guard; when provided, delete only if the " + "message belongs to this session.", + MCPC_U8STR, + false) && mcpc_server_add_tool(server, tool) == MCPC_EC_0; } diff --git a/src/mcp/tools/get_system_health.c b/src/mcp/tools/get_system_health.c index eb02090..5fd3fc8 100644 --- a/src/mcp/tools/get_system_health.c +++ b/src/mcp/tools/get_system_health.c @@ -43,7 +43,10 @@ call_get_system_health(const mcpc_tool_t *tool, mcpc_ucbr_t *result) bool tiny_mcp_register_get_system_health(mcpc_server_t *server) { - mcpc_tool_t *tool - = tiny_mcp_tool_new("get_system_health", "Report storage health", call_get_system_health); + mcpc_tool_t *tool = tiny_mcp_tool_new( + "get_system_health", + "Inspect storage health, recovery state, message counts, and file sizes. Use " + "it to diagnose persistence or recovery problems.", + call_get_system_health); return tool && mcpc_server_add_tool(server, tool) == MCPC_EC_0; } diff --git a/src/mcp/tools/read_messages.c b/src/mcp/tools/read_messages.c index 1581534..44a026f 100644 --- a/src/mcp/tools/read_messages.c +++ b/src/mcp/tools/read_messages.c @@ -318,11 +318,29 @@ call_read_messages(const mcpc_tool_t *tool, mcpc_ucbr_t *result) bool tiny_mcp_register_read_messages(mcpc_server_t *server) { - mcpc_tool_t *tool = tiny_mcp_tool_new("read_messages", "Read a session page", call_read_messages); - return tool && tiny_mcp_tool_add_property(tool, "session_id", "Session ID", MCPC_U8STR, true) + mcpc_tool_t *tool + = tiny_mcp_tool_new("read_messages", + "Read persisted messages from one known session in chronological order. " + "Returns a paginated history for reconstructing that conversation.", + call_read_messages); + return tool + && tiny_mcp_tool_add_property(tool, + "session_id", + "Conversation session whose chronological history to read.", + MCPC_U8STR, + true) && tiny_mcp_tool_add_property( - tool, "limit", "Optional page limit from 1 to 1000; defaults to 100", MCPC_I32, false) + tool, + "limit", + "Maximum messages to return in this page, from 1 to 1000; defaults to 100.", + MCPC_I32, + false) && tiny_mcp_tool_add_property( - tool, "cursor", "Optional opaque page cursor", MCPC_U8STR, false) + tool, + "cursor", + "Opaque nextCursor returned by a previous read_messages call; " + "omit for the first page.", + MCPC_U8STR, + false) && mcpc_server_add_tool(server, tool) == MCPC_EC_0; } diff --git a/src/mcp/tools/rebuild_index.c b/src/mcp/tools/rebuild_index.c index 7208d77..e6dbf69 100644 --- a/src/mcp/tools/rebuild_index.c +++ b/src/mcp/tools/rebuild_index.c @@ -59,6 +59,11 @@ call_rebuild_index(const mcpc_tool_t *tool, mcpc_ucbr_t *result) bool tiny_mcp_register_rebuild_index(mcpc_server_t *server) { - mcpc_tool_t *tool = tiny_mcp_tool_new("rebuild_index", "Compact and rebuild", call_rebuild_index); + mcpc_tool_t *tool = tiny_mcp_tool_new( + "rebuild_index", + "Compact the store and rebuild its snapshot and in-memory indexes. Use it " + "for maintenance or to physically remove logically deleted records; it may " + "block other requests while running.", + call_rebuild_index); return tool && mcpc_server_add_tool(server, tool) == MCPC_EC_0; } diff --git a/src/mcp/tools/search_messages.c b/src/mcp/tools/search_messages.c index d20d7b2..44db1ef 100644 --- a/src/mcp/tools/search_messages.c +++ b/src/mcp/tools/search_messages.c @@ -127,11 +127,29 @@ call_search_messages(const mcpc_tool_t *tool, mcpc_ucbr_t *result) bool tiny_mcp_register_search_messages(mcpc_server_t *server) { - mcpc_tool_t *tool = tiny_mcp_tool_new("search_messages", "Search messages", call_search_messages); - return tool && tiny_mcp_tool_add_property(tool, "query", "Search text", MCPC_U8STR, true) + mcpc_tool_t *tool + = tiny_mcp_tool_new("search_messages", + "Search persisted message content and tags by text relevance. Use it to " + "recall matching information globally or within one session.", + call_search_messages); + return tool && tiny_mcp_tool_add_property( - tool, "session_id", "Optional session ID; omitted searches all", MCPC_U8STR, false) + tool, + "query", + "UTF-8 text to match against persisted message content and tags.", + MCPC_U8STR, + true) && tiny_mcp_tool_add_property( - tool, "limit", "Optional result limit from 1 to 100; defaults to 20", MCPC_I32, false) + tool, + "session_id", + "Conversation session to search; omit to search across all sessions.", + MCPC_U8STR, + false) + && tiny_mcp_tool_add_property( + tool, + "limit", + "Maximum ranked matches to return, from 1 to 100; defaults to 20.", + MCPC_I32, + false) && mcpc_server_add_tool(server, tool) == MCPC_EC_0; } diff --git a/src/mcp/tools/write_message.c b/src/mcp/tools/write_message.c index c4b18cc..7df0058 100644 --- a/src/mcp/tools/write_message.c +++ b/src/mcp/tools/write_message.c @@ -211,13 +211,21 @@ bool tiny_mcp_register_write_message(mcpc_server_t *server) { mcpc_tool_t *tool - = tiny_mcp_tool_new("write_message", "Append a conversation message", call_write_message); - return tool && tiny_mcp_tool_add_property(tool, "session_id", "Session ID", MCPC_U8STR, true) - && tiny_mcp_tool_add_property(tool, "role", "user, assistant, or system", MCPC_U8STR, true) - && tiny_mcp_tool_add_property(tool, "content", "Message text", MCPC_U8STR, true) + = tiny_mcp_tool_new("write_message", + "Append and durably persist a conversation message. Use it to store " + "information that should remain available after server restarts.", + call_write_message); + return tool + && tiny_mcp_tool_add_property( + tool, "session_id", "Conversation session that owns the message.", MCPC_U8STR, true) + && tiny_mcp_tool_add_property( + tool, "role", "Message author role: user, assistant, or system.", MCPC_U8STR, true) + && tiny_mcp_tool_add_property( + tool, "content", "UTF-8 message text to persist.", MCPC_U8STR, true) && tiny_mcp_tool_add_property(tool, "metadata_json", - "Optional metadata object JSON; defaults to {}", + "Optional JSON object string containing tool_call_id, tags, " + "and/or memory_tier; defaults to {}.", MCPC_U8STR, false) && mcpc_server_add_tool(server, tool) == MCPC_EC_0; diff --git a/tests/mcp_protocol_test.py b/tests/mcp_protocol_test.py index 4d1deb2..2dc70ff 100644 --- a/tests/mcp_protocol_test.py +++ b/tests/mcp_protocol_test.py @@ -128,6 +128,40 @@ def main() -> None: "rebuild_index", "get_system_health", } + expected_descriptions = { + "write_message": "Append and durably persist a conversation message. Use it to store information that should remain available after server restarts.", + "read_messages": "Read persisted messages from one known session in chronological order. Returns a paginated history for reconstructing that conversation.", + "search_messages": "Search persisted message content and tags by text relevance. Use it to recall matching information globally or within one session.", + "delete_message": "Delete a persisted message so it is immediately excluded from reads and searches. Physical removal occurs after rebuild_index compacts the store.", + "rebuild_index": "Compact the store and rebuild its snapshot and in-memory indexes. Use it for maintenance or to physically remove logically deleted records; it may block other requests while running.", + "get_system_health": "Inspect storage health, recovery state, message counts, and file sizes. Use it to diagnose persistence or recovery problems.", + } + assert {name: tool["description"] for name, tool in tools.items()} == expected_descriptions + expected_property_descriptions = { + "write_message": { + "session_id": "Conversation session that owns the message.", + "role": "Message author role: user, assistant, or system.", + "content": "UTF-8 message text to persist.", + "metadata_json": "Optional JSON object string containing tool_call_id, tags, and/or memory_tier; defaults to {}.", + }, + "read_messages": { + "session_id": "Conversation session whose chronological history to read.", + "limit": "Maximum messages to return in this page, from 1 to 1000; defaults to 100.", + "cursor": "Opaque nextCursor returned by a previous read_messages call; omit for the first page.", + }, + "search_messages": { + "query": "UTF-8 text to match against persisted message content and tags.", + "session_id": "Conversation session to search; omit to search across all sessions.", + "limit": "Maximum ranked matches to return, from 1 to 100; defaults to 20.", + }, + "delete_message": { + "message_id": "Canonical 26-character ULID of the message to delete.", + "session_id": "Optional session guard; when provided, delete only if the message belongs to this session.", + }, + } + for tool_name, descriptions in expected_property_descriptions.items(): + properties = tools[tool_name]["inputSchema"]["properties"] + assert {name: value["description"] for name, value in properties.items()} == descriptions assert tools["write_message"]["inputSchema"]["required"] == [ "session_id", "role", |
