DEV Community

albert nahas
albert nahas

Posted on • Originally published at leandine.hashnode.dev

Building an AI Meeting Summarizer with Claude and TypeScript

Meetings are the heartbeat of modern collaboration, but the aftershock—summarizing, capturing decisions, and tracking next steps—is where productivity often falters. Manual note-taking is error-prone and time-consuming, and even sophisticated transcription tools rarely provide the structured extraction that busy teams crave. This is where AI meeting summarizers, combined with APIs like Claude and the power of TypeScript, can elevate your workflow. Let’s dive into building a robust AI meeting summary pipeline that does more than just transcribe; it distills meetings into actionable intelligence.

Why Structured Meeting Summaries Matter

A transcript is not a summary, and a summary is not a decision log. Teams need more:

  • Concise summaries for quick reference
  • Explicit decisions to prevent ambiguity
  • Clear next steps to drive accountability

Automating this structured extraction saves hours and reduces the risk of missed follow-ups. By leveraging the Claude API for language understanding and TypeScript for type safety and maintainability, you can build a meeting summarizer that delivers real business value.

Overview of the Solution

Our goal is an AI meeting summarizer that takes meeting audio (or a transcript) and outputs a structured object:

type MeetingSummary = {
  summary: string;
  decisions: string[];
  nextSteps: string[];
};
Enter fullscreen mode Exit fullscreen mode

The workflow:

  1. Transcribe audio (optional, if you already have text)
  2. Send transcript to Claude API with a structured prompt
  3. Parse the response into a TypeScript object
  4. Integrate into your workflow (e.g., save to a database, send in Slack)

Step 1: Preparing the Transcript

If you’re starting from audio, use a speech-to-text engine like Whisper, Google Speech-to-Text, or AWS Transcribe. This step is crucial: high-quality transcripts yield better summaries.

// Example: loading a transcript from a file
import fs from 'fs/promises';

async function loadTranscript(path: string): Promise<string> {
  return await fs.readFile(path, 'utf8');
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Crafting a Structured Prompt for Claude

Large Language Models excel when given clear, structured instructions. For structured extraction, prompt engineering is key. Here’s a sample prompt to guide the Claude API:

You are an AI assistant. Given the following meeting transcript, extract:

1. A concise summary (2-3 sentences)
2. A list of key decisions made
3. A list of next steps and action items

Return your response in valid JSON with the fields: "summary", "decisions", and "nextSteps".

Transcript:
---
[Paste transcript here]
---
Enter fullscreen mode Exit fullscreen mode

Why JSON Output?

Requesting JSON ensures the response can be parsed programmatically, reducing ambiguity and making downstream processing trivial with TypeScript.

Step 3: Calling the Claude API with TypeScript

Assuming you have access to the Claude API (e.g., via Anthropic's API), you’ll need to make an authenticated POST request.

Here’s a skeleton using fetch:

const CLAUDE_API_URL = "https://api.anthropic.com/v1/messages";
const CLAUDE_API_KEY = process.env.CLAUDE_API_KEY; // secure your key!

async function getStructuredSummary(transcript: string): Promise<MeetingSummary> {
  const prompt = `
You are an AI assistant. Given the following meeting transcript, extract:

1. A concise summary (2-3 sentences)
2. A list of key decisions made
3. A list of next steps and action items

Return your response in valid JSON with the fields: "summary", "decisions", and "nextSteps".

Transcript:
---
${transcript}
---
`;

  const response = await fetch(CLAUDE_API_URL, {
    method: 'POST',
    headers: {
      'x-api-key': CLAUDE_API_KEY!,
      'content-type': 'application/json'
    },
    body: JSON.stringify({
      model: "claude-3-opus-20240229", // or another Claude model you have access to
      max_tokens: 1024,
      messages: [{ role: "user", content: prompt }]
    })
  });

  const data = await response.json();
  const completion = data?.content?.[0]?.text || data?.completion || '';

  // Parse the JSON output from Claude's response
  try {
    return JSON.parse(completion);
  } catch (e) {
    throw new Error("Failed to parse Claude output: " + e);
  }
}
Enter fullscreen mode Exit fullscreen mode

TypeScript Interface

type MeetingSummary = {
  summary: string;
  decisions: string[];
  nextSteps: string[];
};
Enter fullscreen mode Exit fullscreen mode

Error Handling & Validation

AI outputs are not always perfectly formatted. For reliability, add validation:

function isValidMeetingSummary(obj: any): obj is MeetingSummary {
  return (
    typeof obj.summary === 'string' &&
    Array.isArray(obj.decisions) &&
    Array.isArray(obj.nextSteps)
  );
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Putting It All Together

Here’s a full workflow example:

async function runMeetingSummarizer(transcriptPath: string) {
  const transcript = await loadTranscript(transcriptPath);
  const summary = await getStructuredSummary(transcript);

  if (!isValidMeetingSummary(summary)) {
    throw new Error("Summarizer returned invalid structure");
  }

  // Example output
  console.log("Summary:", summary.summary);
  console.log("Decisions:", summary.decisions.join('\n- '));
  console.log("Next Steps:", summary.nextSteps.join('\n- '));
}

// Usage
runMeetingSummarizer('./meeting.txt').catch(console.error);
Enter fullscreen mode Exit fullscreen mode

Practical Considerations and Best Practices

Handling Large Transcripts

Claude and similar LLMs have context window limits (e.g., 100k tokens for Claude 3 Opus). For long meetings:

  • Chunk the transcript and summarize each section
  • Merge chunk summaries into a final summary

Improving Summarization Quality

  • Experiment with prompts: Be explicit about desired format and length.
  • Pre-clean transcripts: Remove speaker labels, timestamps, and irrelevant chatter if possible.
  • Test with real meetings: Validate output with your team for accuracy and clarity.

Security and Privacy

  • Sensitive data: Ensure meeting data is handled securely and in compliance with privacy laws.
  • API keys: Store API credentials securely (e.g., environment variables, secret managers).

Integrating with Other Tools

Once you have structured extraction, the possibilities expand:

  • Send summaries to Slack/Teams
  • Create tasks in project management tools (Asana, Jira, etc.)
  • Archive summaries for compliance or searchability

Alternative APIs and Tools

While Claude is powerful for structured extraction, consider alternatives depending on your needs:

  • OpenAI GPT-4o/GPT-3.5 Turbo: Competitive language models with similar capabilities.
  • Google Vertex AI: Enterprise-focused models with robust APIs.
  • Azure OpenAI: Useful for organizations using Microsoft ecosystems.
  • Recallix, Otter.ai, Fireflies.ai: Products offering end-to-end AI meeting summary and insight extraction, sometimes with integrations and advanced analytics.

Each tool has trade-offs in terms of API access, pricing, privacy, and features.

Key Takeaways

Building an AI meeting summarizer with the Claude API and TypeScript enables teams to extract not just what was said, but what matters most: summaries, decisions, and next steps, all in a structured, actionable format. By combining robust prompt engineering, strong TypeScript typing, and careful handling of transcripts, you can automate a task that traditionally saps productivity. The real leverage comes from integrating these structured outputs into your workflows—so meetings become a launching pad for action, not a black hole where information goes to die.

Top comments (0)