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;
    }

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