Skip to main content
Glama

stablecoin_manage

Manage enterprise stablecoins on Hedera with role-based controls for minting, burning, freezing, and compliance operations.

Instructions

Enterprise-grade stablecoin management via Hedera Stablecoin Studio.

OPERATIONS:

  • create: Create compliant stablecoin with role-based controls

  • info: Get stablecoin details (supply, treasury, pause status)

  • balance: Check account balance for stablecoin

  • cashin: Mint tokens to account (controlled by CASHIN role)

  • burn: Burn tokens from treasury (controlled by BURN role)

  • wipe: Remove tokens from any account (controlled by WIPE role)

  • rescue: Rescue tokens from proxy contract treasury

  • rescue_hbar: Rescue HBAR from proxy contract

  • freeze/unfreeze: Control account transfer ability

  • pause/unpause: Halt/resume all token operations globally

  • kyc_grant/kyc_revoke: Manage KYC compliance status

  • role_grant/role_revoke/role_check: Manage role assignments

  • delete: Permanently delete stablecoin (DANGER)

FEATURES:

  • Role-based access control (CASHIN, BURN, WIPE, RESCUE, PAUSE, FREEZE, KYC, DELETE)

  • Native KYC/AML compliance

  • Proof-of-Reserve support

  • Proxy contract architecture (upgradable)

  • Cash-in allowances for controlled minting

AUTO-CONFIG: Uses MCP operator account for SDK authentication.

USE FOR: Institutional stablecoin issuance, compliance workflows, token lifecycle management.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationYesStablecoin operation to perform
stablecoinIdNoStablecoin token ID (0.0.xxxxx) - required for most operations
targetAccountNoTarget account ID for cashin/wipe/freeze/kyc/role operations
amountNoToken amount as string (for precise decimals)
nameNoStablecoin name (for create)
symbolNoToken symbol (for create)
decimalsNoDecimal places (default: 6)
initialSupplyNoInitial supply (default: 0)
maxSupplyNoMaximum supply (optional, for FINITE supply type)
memoNoToken memo
freezeDefaultNoFreeze accounts by default (default: false)
supplyTypeNoSupply type (default: INFINITE)
cashInRoleAccountNoAccount with CASHIN role (default: operator)
burnRoleAccountNoAccount with BURN role (default: operator)
wipeRoleAccountNoAccount with WIPE role (default: operator)
rescueRoleAccountNoAccount with RESCUE role (default: operator)
pauseRoleAccountNoAccount with PAUSE role (default: operator)
freezeRoleAccountNoAccount with FREEZE role (default: operator)
kycRoleAccountNoAccount with KYC role (default: operator)
deleteRoleAccountNoAccount with DELETE role (default: operator)
cashInAllowanceNoCash-in allowance limit (default: unlimited)
createReserveNoCreate proof-of-reserve contract
reserveInitialAmountNoInitial reserve amount
reserveAddressNoExisting reserve contract address
proxyAdminOwnerAccountNoProxy admin owner (default: operator)
roleNoRole for grant/revoke/check operations
networkNoNetwork (auto-detected from config)

Implementation Reference

  • Core handler function implementing all stablecoin operations via switch statement dispatching to stablecoinStudio service methods.
    export async function stablecoinManage(args: {
      operation:
        | 'create'
        | 'info'
        | 'balance'
        | 'cashin'
        | 'burn'
        | 'wipe'
        | 'rescue'
        | 'rescue_hbar'
        | 'freeze'
        | 'unfreeze'
        | 'pause'
        | 'unpause'
        | 'kyc_grant'
        | 'kyc_revoke'
        | 'role_grant'
        | 'role_revoke'
        | 'role_check'
        | 'delete';
      // Common parameters
      stablecoinId?: string;
      targetAccount?: string;
      amount?: string;
      // Create-specific
      name?: string;
      symbol?: string;
      decimals?: number;
      initialSupply?: string;
      maxSupply?: string;
      memo?: string;
      freezeDefault?: boolean;
      supplyType?: 'INFINITE' | 'FINITE';
      // Role accounts
      cashInRoleAccount?: string;
      burnRoleAccount?: string;
      wipeRoleAccount?: string;
      rescueRoleAccount?: string;
      pauseRoleAccount?: string;
      freezeRoleAccount?: string;
      kycRoleAccount?: string;
      deleteRoleAccount?: string;
      // Cash-in limits
      cashInAllowance?: string;
      // Reserve
      createReserve?: boolean;
      reserveInitialAmount?: string;
      reserveAddress?: string;
      // Proxy
      proxyAdminOwnerAccount?: string;
      // Role operations
      role?: 'CASHIN' | 'BURN' | 'WIPE' | 'RESCUE' | 'PAUSE' | 'FREEZE' | 'KYC' | 'DELETE';
      // Network (for initialization)
      network?: 'mainnet' | 'testnet' | 'previewnet';
    }): Promise<ToolResult> {
      try {
        logger.info('Stablecoin operation', { operation: args.operation });
    
        // Initialize SDK if needed (will use network from config or args)
        if (args.network) {
          await stablecoinStudio.initialize(args.network);
        }
    
        switch (args.operation) {
          case 'create': {
            if (!args.name || !args.symbol) {
              throw new Error('Name and symbol are required for stablecoin creation');
            }
    
            const result = await stablecoinStudio.createStablecoin({
              name: args.name,
              symbol: args.symbol,
              decimals: args.decimals,
              initialSupply: args.initialSupply,
              maxSupply: args.maxSupply,
              memo: args.memo,
              freezeDefault: args.freezeDefault,
              supplyType: args.supplyType,
              cashInRoleAccount: args.cashInRoleAccount,
              burnRoleAccount: args.burnRoleAccount,
              wipeRoleAccount: args.wipeRoleAccount,
              rescueRoleAccount: args.rescueRoleAccount,
              pauseRoleAccount: args.pauseRoleAccount,
              freezeRoleAccount: args.freezeRoleAccount,
              kycRoleAccount: args.kycRoleAccount,
              deleteRoleAccount: args.deleteRoleAccount,
              cashInAllowance: args.cashInAllowance,
              createReserve: args.createReserve,
              reserveInitialAmount: args.reserveInitialAmount,
              reserveAddress: args.reserveAddress,
              proxyAdminOwnerAccount: args.proxyAdminOwnerAccount,
            });
    
            // Get current network for HashScan links
            const currentNetwork = stablecoinStudio.getCurrentNetwork();
            const hashScanBase = `https://hashscan.io/${currentNetwork}`;
    
            return {
              success: result.success,
              data: result.success
                ? {
                    message: 'Stablecoin created successfully',
                    tokenId: result.tokenId,
                    proxyAddress: result.proxyAddress,
                    ...result.data,
                    verification: {
                      tokenUrl: `${hashScanBase}/token/${result.tokenId}`,
                      proxyContractUrl: result.proxyAddress ? `${hashScanBase}/contract/${result.proxyAddress}` : undefined,
                      message: `You can verify your stablecoin at: ${hashScanBase}/token/${result.tokenId}`,
                    },
                  }
                : undefined,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'create',
              },
            };
          }
    
          case 'info': {
            if (!args.stablecoinId) {
              throw new Error('stablecoinId is required');
            }
    
            const result = await stablecoinStudio.getInfo(args.stablecoinId);
    
            return {
              success: result.success,
              data: result.data,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'info',
              },
            };
          }
    
          case 'balance': {
            if (!args.stablecoinId || !args.targetAccount) {
              throw new Error('stablecoinId and targetAccount are required');
            }
    
            const result = await stablecoinStudio.getBalance(args.stablecoinId, args.targetAccount);
    
            return {
              success: result.success,
              data: result.data,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'balance',
              },
            };
          }
    
          case 'cashin': {
            if (!args.stablecoinId || !args.targetAccount || !args.amount) {
              throw new Error('stablecoinId, targetAccount, and amount are required');
            }
    
            const result = await stablecoinStudio.cashIn(args.stablecoinId, args.targetAccount, args.amount);
    
            return {
              success: result.success,
              data: result.success
                ? {
                    message: `Minted ${args.amount} tokens to ${args.targetAccount}`,
                    ...result.data,
                  }
                : undefined,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'cashin',
              },
            };
          }
    
          case 'burn': {
            if (!args.stablecoinId || !args.amount) {
              throw new Error('stablecoinId and amount are required');
            }
    
            const result = await stablecoinStudio.burn(args.stablecoinId, args.amount);
    
            return {
              success: result.success,
              data: result.success
                ? {
                    message: `Burned ${args.amount} tokens from treasury`,
                    ...result.data,
                  }
                : undefined,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'burn',
              },
            };
          }
    
          case 'wipe': {
            if (!args.stablecoinId || !args.targetAccount || !args.amount) {
              throw new Error('stablecoinId, targetAccount, and amount are required');
            }
    
            const result = await stablecoinStudio.wipe(args.stablecoinId, args.targetAccount, args.amount);
    
            return {
              success: result.success,
              data: result.success
                ? {
                    message: `Wiped ${args.amount} tokens from ${args.targetAccount}`,
                    ...result.data,
                  }
                : undefined,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'wipe',
              },
            };
          }
    
          case 'rescue': {
            if (!args.stablecoinId || !args.amount) {
              throw new Error('stablecoinId and amount are required');
            }
    
            const result = await stablecoinStudio.rescue(args.stablecoinId, args.amount);
    
            return {
              success: result.success,
              data: result.success
                ? {
                    message: `Rescued ${args.amount} tokens from contract`,
                    ...result.data,
                  }
                : undefined,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'rescue',
              },
            };
          }
    
          case 'rescue_hbar': {
            if (!args.stablecoinId || !args.amount) {
              throw new Error('stablecoinId and amount are required');
            }
    
            const result = await stablecoinStudio.rescueHbar(args.stablecoinId, args.amount);
    
            return {
              success: result.success,
              data: result.success
                ? {
                    message: `Rescued ${args.amount} HBAR from contract`,
                    ...result.data,
                  }
                : undefined,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'rescue_hbar',
              },
            };
          }
    
          case 'freeze': {
            if (!args.stablecoinId || !args.targetAccount) {
              throw new Error('stablecoinId and targetAccount are required');
            }
    
            const result = await stablecoinStudio.freeze(args.stablecoinId, args.targetAccount);
    
            return {
              success: result.success,
              data: result.success
                ? {
                    message: `Froze account ${args.targetAccount}`,
                    ...result.data,
                  }
                : undefined,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'freeze',
              },
            };
          }
    
          case 'unfreeze': {
            if (!args.stablecoinId || !args.targetAccount) {
              throw new Error('stablecoinId and targetAccount are required');
            }
    
            const result = await stablecoinStudio.unfreeze(args.stablecoinId, args.targetAccount);
    
            return {
              success: result.success,
              data: result.success
                ? {
                    message: `Unfroze account ${args.targetAccount}`,
                    ...result.data,
                  }
                : undefined,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'unfreeze',
              },
            };
          }
    
          case 'pause': {
            if (!args.stablecoinId) {
              throw new Error('stablecoinId is required');
            }
    
            const result = await stablecoinStudio.pause(args.stablecoinId);
    
            return {
              success: result.success,
              data: result.success
                ? {
                    message: 'Token operations paused',
                    ...result.data,
                  }
                : undefined,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'pause',
              },
            };
          }
    
          case 'unpause': {
            if (!args.stablecoinId) {
              throw new Error('stablecoinId is required');
            }
    
            const result = await stablecoinStudio.unpause(args.stablecoinId);
    
            return {
              success: result.success,
              data: result.success
                ? {
                    message: 'Token operations resumed',
                    ...result.data,
                  }
                : undefined,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'unpause',
              },
            };
          }
    
          case 'kyc_grant': {
            if (!args.stablecoinId || !args.targetAccount) {
              throw new Error('stablecoinId and targetAccount are required');
            }
    
            const result = await stablecoinStudio.grantKyc(args.stablecoinId, args.targetAccount);
    
            return {
              success: result.success,
              data: result.success
                ? {
                    message: `Granted KYC to ${args.targetAccount}`,
                    ...result.data,
                  }
                : undefined,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'kyc_grant',
              },
            };
          }
    
          case 'kyc_revoke': {
            if (!args.stablecoinId || !args.targetAccount) {
              throw new Error('stablecoinId and targetAccount are required');
            }
    
            const result = await stablecoinStudio.revokeKyc(args.stablecoinId, args.targetAccount);
    
            return {
              success: result.success,
              data: result.success
                ? {
                    message: `Revoked KYC from ${args.targetAccount}`,
                    ...result.data,
                  }
                : undefined,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'kyc_revoke',
              },
            };
          }
    
          case 'role_grant': {
            if (!args.stablecoinId || !args.targetAccount || !args.role) {
              throw new Error('stablecoinId, targetAccount, and role are required');
            }
    
            const result = await stablecoinStudio.grantRole(args.stablecoinId, args.role, args.targetAccount);
    
            return {
              success: result.success,
              data: result.success
                ? {
                    message: `Granted ${args.role} role to ${args.targetAccount}`,
                    ...result.data,
                  }
                : undefined,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'role_grant',
              },
            };
          }
    
          case 'role_revoke': {
            if (!args.stablecoinId || !args.targetAccount || !args.role) {
              throw new Error('stablecoinId, targetAccount, and role are required');
            }
    
            const result = await stablecoinStudio.revokeRole(args.stablecoinId, args.role, args.targetAccount);
    
            return {
              success: result.success,
              data: result.success
                ? {
                    message: `Revoked ${args.role} role from ${args.targetAccount}`,
                    ...result.data,
                  }
                : undefined,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'role_revoke',
              },
            };
          }
    
          case 'role_check': {
            if (!args.stablecoinId || !args.targetAccount || !args.role) {
              throw new Error('stablecoinId, targetAccount, and role are required');
            }
    
            const result = await stablecoinStudio.checkRole(args.stablecoinId, args.role, args.targetAccount);
    
            return {
              success: result.success,
              data: result.data,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'role_check',
              },
            };
          }
    
          case 'delete': {
            if (!args.stablecoinId) {
              throw new Error('stablecoinId is required');
            }
    
            const result = await stablecoinStudio.delete(args.stablecoinId);
    
            return {
              success: result.success,
              data: result.success
                ? {
                    message: 'Stablecoin deleted',
                    ...result.data,
                  }
                : undefined,
              error: result.error,
              metadata: {
                executedVia: 'stablecoin_studio',
                command: 'delete',
              },
            };
          }
    
          default:
            throw new Error(`Unknown operation: ${args.operation}`);
        }
      } catch (error) {
        logger.error('Stablecoin operation failed', { operation: args.operation, error });
        return {
          success: false,
          error: error instanceof Error ? error.message : 'Unknown error',
          metadata: {
            executedVia: 'stablecoin_studio',
            command: args.operation || 'unknown',
          },
        };
      }
    }
  • Tool definition including name, detailed description, and comprehensive input schema with all parameters and enums.
    export const stablecoinToolDefinition = {
      name: 'stablecoin_manage',
      description: `Enterprise-grade stablecoin management via Hedera Stablecoin Studio.
    
    OPERATIONS:
    - create: Create compliant stablecoin with role-based controls
    - info: Get stablecoin details (supply, treasury, pause status)
    - balance: Check account balance for stablecoin
    - cashin: Mint tokens to account (controlled by CASHIN role)
    - burn: Burn tokens from treasury (controlled by BURN role)
    - wipe: Remove tokens from any account (controlled by WIPE role)
    - rescue: Rescue tokens from proxy contract treasury
    - rescue_hbar: Rescue HBAR from proxy contract
    - freeze/unfreeze: Control account transfer ability
    - pause/unpause: Halt/resume all token operations globally
    - kyc_grant/kyc_revoke: Manage KYC compliance status
    - role_grant/role_revoke/role_check: Manage role assignments
    - delete: Permanently delete stablecoin (DANGER)
    
    FEATURES:
    - Role-based access control (CASHIN, BURN, WIPE, RESCUE, PAUSE, FREEZE, KYC, DELETE)
    - Native KYC/AML compliance
    - Proof-of-Reserve support
    - Proxy contract architecture (upgradable)
    - Cash-in allowances for controlled minting
    
    AUTO-CONFIG: Uses MCP operator account for SDK authentication.
    
    USE FOR: Institutional stablecoin issuance, compliance workflows, token lifecycle management.`,
      inputSchema: {
        type: 'object' as const,
        properties: {
          operation: {
            type: 'string',
            enum: [
              'create',
              'info',
              'balance',
              'cashin',
              'burn',
              'wipe',
              'rescue',
              'rescue_hbar',
              'freeze',
              'unfreeze',
              'pause',
              'unpause',
              'kyc_grant',
              'kyc_revoke',
              'role_grant',
              'role_revoke',
              'role_check',
              'delete',
            ],
            description: 'Stablecoin operation to perform',
          },
          stablecoinId: { type: 'string', description: 'Stablecoin token ID (0.0.xxxxx) - required for most operations' },
          targetAccount: { type: 'string', description: 'Target account ID for cashin/wipe/freeze/kyc/role operations' },
          amount: { type: 'string', description: 'Token amount as string (for precise decimals)' },
          // Create parameters
          name: { type: 'string', description: 'Stablecoin name (for create)' },
          symbol: { type: 'string', description: 'Token symbol (for create)' },
          decimals: { type: 'number', description: 'Decimal places (default: 6)' },
          initialSupply: { type: 'string', description: 'Initial supply (default: 0)' },
          maxSupply: { type: 'string', description: 'Maximum supply (optional, for FINITE supply type)' },
          memo: { type: 'string', description: 'Token memo' },
          freezeDefault: { type: 'boolean', description: 'Freeze accounts by default (default: false)' },
          supplyType: { type: 'string', enum: ['INFINITE', 'FINITE'], description: 'Supply type (default: INFINITE)' },
          // Role accounts
          cashInRoleAccount: { type: 'string', description: 'Account with CASHIN role (default: operator)' },
          burnRoleAccount: { type: 'string', description: 'Account with BURN role (default: operator)' },
          wipeRoleAccount: { type: 'string', description: 'Account with WIPE role (default: operator)' },
          rescueRoleAccount: { type: 'string', description: 'Account with RESCUE role (default: operator)' },
          pauseRoleAccount: { type: 'string', description: 'Account with PAUSE role (default: operator)' },
          freezeRoleAccount: { type: 'string', description: 'Account with FREEZE role (default: operator)' },
          kycRoleAccount: { type: 'string', description: 'Account with KYC role (default: operator)' },
          deleteRoleAccount: { type: 'string', description: 'Account with DELETE role (default: operator)' },
          // Cash-in limits
          cashInAllowance: { type: 'string', description: 'Cash-in allowance limit (default: unlimited)' },
          // Reserve
          createReserve: { type: 'boolean', description: 'Create proof-of-reserve contract' },
          reserveInitialAmount: { type: 'string', description: 'Initial reserve amount' },
          reserveAddress: { type: 'string', description: 'Existing reserve contract address' },
          // Proxy
          proxyAdminOwnerAccount: { type: 'string', description: 'Proxy admin owner (default: operator)' },
          // Role operations
          role: {
            type: 'string',
            enum: ['CASHIN', 'BURN', 'WIPE', 'RESCUE', 'PAUSE', 'FREEZE', 'KYC', 'DELETE'],
            description: 'Role for grant/revoke/check operations',
          },
          // Network
          network: { type: 'string', enum: ['mainnet', 'testnet', 'previewnet'], description: 'Network (auto-detected from config)' },
        },
        required: ['operation'],
      },
    };
  • src/index.ts:661-662 (registration)
    Registration in the main tool dispatch switch statement, mapping tool calls to the stablecoinManage handler.
    case 'stablecoin_manage':
      result = await stablecoinManage(args as any);
  • src/index.ts:527-527 (registration)
    Inclusion of stablecoinToolDefinition in the optimizedToolDefinitions array for ListToolsRequest.
    stablecoinToolDefinition,
  • src/index.ts:58-58 (registration)
    Import of handler and tool definition from stablecoin module.
    import { stablecoinManage, stablecoinToolDefinition } from './tools/stablecoin.js';
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It does well by describing role-based controls, compliance features, and dangerous operations like 'delete' with DANGER warning. However, it lacks details about authentication requirements, rate limits, error handling, or what happens when operations fail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (OPERATIONS, FEATURES, AUTO-CONFIG, USE FOR) and efficiently communicates complex functionality. While comprehensive, it could be more front-loaded with the most critical information rather than burying the 'USE FOR' section at the end.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with 27 parameters, no annotations, and no output schema, the description provides good operational overview but lacks critical behavioral details. It doesn't explain return values, error conditions, or provide examples of successful usage patterns. The absence of output schema means the description should compensate more with expected response information.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 27 parameters thoroughly. The description adds value by explaining the purpose of operations and features like role-based access control, but doesn't provide additional parameter semantics beyond what's in the schema. Baseline 3 is appropriate when schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose as 'Enterprise-grade stablecoin management via Hedera Stablecoin Studio' and lists 18 specific operations. It distinguishes itself from sibling tools like 'token_manage' by focusing specifically on stablecoins with compliance features and role-based controls.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context with 'USE FOR: Institutional stablecoin issuance, compliance workflows, token lifecycle management' which gives appropriate usage scenarios. However, it doesn't explicitly state when NOT to use this tool or provide direct alternatives to sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/justmert/hashpilot'

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