Skip to main content
Glama

menese_strategy

Create and manage automated trading strategies including DCA, Take Profit, and Stop Loss across 19 blockchain networks to optimize cryptocurrency investments.

Instructions

Manage automated trading strategies: DCA (dollar-cost averaging), Take Profit (sell above target), Stop Loss (sell below threshold).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesAction to perform
strategyTypeNoStrategy type (required for create)
chainNoTarget chain (required for create)
amountNoAmount per execution (decimal, for create)
intervalSecondsNoInterval between DCA executions in seconds (min 60)
maxExecutionsNoMax number of executions
targetPriceNoTarget price in USD (for take_profit/stop_loss)
ruleIdNoRule ID (for cancel)

Implementation Reference

  • The handler logic for 'menese_strategy' tool, managing create, list, and cancel actions for trading strategies.
    async ({ action, strategyType, chain, amount, intervalSeconds, maxExecutions, targetPrice, ruleId }) => {
      const identity = store.get();
      if (!identity) {
        return { content: [{ type: "text" as const, text: "No wallet configured. Use menese_setup first." }], isError: true };
      }
    
      if (action === "list") {
        const result = await listStrategies(config, resolveActorIdentity(store));
        return {
          content: [{
            type: "text" as const,
            text: JSON.stringify(result, bigIntReplacer, 2),
          }],
        };
      }
    
      if (action === "cancel") {
        if (ruleId == null) {
          return { content: [{ type: "text" as const, text: "ruleId is required for cancel." }], isError: true };
        }
        const result = await deleteStrategy(config, resolveActorIdentity(store), ruleId);
        return {
          content: [{
            type: "text" as const,
            text: JSON.stringify(result, bigIntReplacer, 2),
          }],
        };
      }
    
      // action === "create"
      if (!strategyType || !chain || !amount) {
        return {
          content: [{ type: "text" as const, text: "strategyType, chain, and amount are required for create." }],
          isError: true,
        };
      }
    
      const chainType = CHAIN_TYPE_MAP[chain];
      const ruleType = RULE_TYPE_MAP[strategyType];
      if (!chainType || !ruleType) {
        return { content: [{ type: "text" as const, text: "Invalid chain or strategy type." }], isError: true };
      }
    
      const decimals = CHAIN_DECIMALS[chain] ?? 18;
      const triggerPrice = targetPrice ? BigInt(Math.round(parseFloat(targetPrice) * 1_000_000)) : 0n;
    
      // Build the Candid Rule record
      const rule: Record<string, unknown> = {
        chainType,
        ruleType,
        triggerPrice,
        sizePct: 100n,
        positionId: 0n,
        id: 0n,
        status: { Draft: null },
        createdAt: BigInt(Date.now()) * 1_000_000n,
        apyMigrationConfig: [],
        lpConfig: [],
        scheduledConfig: [],
        volatilityConfig: [],
        swapAmountDrops: [],
        swapAmountLamports: [],
        swapAmountWei: [],
        dcaConfig: [],
      };
    
      // Set chain-specific amount field
      if (chain === "solana") {
        rule.swapAmountLamports = [parseAmount(amount, 9)];
      } else if (chain === "xrp") {
        rule.swapAmountDrops = [parseAmount(amount, 6)];
      } else {
        rule.swapAmountWei = [parseAmount(amount, decimals)];
      }
    
      // DCA config
      if (strategyType === "dca" && intervalSeconds) {
        rule.dcaConfig = [{ intervalSeconds: BigInt(intervalSeconds), maxExecutions: maxExecutions ? [BigInt(maxExecutions)] : [] }];
      }
    
      const result = await addStrategy(config, resolveActorIdentity(store), rule);
      return {
        content: [{
          type: "text" as const,
          text: JSON.stringify(result, bigIntReplacer, 2),
        }],
      };
    },
  • The input schema for 'menese_strategy', defining parameters for different actions.
    description:
      "Manage automated trading strategies: DCA (dollar-cost averaging), " +
      "Take Profit (sell above target), Stop Loss (sell below threshold).",
    inputSchema: {
      action: z.enum(["create", "list", "cancel"]).describe("Action to perform"),
      strategyType: z.enum(["dca", "take_profit", "stop_loss"]).optional()
        .describe("Strategy type (required for create)"),
      chain: z.enum(SUPPORTED_CHAINS as unknown as [string, ...string[]]).optional()
        .describe("Target chain (required for create)"),
      amount: z.string().optional().describe("Amount per execution (decimal, for create)"),
      intervalSeconds: z.number().min(60).optional()
        .describe("Interval between DCA executions in seconds (min 60)"),
      maxExecutions: z.number().min(1).optional()
        .describe("Max number of executions"),
      targetPrice: z.string().optional()
        .describe("Target price in USD (for take_profit/stop_loss)"),
      ruleId: z.number().optional().describe("Rule ID (for cancel)"),
    },
  • Registration function for the 'menese_strategy' tool.
    export function registerStrategyTool(
      server: McpServer,
      store: IdentityStore,
      config: MeneseConfig,
    ): void {
      server.registerTool(
        "menese_strategy",
        {
          description:
            "Manage automated trading strategies: DCA (dollar-cost averaging), " +
            "Take Profit (sell above target), Stop Loss (sell below threshold).",
          inputSchema: {
            action: z.enum(["create", "list", "cancel"]).describe("Action to perform"),
            strategyType: z.enum(["dca", "take_profit", "stop_loss"]).optional()
              .describe("Strategy type (required for create)"),
            chain: z.enum(SUPPORTED_CHAINS as unknown as [string, ...string[]]).optional()
              .describe("Target chain (required for create)"),
            amount: z.string().optional().describe("Amount per execution (decimal, for create)"),
            intervalSeconds: z.number().min(60).optional()
              .describe("Interval between DCA executions in seconds (min 60)"),
            maxExecutions: z.number().min(1).optional()
              .describe("Max number of executions"),
            targetPrice: z.string().optional()
              .describe("Target price in USD (for take_profit/stop_loss)"),
            ruleId: z.number().optional().describe("Rule ID (for cancel)"),
          },
        },
        async ({ action, strategyType, chain, amount, intervalSeconds, maxExecutions, targetPrice, ruleId }) => {
          const identity = store.get();
          if (!identity) {
            return { content: [{ type: "text" as const, text: "No wallet configured. Use menese_setup first." }], isError: true };
          }
    
          if (action === "list") {
            const result = await listStrategies(config, resolveActorIdentity(store));
            return {
              content: [{
                type: "text" as const,
                text: JSON.stringify(result, bigIntReplacer, 2),
              }],
            };
          }
    
          if (action === "cancel") {
            if (ruleId == null) {
              return { content: [{ type: "text" as const, text: "ruleId is required for cancel." }], isError: true };
            }
            const result = await deleteStrategy(config, resolveActorIdentity(store), ruleId);
            return {
              content: [{
                type: "text" as const,
                text: JSON.stringify(result, bigIntReplacer, 2),
              }],
            };
          }
    
          // action === "create"
          if (!strategyType || !chain || !amount) {
            return {
              content: [{ type: "text" as const, text: "strategyType, chain, and amount are required for create." }],
              isError: true,
            };
          }
    
          const chainType = CHAIN_TYPE_MAP[chain];
          const ruleType = RULE_TYPE_MAP[strategyType];
          if (!chainType || !ruleType) {
            return { content: [{ type: "text" as const, text: "Invalid chain or strategy type." }], isError: true };
          }
    
          const decimals = CHAIN_DECIMALS[chain] ?? 18;
          const triggerPrice = targetPrice ? BigInt(Math.round(parseFloat(targetPrice) * 1_000_000)) : 0n;
    
          // Build the Candid Rule record
          const rule: Record<string, unknown> = {
            chainType,
            ruleType,
            triggerPrice,
            sizePct: 100n,
            positionId: 0n,
            id: 0n,
            status: { Draft: null },
            createdAt: BigInt(Date.now()) * 1_000_000n,
            apyMigrationConfig: [],
            lpConfig: [],
            scheduledConfig: [],
            volatilityConfig: [],
            swapAmountDrops: [],
            swapAmountLamports: [],
            swapAmountWei: [],
            dcaConfig: [],
          };
    
          // Set chain-specific amount field
          if (chain === "solana") {
            rule.swapAmountLamports = [parseAmount(amount, 9)];
          } else if (chain === "xrp") {
            rule.swapAmountDrops = [parseAmount(amount, 6)];
          } else {
            rule.swapAmountWei = [parseAmount(amount, decimals)];
          }
    
          // DCA config
          if (strategyType === "dca" && intervalSeconds) {
            rule.dcaConfig = [{ intervalSeconds: BigInt(intervalSeconds), maxExecutions: maxExecutions ? [BigInt(maxExecutions)] : [] }];
          }
    
          const result = await addStrategy(config, resolveActorIdentity(store), rule);
          return {
            content: [{
              type: "text" as const,
              text: JSON.stringify(result, bigIntReplacer, 2),
            }],
          };
        },
      );
    }
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. It discloses that strategies are 'automated' and explains the behavioral logic of each strategy type (e.g., Stop Loss triggers 'below threshold'). However, it omits operational details such as whether strategies persist until canceled, if funds are reserved upon creation, or what the list/cancel actions return.

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

Conciseness5/5

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

The description is a single, front-loaded sentence where every clause earns its place. It efficiently introduces the resource ('Manage automated trading strategies') and immediately specifies the three variant behaviors without redundant verbosity.

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?

Given the 8 parameters with conditional requirements (e.g., targetPrice only for specific strategies) and no output schema, the description adequately covers the 'what' but leaves gaps on the action types (create/list/cancel) and return values. The 100% schema coverage compensates for parameter details, but the description should ideally acknowledge the CRUD nature of the tool.

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

Parameters4/5

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

Schema coverage is 100%, establishing a baseline of 3. The description adds value by defining the semantic meaning of the strategyType enum values (e.g., explaining DCA as 'dollar-cost averaging' and Take Profit as 'sell above target'), which helps the agent map user intent to the correct parameter value.

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 uses specific verbs ('Manage') and resources ('automated trading strategies') and explicitly lists the three supported strategy types (DCA, Take Profit, Stop Loss). The term 'automated' clearly distinguishes this from sibling tools like menese_swap or menese_send which handle immediate transactions.

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

Usage Guidelines3/5

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

The description explains what each strategy type does (e.g., 'sell above target' for Take Profit), providing implicit guidance on when to select each strategyType. However, it lacks explicit guidance on when to use this tool versus immediate execution tools like menese_swap, or prerequisites for creating strategies.

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/Aboodtt404/mcp-menesesdk'

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