summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authortanaka takashi <isazaka@gmail.com>2026-07-04 16:22:35 +0900
committertanaka takashi <isazaka@gmail.com>2026-07-04 16:22:35 +0900
commiteb5e9d9f37bda7d78f69614da70402357794168a (patch)
tree608dd61d8b4ca989df505e9777a8b95f4f17b06d /tests
parent1a6a2e7f8572415d435c056dc9947d6d08eb1862 (diff)
feat(P1-002): add offline JSONL import via import_messages MCP tool
- implement `import_messages` MCP tool parsing manifest + PUT/DEL JSONL - atomic store replacement under lock with overwrite/reject conflict policies - add `include_deleted` to read_messages export view for full round-trip - register new tool in MCP registry and update protocol test expectations - update docs/development-plan.md and docs/implementation-status.md Debug/Release/ASan 15/15 CTest pass
Diffstat (limited to 'tests')
-rw-r--r--tests/mcp_protocol_test.py7
1 files changed, 7 insertions, 0 deletions
diff --git a/tests/mcp_protocol_test.py b/tests/mcp_protocol_test.py
index 2d239fb..ec4f350 100644
--- a/tests/mcp_protocol_test.py
+++ b/tests/mcp_protocol_test.py
@@ -134,6 +134,7 @@ def main() -> None:
"delete_message",
"rebuild_index",
"get_system_health",
+ "import_messages",
}
expected_descriptions = {
"write_message": "Append and durably persist a conversation message. Use it to store information that should remain available after server restarts.",
@@ -143,6 +144,7 @@ def main() -> None:
"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.",
+ "import_messages": "Atomically import a JSONL export from read_messages view=export. The manifest line is required; subsequent lines are PUT messages or DEL tombstones. Conflicting message IDs are resolved by the policy argument.",
}
assert {name: tool["description"] for name, tool in tools.items()} == expected_descriptions
expected_property_descriptions = {
@@ -162,6 +164,7 @@ def main() -> None:
"relation_types_json": "Optional JSON array string of relation types to follow.",
"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.",
+ "include_deleted": "When true, export view includes deleted records as DEL lines; other views ignore this option.",
},
"search_messages": {
"query": "UTF-8 text to match against persisted message content and tags.",
@@ -181,6 +184,10 @@ def main() -> None:
"metadata_json": "Replacement metadata JSON; omit to retain metadata.",
"expected_revision": "Optional positive revision for optimistic concurrency.",
},
+ "import_messages": {
+ "jsonl": "JSONL string containing a manifest line followed by PUT message lines and optional DEL tombstone lines.",
+ "policy": "Conflict policy: overwrite (default) replaces existing message IDs, reject refuses duplicate IDs.",
+ },
}
for tool_name, descriptions in expected_property_descriptions.items():
properties = tools[tool_name]["inputSchema"]["properties"]