{"ok":true,"tool":"penny-lock","module_version":"0.1.0","result":{"slug":"penny-lock","name":"PennyLock","version":"0.1.0","category":"coordination","status":"beta","mode":"atomic","summary":"Acquire an opaque distributed lock with a short TTL.","description":"Atomically sets a namespaced opaque key if it is absent. Use it to ensure one agent temporarily owns a task. The service never exposes a list of locks or owners.","when_to_use":["One agent must briefly own an opaque resource while peers stand down.","Duplicate work is possible and a bounded distributed lock is sufficient."],"do_not_use_when":["The operation itself must execute exactly once.","The resource identifier contains secrets or personal data."],"tested_with":["HTTP/1.1","HTTP/2","MCP Streamable HTTP"],"input_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"namespace":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[a-zA-Z0-9._:-]+$"},"key":{"type":"string","minLength":1,"maxLength":256},"owner":{"type":"string","minLength":1,"maxLength":128},"ttl_seconds":{"type":"integer","minimum":1,"maximum":3600}},"required":["namespace","key","ttl_seconds"],"additionalProperties":false},"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"acquired":{"type":"boolean"},"lock_hash":{"type":"string"},"expires_at":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"},{"type":"null"}]},"ttl_seconds_remaining":{"anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"null"}]}},"required":["acquired","lock_hash","expires_at","ttl_seconds_remaining"],"additionalProperties":false},"payment":{"kind":"free"},"side_effects":["Creates a temporary lock when acquired."],"retention":"The opaque key hash and owner value remain in Valkey only until the requested TTL expires. A result envelope containing no raw key or owner may be retained for idempotent replay for up to 24 hours.","limits":{"max_ttl_seconds":3600,"max_key_bytes":256,"max_client_requests_per_minute":30,"max_global_requests_per_minute":120},"examples":{"input":{"namespace":"crawl:example.invalid","key":"job-42","owner":"agent-a","ttl_seconds":30},"output":{"acquired":true,"lock_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","expires_at":"2026-07-24T12:00:30.000Z","ttl_seconds_remaining":30},"negative":[{"scenario":"The operation itself must execute exactly once.","expected_error":"INVALID_INPUT","charged":false}]},"execution":{"errors":[{"code":"INVALID_INPUT","retryable":false,"charged":false,"recovery":"Correct the request to match input_schema."},{"code":"TOOL_PAUSED","retryable":true,"charged":false,"recovery":"Wait for the operator to resume the tool."},{"code":"RATE_LIMITED","retryable":true,"charged":false,"recovery":"Retry after the response Retry-After interval."},{"code":"DEPENDENCY_UNAVAILABLE","retryable":true,"charged":false,"recovery":"Retry with the same idempotency identity."}],"idempotency":{"required":true,"mock_or_unpaid_header":"Idempotency-Key","x402_extension":null,"replay_retention":"up to 24 hours"}},"endpoints":{"describe":"/v1/tools/penny-lock","execute":"/v1/tools/penny-lock"}},"meta":{"request_id":"req_c5b7cf88e7774c2d9ed4d37f512370bb","observed_at":"2026-07-24T23:23:26.981Z"}}