Skip to main content
Glama

get_risk_policy

Retrieve risk governance policies for crypto assets to determine trading limits, including position sizing, leverage restrictions, and allowed actions before executing trades.

Instructions

Get the current risk governance policy for a crypto asset. Returns policy level (BLOCK/CAUTIOUS/GREEN), max position size, leverage limits, allowed and blocked actions, and confidence score. Call this BEFORE every trade to determine how much risk is allowed.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
assetYesAsset to get risk policy for
wallet_addressNoDeFi wallet address for on-chain position data (LTV, health factor)
protocolNoDeFi lending protocol (default: spark)
include_detailsNoInclude detailed breakdown: composite subscores, macro data, risk flags, data sources

Implementation Reference

  • The get_risk_policy tool is registered and implemented directly in src/index.ts, combining definition, schema validation (using Zod), and the handler logic in one block.
    server.tool(
      "get_risk_policy",
      "Get the current risk governance policy for a crypto asset. Returns policy level (BLOCK/CAUTIOUS/GREEN), max position size, leverage limits, allowed and blocked actions, and confidence score. Call this BEFORE every trade to determine how much risk is allowed.",
      {
        asset: z.enum(["BTC", "ETH"]).describe("Asset to get risk policy for"),
        wallet_address: z
          .string()
          .optional()
          .describe(
            "DeFi wallet address for on-chain position data (LTV, health factor)"
          ),
        protocol: z
          .enum(["spark", "aave"])
          .optional()
          .describe("DeFi lending protocol (default: spark)"),
        include_details: z
          .boolean()
          .optional()
          .describe(
            "Include detailed breakdown: composite subscores, macro data, risk flags, data sources"
          ),
      },
      async (input) => {
        const apiKey = process.env.RISKSTATE_API_KEY;
        if (!apiKey) {
          return {
            content: [
              {
                type: "text" as const,
                text: "Error: RISKSTATE_API_KEY environment variable is required. Get a free API key at https://riskstate.ai",
              },
            ],
            isError: true,
          };
        }
    
        const body: Record<string, unknown> = { asset: input.asset };
        if (input.wallet_address) body.wallet_address = input.wallet_address;
        if (input.protocol) body.protocol = input.protocol;
        if (input.include_details) body.include_details = input.include_details;
    
        try {
          const response = await fetch(`${API_BASE}/v1/risk-state`, {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              Authorization: `Bearer ${apiKey}`,
            },
            body: JSON.stringify(body),
            signal: AbortSignal.timeout(15000),
          });
    
          if (!response.ok) {
            const status = response.status;
            const errorText = await response.text().catch(() => "");
    
            let message: string;
            if (status === 401) {
              message =
                "Authentication failed. Check your RISKSTATE_API_KEY is valid.";
            } else if (status === 429) {
              message =
                "Rate limited. Wait 60 seconds before retrying. Limit: 60 requests/minute.";
            } else if (status === 400) {
              message = `Bad request: ${errorText || "check parameters"}`;
            } else if (status >= 500) {
              message = `Server error (${status}). Retry in 30 seconds.`;
            } else {
              message = `HTTP ${status}: ${errorText || "Unknown error"}`;
            }
    
            return {
              content: [{ type: "text" as const, text: message }],
              isError: true,
            };
          }
    
          const data = await response.json();
    
          // Build human-readable summary for quick agent parsing
          const policy = data.exposure_policy || {};
          const classification = data.classification || {};
          const audit = data.auditability || {};
    
          const summary = [
            `POLICY: ${policy.policy_level || "UNKNOWN"}`,
            `MAX SIZE: ${policy.max_size_pct ?? "?"}%`,
            `LEVERAGE: ${policy.leverage_max ?? "?"}x`,
            `BLOCKED: ${(policy.blocked_actions || []).join(", ") || "none"}`,
            `REGIME: ${classification.market_regime || "?"} | DIRECTION: ${classification.direction || "?"}`,
            `COMPOSITE: ${audit.composite_score ?? "?"} | CONFIDENCE: ${audit.confidence_score ?? "?"}`,
            `TTL: ${audit.ttl_seconds ?? 60}s`,
          ].join("\n");
    
          return {
            content: [
              {
                type: "text" as const,
                text: summary + "\n\n" + JSON.stringify(data, null, 2),
              },
            ],
          };
        } catch (err) {
          const message =
            err instanceof Error
              ? err.name === "TimeoutError" || err.name === "AbortError"
                ? "Request timed out after 15s. The API may be under heavy load — retry in 30s."
                : `Network error: ${err.message}`
              : "Unknown error";
          return {
            content: [{ type: "text" as const, text: message }],
            isError: true,
          };
        }
      }
    );
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 effectively describes the return data structure and the pre-trade timing requirement, but lacks details about permissions, rate limits, error conditions, or whether this is a read-only operation. The description doesn't contradict any annotations.

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 efficiently structured in two sentences: the first explains what the tool does and returns, the second provides crucial usage guidance. Every word serves a purpose with zero wasted information, making it easy to parse and understand.

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

Completeness4/5

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

For a tool with no annotations and no output schema, the description does well by explaining the return values and usage timing. However, it could be more complete by mentioning authentication requirements, error handling, or whether the tool makes external API calls. The 100% schema coverage helps compensate for some gaps.

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 parameters thoroughly. The description doesn't add any parameter-specific information beyond what's in the schema, but it does provide context about why parameters matter (e.g., 'for on-chain position data'). This meets the baseline for high schema coverage.

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 specific action ('Get') and resource ('risk governance policy for a crypto asset'), including the exact data returned (policy level, max position size, leverage limits, allowed/blocked actions, confidence score). It distinguishes itself by focusing on pre-trade risk assessment without any sibling tools to differentiate from.

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

Usage Guidelines5/5

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

The description explicitly states when to use this tool: 'Call this BEFORE every trade to determine how much risk is allowed.' This provides clear, actionable guidance on the tool's intended context and timing, with no alternatives mentioned since there are no 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/likidodefi/riskstate-mcp'

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