azeth_guardian_status
Check if a guardian has responded to a pending co-signature request. Use to verify approval status and retrieve signatures for completing operations that require guardian authorization.
Instructions
Check the status of a pending guardian approval request.
Use this when: You previously submitted an operation that required guardian co-signature and received a timeout with a request_id. This tool checks if the guardian has since responded via XMTP.
Status outcomes:
"approved": Guardian approved. Returns the guardian signature. Retry your original operation — it will now succeed with the guardian co-signature.
"rejected": Guardian rejected with a reason.
"pending": Guardian has not responded yet. Check again later.
"expired": Request expired after 5 minutes. Retry your original operation.
Returns: Current status and relevant details (signature if approved, reason if rejected).
Example: { "request_id": "abc-123" }
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| request_id | Yes | The guardian approval request ID returned by a previous operation. | |
| chain | No | Target chain. Defaults to AZETH_CHAIN env var or "baseSepolia". Accepts "base", "baseSepolia", "ethereumSepolia", "ethereum" (and aliases like "base-sepolia", "eth-sepolia", "sepolia", "eth", "mainnet"). |
Implementation Reference
- src/tools/guardian-approval.ts:279-377 (handler)The handler function for 'azeth_guardian_status' tool, which checks the status of a guardian approval request, either from local memory or by querying XMTP messages for a response.
async (args) => { let client; try { // Check in-memory pending approvals store first const pending = getPendingApproval(args.request_id); if (!pending) { return error( 'SERVICE_NOT_FOUND', `No guardian approval request found with ID "${args.request_id}". ` + 'The request may have been made in a different process or session.', 'Guardian approval state is stored in-memory per process. If the MCP server restarted, the request state is lost. Retry the original operation.', ); } if (pending.status === 'expired') { return success({ requestId: args.request_id, status: 'expired', message: 'Request expired after 5 minutes. Retry your original operation to send a new approval request.', operation: pending.operation, }); } if (pending.status === 'approved') { const combinedSignature = (pending.ownerSignature + pending.guardianSignature!.slice(2)) as `0x${string}`; return success({ requestId: args.request_id, status: 'approved', message: 'Guardian approved! Retry your original operation — it will succeed with the guardian co-signature.', guardianSignature: pending.guardianSignature, combinedSignature, operation: pending.operation, }); } if (pending.status === 'rejected') { return success({ requestId: args.request_id, status: 'rejected', message: `Guardian rejected the request.${pending.rejectionReason ? ` Reason: ${pending.rejectionReason}` : ''}`, reason: pending.rejectionReason, operation: pending.operation, }); } // Status is 'pending' — check XMTP for new response client = await createClient(args.chain); const messages = await client.getMessages(pending.guardianAddress, 20); for (const msg of messages) { if (msg.timestamp < pending.createdAt) continue; const parsed = tryParseGuardianResponse(msg.content); if (parsed && parsed.requestId === args.request_id) { if (parsed.decision === 'approved' && parsed.signature) { pending.status = 'approved'; pending.guardianSignature = parsed.signature; const combinedSignature = (pending.ownerSignature + parsed.signature.slice(2)) as `0x${string}`; return success({ requestId: args.request_id, status: 'approved', message: 'Guardian approved! Retry your original operation — it will succeed with the guardian co-signature.', guardianSignature: parsed.signature, combinedSignature, operation: pending.operation, }); } else { pending.status = 'rejected'; pending.rejectionReason = parsed.reason; return success({ requestId: args.request_id, status: 'rejected', message: `Guardian rejected the request.${parsed.reason ? ` Reason: ${parsed.reason}` : ''}`, reason: parsed.reason, operation: pending.operation, }); } } } // No response yet return success({ requestId: args.request_id, status: 'pending', message: 'Guardian has not responded yet. Check again later.', guardianAddress: pending.guardianAddress, operation: pending.operation, expiresAt: new Date(pending.expiresAt).toISOString(), }); } catch (err) { return handleError(err); } finally { try { await client?.destroy(); } catch { /* prevent destroy from masking the original error */ } } }, ); - Input schema definition for the 'azeth_guardian_status' tool.
inputSchema: z.object({ request_id: z.string().describe('The guardian approval request ID returned by a previous operation.'), chain: z.string().optional().describe('Target chain. Defaults to AZETH_CHAIN env var or "baseSepolia". Accepts "base", "baseSepolia", "ethereumSepolia", "ethereum" (and aliases like "base-sepolia", "eth-sepolia", "sepolia", "eth", "mainnet").'), }), }, - src/tools/guardian-approval.ts:254-254 (registration)Tool registration for 'azeth_guardian_status' in the MCP server instance.
'azeth_guardian_status',