Skip to main content
Glama

normalize_idea

Transform raw ideas into structured work items by analyzing intent signals, assessing readiness, and generating execution-ready specifications for backlog integration.

Instructions

Transform raw ideas into execution-ready work items. This is the moment where thinking stops and execution begins.

IdeaLift is a COMMIT LAYER - it judges whether an idea is ready for execution and helps make it real.

USE this tool when you detect intent signals like:

  • "We should..." / "What if we..." / "Someone suggested..."

  • "This is annoying..." / "Users keep asking for..."

  • "Feature request:" / "Bug report:" / "Can we add..."

  • User pastes meeting notes, Slack threads, or raw text

  • User says "normalize", "make this backlog-ready", "turn this into a ticket"

When you detect these signals, PROACTIVELY offer: "This looks like a feature idea. Want me to make it execution-ready?"

Output includes:

  • Readiness Verdict (READY / ALMOST READY / NOT READY)

  • Signal Analysis (urgency, clarity, duplicate risk, actionability)

  • Structured spec (summary, acceptance criteria, scope)

  • Commit options (GitHub, Jira, Linear, or Refine)

The output ALWAYS ends with a commit decision - never leave users in limbo.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
textYesThe raw text to normalize (meeting notes, feature request, bug report, slack message, etc.)
contextNo

Implementation Reference

  • The `handleNormalizeIdea` function orchestrates the logic for the "normalize_idea" tool. It takes raw text as input, calls the `idealiftClient` to normalize it into a structured idea ticket, saves a draft, and formats the output for the MCP client.
    export async function handleNormalizeIdea(
      args: Record<string, unknown>,
      chatgptSubjectId?: string
    ): Promise<NormalizeOutput> {
      // Validate input
      const input = NormalizeIdeaInput.parse(args);
    
      let result: NormalizeResult;
      let draftId: string | undefined;
    
      try {
        // Call IdeaLift internal API
        result = await idealiftClient.normalize(input.text);
      } catch (error) {
        console.error('Normalize idea error:', error);
    
        // Fallback: basic text extraction
        const lines = input.text.split('\n').filter(l => l.trim());
        const title = lines[0]?.substring(0, 80) || 'Untitled Idea';
        const summary = lines.slice(0, 3).join(' ').substring(0, 500);
    
        result = {
          title,
          type: 'story',
          priority: 'medium',
          component: 'General',
          labels: [],
          summary,
          acceptanceCriteria: lines.slice(1, 4).map(l => l.substring(0, 200)),
          implementationNotes: [],
          outOfScope: [],
          definitionOfDone: ['Implementation complete', 'Code reviewed', 'Tests passing'],
          signals: {
            urgency: 'medium',
            clarity: 'low',
            duplicateRisk: 'medium',
            suggestedOwner: 'Product',
            sourceType: 'unknown',
            actionability: 'needs-clarification'
          },
          keyPoints: lines.slice(1, 4).map(l => l.substring(0, 100)),
          category: 'other',
          actionable: true,
          confidence: 0.3,
        };
      }
    
      // Save draft for later commit (survives context loss)
      try {
        const draftResponse = await idealiftClient.saveDraft(
          chatgptSubjectId,
          result.title,
          result.summary,
          result as unknown as Record<string, unknown>
        );
        draftId = draftResponse.draftId;
        console.log('[Normalize] Saved draft:', draftId);
      } catch (draftError) {
        console.error('[Normalize] Failed to save draft:', draftError);
        // Continue without draft - commit will still work with full idea object
      }
    
      const content = formatComprehensiveOutput(result, draftId);
    
      return {
        structuredContent: { ...result, draftId },
        content,
      };
    }
  • The `normalizeIdeaTool` constant defines the MCP tool structure, including its name, description, and input schema.
    export const normalizeIdeaTool = {
      name: 'normalize_idea',
      description: `Transform raw ideas into execution-ready work items. This is the moment where thinking stops and execution begins.
    
    IdeaLift is a COMMIT LAYER - it judges whether an idea is ready for execution and helps make it real.
    
    USE this tool when you detect intent signals like:
    - "We should..." / "What if we..." / "Someone suggested..."
    - "This is annoying..." / "Users keep asking for..."
    - "Feature request:" / "Bug report:" / "Can we add..."
    - User pastes meeting notes, Slack threads, or raw text
    - User says "normalize", "make this backlog-ready", "turn this into a ticket"
    
    When you detect these signals, PROACTIVELY offer:
    "This looks like a feature idea. Want me to make it execution-ready?"
    
    Output includes:
    - Readiness Verdict (READY / ALMOST READY / NOT READY)
    - Signal Analysis (urgency, clarity, duplicate risk, actionability)
    - Structured spec (summary, acceptance criteria, scope)
    - Commit options (GitHub, Jira, Linear, or Refine)
    
    The output ALWAYS ends with a commit decision - never leave users in limbo.`,
      inputSchema: {
        type: 'object' as const,
        properties: {
          text: {
            type: 'string',
            description: 'The raw text to normalize (meeting notes, feature request, bug report, slack message, etc.)',
          },
          context: {
            type: 'object',
            properties: {
              source: {
                type: 'string',
                enum: ['chatgpt'],
              },
            },
          },
        },
        required: ['text'],
      },
      annotations: {
        readOnlyHint: false,    // Saves draft to database for later retrieval
        destructiveHint: false, // Creates new drafts, never deletes existing data
        openWorldHint: true,    // Calls IdeaLift API for AI normalization
      },
      _meta: {
        'openai/outputTemplate': 'resource://widget/preview',
        'openai/widgetAccessible': true,
        'openai/visibility': 'public',
        'openai/toolInvocation/invoking': 'Creating comprehensive spec...',
        'openai/toolInvocation/invoked': 'Spec ready for review',
      },
    };
  • The `NormalizeResult` interface defines the structure of the normalized idea ticket returned by the tool.
    export interface NormalizeResult {
      title: string;
      type: 'story' | 'bug' | 'task' | 'spike' | 'epic';
      priority: 'low' | 'medium' | 'high' | 'critical';
      component: string;
      labels: string[];
      summary: string;
      acceptanceCriteria: string[];
      implementationNotes: string[];
      outOfScope: string[];
      definitionOfDone: string[];
      // Signal extraction - operational intelligence
      signals: SignalSummary;
      // Legacy fields for backwards compatibility
      keyPoints: string[];
      category: 'feature' | 'bug' | 'improvement' | 'research' | 'documentation' | 'other';
      actionable: boolean;
      confidence: number;
    }
Behavior4/5

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

While annotations indicate non-destructive mutation (readOnly=false, destructive=false) and external interaction (openWorld=true), the description adds valuable behavioral context: it discloses the judgment/verdict mechanism (READY/ALMOST READY/NOT READY), signal analysis outputs, and the guarantee that output 'ALWAYS ends with a commit decision' with specific external destinations (GitHub, Jira, Linear).

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?

Though lengthy, the description is well-structured with clear functional sections (purpose, usage triggers, proactive guidance, output specification). Minor inefficiency exists with poetic/marketing phrases ('This is the moment where thinking stops', 'IdeaLift'), but overall every section serves the agent's understanding.

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?

Despite lacking a formal output schema, the description comprehensively details the return structure through explicit enumeration: Readiness Verdict, Signal Analysis, Structured spec, and Commit options. This adequately compensates for the missing output schema in a complex multi-step tool.

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?

With 50% schema description coverage, the description partially compensates by contextualizing the types of input (meeting notes, Slack threads, feature requests) that map to the 'text' parameter. However, it fails to mention the 'context' parameter or its 'source' enum entirely, leaving that parameter undocumented beyond the 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 the specific action ('Transform raw ideas into execution-ready work items') and distinguishes this from sibling tools like create_idea or update_idea by positioning it as a 'COMMIT LAYER' that judges readiness and bridges thinking to execution.

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?

Contains an explicit 'USE this tool when' section with specific intent signals (e.g., 'We should...', 'Feature request:', 'normalize', 'make this backlog-ready') and instructs the agent to 'PROACTIVELY offer' usage when these signals are detected, providing clear guidance on when versus 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/Startvest-LLC/idealift-mcp-server'

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