Skip to main content
Glama

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

TableJSON Schema
NameRequiredDescriptionDefault
request_idYesThe guardian approval request ID returned by a previous operation.
chainNoTarget 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

  • 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").'),
      }),
    },
  • Tool registration for 'azeth_guardian_status' in the MCP server instance.
    'azeth_guardian_status',

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/azeth-protocol/mcp-azeth'

If you have feedback or need assistance with the MCP directory API, please join our Discord server