Skip to main content
Glama

batch_scan

Scan up to 10 Solana token mints in parallel to assess portfolio risk. Returns verdict for each token in a single batch call.

Instructions

Scan multiple Solana tokens in a single call for portfolio-level risk assessment. Runs full_token_scan on each mint in parallel (max 10 per batch). Returns an array of results with verdicts for each token. Use this when evaluating a portfolio, watchlist, or multiple tokens from a pool discovery.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
mintsYesArray of Solana token mint addresses to scan (max 10)

Implementation Reference

  • The main handler for the batch_scan MCP tool. Accepts an array of up to 10 token mint addresses. For each mint, runs 5 analyses in parallel (token safety, honeypot check, holder analysis, Birdeye enrichment, and wallet reputation). Aggregates results using Promise.allSettled, computes a weighted final risk score, and returns verdicts (SAFE/CAUTION/HIGH_RISK/CRITICAL) for each token.
    // ── Tool: batch_scan ──────────────────────────────────────────────────
    server.tool(
        'batch_scan',
        `Scan multiple Solana tokens in a single call for portfolio-level risk assessment. Runs full_token_scan on each mint in parallel (max 10 per batch). Returns an array of results with verdicts for each token. Use this when evaluating a portfolio, watchlist, or multiple tokens from a pool discovery.`,
        {
            mints: z.array(z.string()).max(10).describe('Array of Solana token mint addresses to scan (max 10)'),
        },
        async ({ mints }) => {
            try {
                const results = await Promise.allSettled(
                    mints.map(async (mint) => {
                        const [safety, honeypot, holders, birdeye, walletIntel] = await Promise.all([
                            analyzeTokenSafety(connection, mint, undefined, false),
                            checkHoneypot(mint),
                            analyzeHolders(connection, mint),
                            enrichWithBirdeye(mint, BIRDEYE_API_KEY),
                            enrichCreatorReputation(mint, HELIUS_API_KEY),
                        ]);
    
                        let onChainScore = safety.riskScore;
                        if (honeypot.isHoneypot) onChainScore = Math.min(onChainScore + 30, 100);
                        if (holders.concentrated) onChainScore = Math.min(onChainScore + 15, 100);
    
                        const reputationScore = walletIntel.reputation?.riskScore ?? 0;
                        const marketScore = birdeye.marketRisk.score;
                        const finalScore = Math.round(
                            onChainScore * 0.60 + marketScore * 0.25 + reputationScore * 0.15
                        );
                        const verdict = finalScore === 0 ? 'SAFE'
                            : finalScore <= 15 ? 'CAUTION'
                            : finalScore <= 50 ? 'HIGH_RISK'
                            : 'CRITICAL';
    
                        return {
                            mint,
                            safe: safety.safe && !honeypot.isHoneypot && !holders.concentrated && marketScore < 30,
                            finalScore,
                            verdict,
                            honeypot: honeypot.isHoneypot,
                            liquidity: birdeye.overview?.liquidity ?? null,
                            marketFlags: birdeye.marketRisk.flags,
                            walletAge: walletIntel.reputation?.creatorAge ?? null,
                        };
                    })
                );
    
                const output = results.map((r, i) => {
                    if (r.status === 'fulfilled') return r.value;
                    return { mint: mints[i], error: r.reason?.message ?? String(r.reason) };
                });
    
                return {
                    content: [{
                        type: 'text' as const,
                        text: JSON.stringify({ scanned: output.length, results: output }, null, 2),
                    }],
                };
            } catch (e: unknown) {
                const msg = e instanceof Error ? e.message : String(e);
                return {
                    content: [{ type: 'text' as const, text: JSON.stringify({ error: msg }) }],
                    isError: true,
                };
            }
        },
    );
  • The batch_scan tool is registered via server.tool('batch_scan', ...) at line 320 of src/mcp/server.ts. The description tells the LLM this is for portfolio-level risk assessment of multiple tokens in a single call.
    }
  • The batch_scan tool is also listed in the MCP server card at /.well-known/mcp/server-card.json for Smithery/registry discovery, describing it as 'Scan up to 10 tokens in parallel for portfolio-level risk assessment.'
    { name: 'batch_scan', description: 'Scan up to 10 tokens in parallel for portfolio-level risk assessment.' },
  • Input schema for batch_scan: takes a 'mints' field which is a Zod array of strings with a maximum of 10 items. Validated using zod.
    {
        mints: z.array(z.string()).max(10).describe('Array of Solana token mint addresses to scan (max 10)'),
    },
Behavior3/5

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

No annotations provided, so description carries the burden. Discloses parallel execution, max 10 tokens, and returns array with verdicts. However, it does not mention authentication needs, rate limits, or whether it is read-only.

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?

Two sentences, no filler, front-loaded with the core purpose. Every sentence adds value.

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?

Given no output schema, description mentions return format (array of results with verdicts). For a 1-param tool, it is fairly complete, though the return structure could be more detailed.

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 has 100% coverage for the single parameter (mints). Description adds 'Solana' and 'to scan' but essentially restates the schema description. No additional meaning beyond schema.

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 it scans multiple Solana tokens for portfolio-level risk assessment, and distinguishes from sibling tools like 'full_token_scan' by specifying it runs that on each mint in parallel.

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?

Explicitly says to use when evaluating a portfolio, watchlist, or multiple tokens from a pool discovery. Implicitly distinguishes from single-token tools, though it could explicitly state when not to use.

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/Chronolapse411/sicarius-guard'

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