Skip to main content
Glama
getgapup

@gapup/mcp-knowledge

by getgapup

pitch_deck_storyline

Read-onlyIdempotent

Generate a complete investor pitch-deck storyline tailored to your target audience. Returns 8-20 slides with key points, speaker notes, visual hints, and a Q&A bank of board questions and traps to avoid.

Instructions

Build a complete investor pitch-deck storyline for a company. Returns an 8-20 slide narrative tailored to the target audience (seed-vc / series-a-vc / growth-vc / strategic / bank / grant) — each slide carrying a title, key points, a speaker note and a visual hint — plus a Q&A bank of 10-15 likely board questions and traps to avoid. Output is deck JSON ready to export to Google Slides, Notion or Pitch.com. When to use this tool: the user is preparing a fundraise, a board meeting, or an investor presentation. Inputs: the company profile and the target audience type. Delivered by Sarah, the AI Fundraising lead of the Gapup portfolio.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
companyYes
audienceYesTarget audience — adapts tone + emphasis + Q&A bank
slideCountYes12 = standard VC deck, 15 = bank-friendly with annexes, 20 = growth/strategic
keyFactsYesHard facts to weave into the deck (traction numbers, milestones, awards)

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
executiveSummaryYesOne-paragraph elevator pitch distilled from the deck
slidesYes8-20 slide objects ready to export to Google Slides / Notion / Pitch.com
qaBanksYes10-15 anticipated investor questions with recommended answers
kpisNo3-5 headline KPI bubbles surfaced from keyFacts
recommendationsNoFundraising preparation actions

Implementation Reference

  • The handler function that executes the pitch_deck_storyline tool. It delegates to callGapupEndpoint which sends a POST request to the Gapup API with the slug 'pitch-deck-storyline'.
    export async function handle(input: unknown, signal?: AbortSignal): Promise<unknown> {
      return callGapupEndpoint("pitch-deck-storyline", input, signal);
    }
  • src/index.ts:36-42 (registration)
    Tool registration in the TOOLS array inside index.ts. The 'pitchDeckTool' and 'pitchDeckHandle' exports from pitch-deck-storyline.ts are registered and made available to the MCP server for listing and calling.
    const TOOLS: Array<{ def: ToolDef; handle: ToolHandle }> = [
      { def: competitorIntelTool, handle: competitorIntelHandle },
      { def: trendWatcherTool, handle: trendWatcherHandle },
      { def: partnershipTool, handle: partnershipHandle },
      { def: pitchDeckTool, handle: pitchDeckHandle },
      { def: carbonTool, handle: carbonHandle },
    ];
  • src/index.ts:24-24 (registration)
    Import of the tool definition and handler from pitch-deck-storyline.ts into index.ts for registration.
    import { tool as pitchDeckTool, handle as pitchDeckHandle } from "./tools/pitch-deck-storyline.js";
  • Full tool definition including name ('pitch_deck_storyline'), description, inputSchema, outputSchema, and annotations. Input requires company (name, pitch, stage), audience, slideCount (8-20), and keyFacts. Output includes executiveSummary, slides (8-20 with title, keyPoints, speakerNote, visualHint, layout), qaBanks (10-15 questions), kpis, and recommendations.
    export const tool = {
      name: "pitch_deck_storyline",
      description:
        "Build a complete investor pitch-deck storyline for a company. Returns an 8-20 slide narrative tailored to the target audience (seed-vc / series-a-vc / growth-vc / strategic / bank / grant) — each slide carrying a title, key points, a speaker note and a visual hint — plus a Q&A bank of 10-15 likely board questions and traps to avoid. Output is deck JSON ready to export to Google Slides, Notion or Pitch.com. When to use this tool: the user is preparing a fundraise, a board meeting, or an investor presentation. Inputs: the company profile and the target audience type. Delivered by Sarah, the AI Fundraising lead of the Gapup portfolio.",
      inputSchema: {
        type: "object",
        properties: {
          company: {
            type: "object",
            properties: {
              name: { type: "string", minLength: 2, maxLength: 120 },
              pitch: { type: "string", minLength: 20, maxLength: 800 },
              stage: {
                type: "string",
                enum: ["pre-seed", "seed", "series-a", "series-b", "series-c", "growth"],
              },
            },
            required: ["name", "pitch", "stage"],
          },
          audience: {
            type: "string",
            enum: ["seed-vc", "series-a-vc", "growth-vc", "strategic", "bank", "grant"],
            description: "Target audience — adapts tone + emphasis + Q&A bank",
          },
          slideCount: {
            type: "integer",
            minimum: 8,
            maximum: 20,
            description: "12 = standard VC deck, 15 = bank-friendly with annexes, 20 = growth/strategic",
          },
          keyFacts: {
            type: "array",
            items: { type: "string", minLength: 8, maxLength: 200 },
            minItems: 2,
            maxItems: 8,
            description: "Hard facts to weave into the deck (traction numbers, milestones, awards)",
          },
        },
        required: ["company", "audience", "slideCount", "keyFacts"],
      },
      outputSchema: {
        type: "object",
        properties: {
          executiveSummary: {
            type: "string",
            description: "One-paragraph elevator pitch distilled from the deck",
          },
          slides: {
            type: "array",
            description: "8-20 slide objects ready to export to Google Slides / Notion / Pitch.com",
            items: {
              type: "object",
              properties: {
                slideNumber: { type: "integer" },
                title: { type: "string" },
                keyPoints: {
                  type: "array",
                  items: { type: "string" },
                },
                speakerNote: { type: "string" },
                visualHint: { type: "string" },
                layout: {
                  type: "string",
                  description: "Suggested slide layout (title-only, two-column, chart, etc.)",
                },
              },
              required: ["slideNumber", "title", "keyPoints", "speakerNote"],
            },
          },
          qaBanks: {
            type: "array",
            description: "10-15 anticipated investor questions with recommended answers",
            items: {
              type: "object",
              properties: {
                question: { type: "string" },
                suggestedAnswer: { type: "string" },
                trap: { type: "string", description: "Common mistake to avoid when answering" },
              },
              required: ["question", "suggestedAnswer"],
            },
          },
          kpis: {
            type: "array",
            description: "3-5 headline KPI bubbles surfaced from keyFacts",
            items: {
              type: "object",
              properties: {
                label: { type: "string" },
                value: { type: "string" },
                trend: { type: "string", enum: ["up", "down", "stable"] },
              },
              required: ["label", "value"],
            },
          },
          recommendations: {
            type: "array",
            description: "Fundraising preparation actions",
            items: {
              type: "object",
              properties: {
                action: { type: "string" },
                rationale: { type: "string" },
              },
              required: ["action", "rationale"],
            },
          },
        },
        required: ["executiveSummary", "slides", "qaBanks"],
      },
      annotations: {
        readOnlyHint: true,
        idempotentHint: true,
        destructiveHint: false,
        openWorldHint: false,
        title: "Investor Pitch Deck Storyline",
      },
    } as const;
  • The callGapupEndpoint helper function used by the handler. It sends a POST request to the Gapup API at /api/agent/{slug} with the input as JSON body, passing the AbortSignal for cancellation. Includes error handling for 401, 402, 404, 429, and other HTTP errors.
    export async function callGapupEndpoint(
      slug: string,
      input: unknown,
      signal?: AbortSignal
    ): Promise<unknown> {
      const apiKey = process.env.GAPUP_API_KEY;
      if (!apiKey) {
        throw new GapupAuthError(
          "GAPUP_API_KEY environment variable required. Get a free tier key (100 calls/mo) at https://hub.gapup.io/agents-api/onboard"
        );
      }
    
      const res = await fetch(`${HUB_BASE_URL}/api/agent/${slug}`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-Api-Key": apiKey,
          "Accept": "application/json",
          "User-Agent": "@gapup/mcp-knowledge/0.1.0",
        },
        body: JSON.stringify(input),
        signal,
      });
    
      if (res.status === 401) {
        throw new GapupAuthError(
          "Invalid or missing GAPUP_API_KEY. Verify your key at https://hub.gapup.io/agents-api/onboard"
        );
      }
    
      if (res.status === 402) {
        const body = await res.text().catch(() => "");
        throw new GapupAuthError(
          `Free tier quota exhausted or paid auth required. Upgrade at https://hub.gapup.io/agents-api (received 402: ${body.slice(0, 120)})`
        );
      }
    
      if (res.status === 404) {
        throw new GapupApiError(
          404,
          `Endpoint '${slug}' not found — check GAPUP_API_BASE_URL or update the package (npm update @gapup/mcp-knowledge)`
        );
      }
    
      if (res.status === 429) {
        const retryAfter = res.headers.get("Retry-After");
        const retryMsg = retryAfter ? ` Retry after ${retryAfter} seconds.` : "";
        const body = await res.text().catch(() => "");
        throw new GapupApiError(
          429,
          `Rate limit exceeded.${retryMsg} Upgrade your plan at https://hub.gapup.io/agents-api (received: ${body.slice(0, 100)})`
        );
      }
    
      if (!res.ok) {
        const body = await res.text().catch(() => "");
        throw new GapupApiError(res.status, body);
      }
    
      return res.json();
    }
Behavior4/5

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

Annotations already declare read-only and idempotent behavior. Description adds context: generates 8-20 slides with speaker notes and Q&A, outputs JSON. No contradictions, and no side effects are omitted.

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?

Well-structured: starts with action, then output, usage, inputs, and persona. Every sentence adds value, though the persona line is marginally extraneous. Efficient overall.

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?

Covers all essential aspects: purpose, usage, input structure, and output format (slides and Q&A). An output schema exists, so return value details are not needed. Sufficient for an agent to understand and invoke correctly.

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 75% schema description coverage, the baseline is 3. Description generally mentions inputs but adds no new meaning beyond the schema's own descriptions for audience, slideCount, and keyFacts.

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 explicitly states 'Build a complete investor pitch-deck storyline for a company' with specific verb and resource. It distinguishes from sibling tools like carbon_footprint_calculator by focusing on fundraising presentations.

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?

Includes a dedicated 'When to use this tool' section covering fundraise, board meeting, or investor presentation, providing clear context for invocation. Lacks explicit when-not or alternative tool recommendations, but the given guidance is sufficient.

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/getgapup/gapup-mcp'

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