diff --git a/app/mcp.py b/app/mcp.py index d96e30c1..e21c3e98 100644 --- a/app/mcp.py +++ b/app/mcp.py @@ -174,6 +174,23 @@ { "name": "register_wallet", "description": "Register an MRWK wallet public key", + "inputSchema": { + "type": "object", + "properties": { + "public_key_hex": { + "type": "string", + "pattern": "^[0-9a-fA-F]{64}$", + "description": "Ed25519 public key as 64 hex characters.", + }, + "label": { + "type": "string", + "maxLength": 160, + "description": "Optional wallet label.", + }, + }, + "required": ["public_key_hex"], + "additionalProperties": False, + }, }, { "name": "get_wallet", @@ -194,6 +211,49 @@ { "name": "submit_wallet_transfer", "description": "Submit a signed MRWK wallet transfer", + "inputSchema": { + "type": "object", + "properties": { + "from_address": { + "type": "string", + "pattern": "^[mM][rR][wW][kK]1[0-9a-fA-F]{40}$", + "description": "Sender MRWK wallet address.", + }, + "to_address": { + "type": "string", + "pattern": "^[mM][rR][wW][kK]1[0-9a-fA-F]{40}$", + "description": "Receiver MRWK wallet address.", + }, + "amount_mrwk": { + "type": "string", + "description": "MRWK amount, with up to 6 decimal places.", + }, + "nonce": { + "type": "integer", + "minimum": 1, + "description": "Next wallet nonce signed in the transfer payload.", + }, + "memo": { + "type": "string", + "maxLength": 240, + "default": "", + "description": "Optional transfer memo.", + }, + "signature_hex": { + "type": "string", + "pattern": "^[0-9a-fA-F]{128}$", + "description": "Ed25519 signature as 128 hex characters.", + }, + }, + "required": [ + "from_address", + "to_address", + "amount_mrwk", + "nonce", + "signature_hex", + ], + "additionalProperties": False, + }, }, { "name": "get_ledger_entry", diff --git a/tests/test_api_mcp.py b/tests/test_api_mcp.py index d5458078..e210b1cb 100644 --- a/tests/test_api_mcp.py +++ b/tests/test_api_mcp.py @@ -395,6 +395,35 @@ def test_mcp_tools_list_and_call(sqlite_url: str) -> None: assert proof_schema["required"] == ["hash"] assert proof_schema["additionalProperties"] is False assert proof_schema["properties"]["hash"]["pattern"] == "^[0-9a-fA-F]{64}$" + register_tool = next( + tool for tool in tools["result"]["tools"] if tool["name"] == "register_wallet" + ) + register_schema = register_tool["inputSchema"] + assert register_schema["required"] == ["public_key_hex"] + assert register_schema["additionalProperties"] is False + assert register_schema["properties"]["public_key_hex"]["pattern"] == "^[0-9a-fA-F]{64}$" + assert register_schema["properties"]["label"]["maxLength"] == 160 + transfer_tool = next( + tool for tool in tools["result"]["tools"] if tool["name"] == "submit_wallet_transfer" + ) + transfer_schema = transfer_tool["inputSchema"] + assert transfer_schema["required"] == [ + "from_address", + "to_address", + "amount_mrwk", + "nonce", + "signature_hex", + ] + assert transfer_schema["additionalProperties"] is False + assert transfer_schema["properties"]["from_address"]["pattern"] == ( + "^[mM][rR][wW][kK]1[0-9a-fA-F]{40}$" + ) + assert transfer_schema["properties"]["to_address"]["pattern"] == ( + "^[mM][rR][wW][kK]1[0-9a-fA-F]{40}$" + ) + assert transfer_schema["properties"]["nonce"]["minimum"] == 1 + assert transfer_schema["properties"]["memo"]["maxLength"] == 240 + assert transfer_schema["properties"]["signature_hex"]["pattern"] == "^[0-9a-fA-F]{128}$" balance = client.post( "/mcp",