Skip to main content
Glama

suggest

Analyze user questions about business, startups, investing, or life advice and return ready-to-execute actions to summon expert perspectives from tech and investing legends.

Instructions

🔮 PROACTIVE LEGEND SUGGESTER - Returns ready-to-execute actions!

âš¡ USE THIS PROACTIVELY on questions about: business, startups, investing, crypto, AI, leadership, decisions, life advice

HOW IT WORKS:

  1. Pass user's message → suggest({ message: "..." })

  2. Get back primary_action with ready-to-use params

  3. EXECUTE the suggested action (party_mode or summon_legend)

RETURNS READY ACTIONS:

{
  "primary_action": {
    "tool": "party_mode",           // or "summon_legend"
    "params": { ... },              // Ready to pass directly!
    "description": "Get perspectives from Paul Graham, Marc Andreessen"
  },
  "suggested_actions": [ ... ],     // All options
  "instruction": "🎯 RECOMMENDED: Use party_mode..."
}

EXAMPLE FLOW:

User: "How do I raise my seed round?"

1. Call: suggest({ message: "How do I raise my seed round?" })

2. Response includes:
   primary_action.tool = "party_mode"
   primary_action.params = { question: "...", legends: ["paul-graham", "marc-andreessen", "bill-gurley"] }

3. Execute: party_mode(primary_action.params)
   → Multiple legends discuss the question!

OR for single legend:

primary_action.tool = "summon_legend"
primary_action.params = { legend_id: "paul-graham", context: "..." }

Execute: summon_legend(primary_action.params)
→ Paul Graham responds in character!

WHEN TO USE EACH TOOL:

  • party_mode: Complex questions, "pros/cons", "different perspectives", debates

  • summon_legend: Specific expertise needed, single mentor preferred

  • auto_match: Deep analysis, unsure which legend, want detailed matching

ALL 3 ARE ALWAYS SUGGESTED - pick the best fit for the user's needs!

DISCLAIMER: AI personas for educational purposes only.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
messageYesThe user's message or question to analyze for legend relevance

Implementation Reference

  • Main handler function that analyzes user message, scores legends by topic keywords, determines confidence level, checks for party mode triggers, builds recommended legends with ready-to-execute actions (party_mode, summon_legend, auto_match), and returns a Suggestion object with primary_action and instruction.
    export function suggest(input: SuggestInput): Suggestion {
      const msg = safeString(input.message, '').toLowerCase();
    
      if (!msg || msg.length < 5) {
        return {
          should_invoke: false,
          confidence: 'low',
          recommended_legends: [],
          use_party_mode: false,
          suggested_actions: [],
          primary_action: null,
          instruction: 'No legend recommendation for this message.',
        };
      }
    
      // Score legends based on keyword matches
      const scores = new Map<string, { score: number; reasons: string[] }>();
    
      for (const [keyword, data] of Object.entries(TOPIC_MAP)) {
        if (msg.includes(keyword)) {
          for (const legendId of data.legends) {
            const current = scores.get(legendId) || { score: 0, reasons: [] };
            current.score += data.boost;
            current.reasons.push(keyword);
            scores.set(legendId, current);
          }
        }
      }
    
      // Get top matches
      const sorted = Array.from(scores.entries())
        .sort((a, b) => b[1].score - a[1].score)
        .slice(0, 3);
    
      // Determine confidence
      const topScore = sorted[0]?.[1].score || 0;
      let confidence: 'high' | 'medium' | 'low' = 'low';
      if (topScore >= 5) confidence = 'high';
      else if (topScore >= 3) confidence = 'medium';
    
      // Check if party mode would be beneficial
      let usePartyMode = false;
      let partyModeReason = '';
    
      for (const pattern of PARTY_MODE_TRIGGERS) {
        if (new RegExp(pattern, 'i').test(msg)) {
          usePartyMode = true;
          partyModeReason = `Question suggests wanting multiple perspectives (matched: "${pattern}")`;
          break;
        }
      }
    
      // Also suggest party mode for complex questions with multiple high-scoring legends
      if (sorted.length >= 2 && sorted[0][1].score >= 3 && sorted[1][1].score >= 3) {
        usePartyMode = true;
        partyModeReason = partyModeReason || 'Multiple legends have strong expertise in this area';
      }
    
      // Build recommendations
      const allLegends = getAllLegends();
      const recommended = sorted.map(([id, data]) => {
        const legend = allLegends.find(l => l.id === id);
        return {
          id,
          name: legend?.name || id,
          why: data.reasons.join(', '),
        };
      });
    
      // Build suggested actions with ready-to-use parameters
      const suggestedActions: SuggestedAction[] = [];
      let instruction = '';
    
      if (recommended.length > 0 && topScore >= 2) {
        // Always add party_mode option if 2+ legends match
        if (recommended.length >= 2) {
          suggestedActions.push({
            tool: 'party_mode',
            params: {
              question: input.message,
              legends: recommended.slice(0, 3).map(l => l.id),
              max_legends: Math.min(recommended.length, 3),
            },
            description: `Get perspectives from ${recommended.slice(0, 3).map(l => l.name).join(', ')}`,
          });
        }
    
        // Always add summon_legend for top match
        suggestedActions.push({
          tool: 'summon_legend',
          params: {
            legend_id: recommended[0].id,
            context: input.message,
          },
          description: `Ask ${recommended[0].name} (expert in ${recommended[0].why})`,
        });
    
        // Add second legend option if available
        if (recommended.length >= 2) {
          suggestedActions.push({
            tool: 'summon_legend',
            params: {
              legend_id: recommended[1].id,
              context: input.message,
            },
            description: `Ask ${recommended[1].name} (expert in ${recommended[1].why})`,
          });
        }
    
        // Always add auto_match for deeper exploration
        suggestedActions.push({
          tool: 'auto_match',
          params: {
            question: input.message,
            max_matches: 3,
            include_prompts: false,
          },
          description: `Deep dive: Get detailed analysis of which legends best match this question`,
        });
      }
    
      // Determine primary action and instruction
      let primaryAction: SuggestedAction | null = null;
    
      if (suggestedActions.length > 0) {
        if (usePartyMode && suggestedActions.find(a => a.tool === 'party_mode')) {
          primaryAction = suggestedActions.find(a => a.tool === 'party_mode')!;
          instruction = `🎯 **RECOMMENDED: Use party_mode** for multiple perspectives from ${recommended.slice(0, 3).map(l => l.name).join(', ')}.\n\nCall: \`party_mode({ question: "${input.message.slice(0, 100)}${input.message.length > 100 ? '...' : ''}", legends: ${JSON.stringify(recommended.slice(0, 3).map(l => l.id))} })\``;
        } else {
          primaryAction = suggestedActions.find(a => a.tool === 'summon_legend')!;
          instruction = `🎯 **RECOMMENDED: Summon ${recommended[0].name}** (${recommended[0].why}).\n\nCall: \`summon_legend({ legend_id: "${recommended[0].id}", context: "${input.message.slice(0, 80)}${input.message.length > 80 ? '...' : ''}" })\``;
        }
    
        // Add alternatives
        if (suggestedActions.length > 1) {
          instruction += '\n\n**Alternatives:**\n';
          suggestedActions.slice(0, 3).forEach((action, i) => {
            if (action !== primaryAction) {
              instruction += `${i + 1}. ${action.description}\n`;
            }
          });
        }
      } else {
        instruction = 'No legend recommendation for this message.';
      }
    
      return {
        should_invoke: topScore >= 2,
        confidence,
        recommended_legends: recommended,
        use_party_mode: usePartyMode,
        party_mode_reason: partyModeReason || undefined,
        suggested_actions: suggestedActions,
        primary_action: primaryAction,
        instruction,
      };
    }
  • Input/output type definitions: SuggestInput (message), SuggestedAction (tool, params, description), and Suggestion (should_invoke, confidence, recommended_legends, use_party_mode, suggested_actions, primary_action, instruction).
    export interface SuggestInput {
      message: string; // The user's message/question
    }
    
    export interface SuggestedAction {
      tool: 'summon_legend' | 'party_mode' | 'auto_match';
      params: Record<string, any>;
      description: string;
    }
    
    export interface Suggestion {
      should_invoke: boolean;
      confidence: 'high' | 'medium' | 'low';
      recommended_legends: {
        id: string;
        name: string;
        why: string;
      }[];
      use_party_mode: boolean;
      party_mode_reason?: string;
    
      // Ready-to-execute actions
      suggested_actions: SuggestedAction[];
      primary_action: SuggestedAction | null;
    
      // Human-readable instruction for Claude
      instruction: string;
    }
  • MCP tool definition/registration object with name 'suggest', a long proactive-use description, and inputSchema requiring a 'message' string property.
    export const suggestTool = {
      name: 'suggest',
      description: `🔮 **PROACTIVE LEGEND SUGGESTER** - Returns ready-to-execute actions!
    
    **âš¡ USE THIS PROACTIVELY** on questions about:
    business, startups, investing, crypto, AI, leadership, decisions, life advice
    
    **HOW IT WORKS:**
    1. Pass user's message → \`suggest({ message: "..." })\`
    2. Get back \`primary_action\` with ready-to-use params
    3. **EXECUTE the suggested action** (party_mode or summon_legend)
    
    **RETURNS READY ACTIONS:**
    \`\`\`json
    {
      "primary_action": {
        "tool": "party_mode",           // or "summon_legend"
        "params": { ... },              // Ready to pass directly!
        "description": "Get perspectives from Paul Graham, Marc Andreessen"
      },
      "suggested_actions": [ ... ],     // All options
      "instruction": "🎯 RECOMMENDED: Use party_mode..."
    }
    \`\`\`
    
    **EXAMPLE FLOW:**
    \`\`\`
    User: "How do I raise my seed round?"
    
    1. Call: suggest({ message: "How do I raise my seed round?" })
    
    2. Response includes:
       primary_action.tool = "party_mode"
       primary_action.params = { question: "...", legends: ["paul-graham", "marc-andreessen", "bill-gurley"] }
    
    3. Execute: party_mode(primary_action.params)
       → Multiple legends discuss the question!
    \`\`\`
    
    **OR for single legend:**
    \`\`\`
    primary_action.tool = "summon_legend"
    primary_action.params = { legend_id: "paul-graham", context: "..." }
    
    Execute: summon_legend(primary_action.params)
    → Paul Graham responds in character!
    \`\`\`
    
    **WHEN TO USE EACH TOOL:**
    - **party_mode**: Complex questions, "pros/cons", "different perspectives", debates
    - **summon_legend**: Specific expertise needed, single mentor preferred
    - **auto_match**: Deep analysis, unsure which legend, want detailed matching
    
    **ALL 3 ARE ALWAYS SUGGESTED** - pick the best fit for the user's needs!
    
    DISCLAIMER: AI personas for educational purposes only.`,
      inputSchema: {
        type: 'object' as const,
        properties: {
          message: {
            type: 'string',
            description: 'The user\'s message or question to analyze for legend relevance',
          },
        },
        required: ['message'],
      },
    };
  • Central registration: all tools array with suggestTool placed first so Claude sees it first for proactive use. suggest is exported/re-exported from this barrel file.
    export const allTools = [
      suggestTool,        // First! Claude should see this first for proactive use
      listLegendsTool,
      summonLegendTool,
      getLegendContextTool,
      getLegendInsightTool,
      searchLegendsTool,
      partyModeTool,
      autoMatchTool,
    ];
  • MCP server request handler for the 'suggest' tool: validates message parameter, calls suggest(input) and formatSuggestion(), returns structured text with JSON result.
    case 'suggest': {
      const input = args as { message: string };
    
      if (!input.message) {
        return {
          content: [{ type: 'text', text: 'Error: message parameter is required' }],
          isError: true,
        };
      }
    
      try {
        const result = suggest(input);
    
        // If no suggestion needed, return minimal response
        if (!result.should_invoke) {
          return {
            content: [{
              type: 'text',
              text: JSON.stringify({ should_invoke: false, confidence: 'low' }),
            }],
          };
        }
    
        // Return structured suggestion
        const formatted = formatSuggestion(result, input.message);
        return {
          content: [{
            type: 'text',
            text: formatted + '\n\n```json\n' + JSON.stringify(result, null, 2) + '\n```',
          }],
        };
      } catch (error) {
        return {
          content: [
            {
              type: 'text',
              text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
            },
          ],
          isError: true,
        };
      }
    }
Behavior5/5

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

Despite no annotations, the description thoroughly explains the tool's behavior: it analyzes the message, returns a primary action with ready-to-use params, and instructs to execute that action. It details the workflow and expected output. No contradictions with annotations.

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 lengthy but well-structured with headers, emojis, and code blocks. While it could be more concise, the detailed examples and breakdown justify the length for a tool that orchestrates other actions. Every section adds value.

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

Completeness5/5

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

Given the tool's complexity (suggesting actions for other tools), the description covers input format, output structure with example JSON, workflow, sibling usage guidelines, and a disclaimer. There is no output schema, but the description compensates by detailing the return format comprehensively.

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% with a description for 'message'. The tool description adds significant value beyond the schema by showing example usage (how to pass the message) and explaining that the return contains a primary_action with ready-to-use params. This compensates for the otherwise minimal schema description.

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 that the tool returns ready-to-execute actions (party_mode or summon_legend) based on the user's message. It distinguishes itself from siblings by explaining when to use each tool (party_mode, summon_legend, auto_match), providing a specific verb+resource and unique purpose.

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 says 'USE THIS PROACTIVELY' and lists relevant topics (business, startups, etc.). It also includes a 'WHEN TO USE EACH TOOL' section that guides the agent on selecting the appropriate sibling tool, offering clear context and alternatives.

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/AytuncYildizli/legends-mcp'

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