ClawMart AI
← Back to Blog
August 25, 20267 min readClaw Mart Team

Meeting Notes Agent: How to Auto-Summarize Zoom Calls with OpenClaw

Meeting Notes Agent: How to Auto-Summarize Zoom Calls with OpenClaw

Meeting Notes Agent: How to Auto-Summarize Zoom Calls with OpenClaw

Let's be honest about meeting notes: nobody does them well, and everybody suffers for it.

You leave a 45-minute Zoom call, someone asks "what did we decide about the pricing tier?" two days later, and the best you can do is scroll through a Slack thread hoping someone paraphrased it. Or maybe you're paying $30/user/month for one of those AI note-takers that joins your call like an uninvited guest and spits out summaries like "Team discussed project updates and next steps." Congratulations, you just paid three hundred bucks a month for the world's least useful sentence.

I spent months dealing with this — bouncing between Otter, Fireflies, and various "just record everything" approaches — before landing on something that actually works. Building a meeting notes agent with OpenClaw changed how my entire team operates. Not incrementally. Fundamentally.

Here's the full breakdown of how to set it up, why it works better than anything else I've tried, and the specific gotchas I wish someone had told me from the start.

The Actual Problem With AI Meeting Summaries

Before we get into the build, let's talk about why most AI meeting tools fail. It's not a transcription problem. Whisper and its descendants got transcription accuracy to 95%+ years ago. The problem is everything that happens after the transcript exists.

Problem 1: Summaries strip out context. Someone says "let's pivot to B2C" and your AI note-taker writes "team discussed product direction." That's worse than useless — it actively misleads anyone who reads it later because it sounds like nothing important happened.

Problem 2: Action items are vague garbage. "Follow up on the proposal." Which proposal? Who follows up? By when? What happens if they don't? Every single AI tool I've used produces action items that require a second meeting to clarify.

Problem 3: No connection to where you actually work. Your notes live in some standalone app nobody checks. They don't become Jira tickets. They don't update your sprint board. They don't notify the right people in Slack. They're write-only memory.

Problem 4: The creep factor. Half your meeting participants get uncomfortable when "AI Notetaker Bot" joins the call. Enterprise clients? Forget it. EU-based clients? Legally fraught. The recording-everything approach is a nonstarter for a lot of real-world scenarios.

OpenClaw lets you build an agent that solves all four of these problems. And because you control the pipeline, you can customize it for exactly how your team works.

Architecture Overview

Here's what the meeting notes agent actually looks like:

Input (transcript/audio/notes)
    ↓
OpenClaw Agent
    ├── Transcription Skill (if audio input)
    ├── Context Injection (project info, team structure)
    ├── Analysis Skills
    │   ├── Decision Extraction
    │   ├── Action Item Parser
    │   ├── Sentiment/Tone Filter
    │   └── Risk/Blocker Detection
    └── Output Skills
        ├── Summary Generator
        ├── Jira/Linear Ticket Creator
        ├── Slack Notifier
        └── Knowledge Base Updater

The key insight is that this isn't one prompt doing everything. It's a pipeline of specialized skills that each handle one part of the analysis. That's why the output quality is dramatically better than throwing a transcript at a single LLM and asking for a summary.

Step 1: Setting Up Your OpenClaw Environment

First, get OpenClaw installed and configured:

pip install openclaw
openclaw init meeting-notes-agent
cd meeting-notes-agent

This scaffolds your project with the basic directory structure. You'll see a skills/ folder, a config.yaml, and an agents/ directory.

Configure your LLM provider in config.yaml:

# config.yaml
llm:
  provider: "claude"  # or "openai", "local"
  model: "claude-sonnet-4-20250514"
  api_key: "${ANTHROPIC_API_KEY}"

agent:
  name: "meeting-notes"
  description: "Transcribe, analyze, and distribute meeting notes"
  
integrations:
  slack:
    webhook_url: "${SLACK_WEBHOOK_URL}"
  linear:
    api_key: "${LINEAR_API_KEY}"
    team_id: "engineering"
  notion:
    api_key: "${NOTION_API_KEY}"
    database_id: "${NOTION_MEETINGS_DB}"

Step 2: The Context Configuration (This Is the Secret Sauce)

Here's where most people stop, and where the real magic starts. You need to give your agent context about your business — otherwise it'll produce the same generic nonsense every other tool does.

Create a context/ directory and add your project context:

# context/team_context.py
TEAM_CONTEXT = {
    "company": "Acme Analytics",
    "product": "B2B SaaS analytics platform",
    "current_sprint": {
        "name": "Q1 2026: Mobile App Launch",
        "deadline": "2026-03-15",
        "key_goals": [
            "Ship iOS/Android app to App Store",
            "Migrate 500 beta users",
            "Hit 99.5% uptime SLA"
        ]
    },
    "key_metrics": ["MRR", "churn rate", "NPS", "API uptime"],
    "team": {
        "engineering": {
            "members": ["john@acme.com", "sarah@acme.com", "mike@acme.com"],
            "lead": "sarah@acme.com"
        },
        "product": {
            "members": ["lisa@acme.com", "tom@acme.com"],
            "lead": "lisa@acme.com"
        }
    },
    "known_issues": [
        {"id": "BUG-2847", "title": "Safari iOS checkout timeout", "priority": "P0"},
        {"id": "BUG-2831", "title": "Dashboard load time > 5s on mobile", "priority": "P1"}
    ]
}

This context gets injected into every skill in the pipeline. It's the difference between "team discussed the bug" and "discussed BUG-2847 (Safari iOS checkout timeout, P0) — currently blocking mobile app release deadline of March 15."

Step 3: Building the Analysis Skills

Now let's build the actual skills. Start with the decision extractor:

# skills/decision_extractor.py
from openclaw import Skill

class DecisionExtractor(Skill):
    name = "decision_extractor"
    description = "Extract decisions with full context"
    
    prompt_template = """
    Analyze this meeting transcript and extract every decision made.
    
    For each decision, identify:
    1. WHAT was decided (specific, not vague)
    2. WHY it was decided (the trigger/reasoning)
    3. What ALTERNATIVES were considered and why rejected
    4. WHO made/approved the decision
    5. IMPACT on current sprint goals: {sprint_goals}
    6. DEADLINE or timeline mentioned
    7. RISKS or dependencies
    
    Context about this team:
    - Product: {product_description}
    - Current sprint: {current_sprint}
    - Known issues: {known_issues}
    
    IMPORTANT: Distinguish between firm decisions and casual suggestions.
    If someone says something sarcastically or hypothetically, flag it as 
    "not_a_decision" and explain what the actual underlying issue was.
    
    Transcript:
    {transcript}
    """
    
    def process(self, transcript, context):
        return self.run(
            transcript=transcript,
            sprint_goals=context["current_sprint"]["key_goals"],
            product_description=context["product"],
            current_sprint=context["current_sprint"]["name"],
            known_issues=context["known_issues"]
        )

The sarcasm detection matters more than you'd think. I once had a tool that listed "rewrite everything in Rust" as an action item because an engineer said it in frustration during a standup. OpenClaw's context-aware prompting catches this:

# What the engineer said:
# "Maybe we should just rewrite everything in Rust at this point."

# What basic AI captures:
# Decision: Rewrite codebase in Rust

# What OpenClaw captures:
{
    "classification": "sarcastic_frustration",
    "actual_issue": "Deployment pipeline failing due to Python dependency conflicts",
    "real_action_needed": "Debug pip install failures in CI/CD pipeline",
    "suggested_owner": "DevOps team"
}

Now build the action item parser — this is the one your team will actually care about:

# skills/action_item_parser.py
from openclaw import Skill

class ActionItemParser(Skill):
    name = "action_item_parser"
    description = "Extract specific, assignable action items"
    
    prompt_template = """
    Extract every action item from this transcript.
    
    Each action item MUST include:
    - SPECIFIC task (not "update docs" — WHICH docs, WHAT update)
    - ASSIGNEE (match to team members: {team_members})
    - DEADLINE (explicit or inferred from sprint: {sprint_deadline})
    - BLOCKERS (anything that must happen first)
    - QUOTED CONTEXT (the exact words that created this action)
    - PRIORITY (based on impact to: {key_metrics})
    
    If an action item is vague in the transcript, use the team context 
    to make it specific. If you cannot make it specific, flag it as 
    "needs_clarification" and suggest what question to ask.
    
    Team context: {team_context}
    Known issues: {known_issues}
    
    Transcript:
    {transcript}
    """

The difference in output quality is night and day. Instead of:

Action item: Fix the checkout bug (John)

You get:

Action item: Fix Safari iOS 16+ checkout timeout (BUG-2847)

  • Assignee: john@acme.com
  • Specific fix: Increase Stripe webhook timeout from 10s → 30s in payment-service/handlers.py:127
  • Dependency: Needs DevOps to update webhook config in production
  • Deadline: March 1 (blocks mobile app release March 15, need 2 weeks for App Store review)
  • Impact: 12% of mobile orders currently failing (~$15K MRR at risk)
  • Quoted context: "John said: I can fix the webhook handler, but I need DevOps to bump the timeout on the Stripe config first"

Step 4: Flexible Input — No Bots Required

This is the part that makes OpenClaw work for teams that can't or won't record meetings:

# agents/meeting_agent.py
from openclaw import Agent
from skills.decision_extractor import DecisionExtractor
from skills.action_item_parser import ActionItemParser
from skills.summary_generator import SummaryGenerator
from skills.ticket_creator import TicketCreator
from skills.notifier import SlackNotifier

class MeetingNotesAgent(Agent):
    skills = [
        DecisionExtractor,
        ActionItemParser,
        SummaryGenerator,
        TicketCreator,
        SlackNotifier
    ]
    
    def process(self, source, source_type="transcript", context=None):
        # Handle multiple input types
        if source_type == "audio":
            transcript = self.transcribe(source, store_audio=False)
        elif source_type == "voice_memo":
            transcript = self.transcribe(source, store_audio=False)
        elif source_type == "transcript":
            transcript = self.load_text(source)
        elif source_type == "rough_notes":
            transcript = self.load_text(source)
        
        # Run the skill pipeline
        decisions = self.run_skill("decision_extractor", transcript, context)
        actions = self.run_skill("action_item_parser", transcript, context)
        summary = self.run_skill("summary_generator", 
                                  transcript, decisions, actions, context)
        
        # Create tickets and notify
        tickets = self.run_skill("ticket_creator", actions)
        self.run_skill("notifier", summary, tickets)
        
        return {
            "summary": summary,
            "decisions": decisions,
            "actions": actions,
            "tickets_created": tickets
        }

The voice memo approach is a game-changer for client-facing calls. You hang up the Zoom, spend 90 seconds recording a voice memo with the key points, and OpenClaw does the rest:

# After a client call (no recording, no bot)
openclaw process voice_memo.m4a \
  --type voice_memo \
  --context "enterprise sales call with Dataflix" \
  --create-tickets linear \
  --notify "slack:#sales,slack:#security"

Your 90-second memo becomes structured notes, follow-up tickets, and Slack notifications — all without ever recording the client.

Step 5: Semantic Search Across All Meetings

This is the feature that compounds in value over time. Every processed meeting goes into OpenClaw's searchable knowledge base:

# Search across all historical meetings
results = agent.search(
    "Why did we choose PostgreSQL over MongoDB?",
    date_range="last_6_months",
    participants=["engineering"]
)

# Returns:
# Meeting: "Backend Architecture Review" (Oct 12)
# Decision: PostgreSQL for user analytics
# Reasoning: Complex joins needed for cohort analysis, 
#            JSONB for flexibility, 500ms→50ms query requirement
# Decided by: CTO + Lead Backend Engineer
# Related: "Database Migration Planning" (Oct 19),
#          "Q4 Infrastructure Goals" (Sep 30)

When a new engineer joins and asks "why do we have two databases?" you don't need to schedule a meeting to answer that question. You search, find the decision with full context, and share a link. This alone saved my team probably three to four hours a week of "re-explain past decisions" meetings.

Step 6: The Integration Layer

The output skills handle pushing results where they actually belong:

# skills/ticket_creator.py
from openclaw import Skill
from openclaw.integrations import LinearClient

class TicketCreator(Skill):
    name = "ticket_creator"
    
    def process(self, actions):
        linear = LinearClient()
        created_tickets = []
        
        for action in actions:
            if action["priority"] in ["P0", "P1"]:
                ticket = linear.create_issue(
                    title=action["specific_task"],
                    description=self.format_description(action),
                    assignee=action["assignee"],
                    priority=action["priority"],
                    project=action.get("project", "Backlog"),
                    labels=action.get("labels", []),
                    due_date=action.get("deadline")
                )
                created_tickets.append(ticket)
        
        return created_tickets
    
    def format_description(self, action):
        return f"""
## Context (from meeting)
{action['quoted_context']}

## Specific Task
{action['specific_task']}

## Blockers
{', '.join(action.get('blockers', ['None identified']))}

## Impact
{action.get('impact', 'Not specified')}
        """

After every meeting, P0 and P1 items automatically become Linear tickets with full context. No copy-paste. No forgetting. No "wait, who was supposed to do that?"

The Easy Way: Felix's OpenClaw Starter Pack

Now, everything I've described above works. I've been running it for months and it's excellent. But setting up the skills, the context injection, the integration layer, the search indexing — it took me about two full days of tinkering to get right.

If you don't want to build all of this from scratch, Felix's OpenClaw Starter Pack on Claw Mart includes a pre-built meeting notes workflow that handles most of what I described above. It's $29 and includes pre-configured skills for decision extraction, action item parsing, and the integration hooks for Linear, Jira, Slack, and Notion. The context-aware prompting is already tuned, the sarcasm detection works out of the box, and the search indexing is set up.

I actually discovered it after building my own version and was mildly annoyed at how much time I could have saved. The skills in that pack are well-structured enough that you can customize them without starting from zero — which is the ideal starting point. Buy it, customize the context config for your team, and you're running in an afternoon instead of a weekend.

What the Output Actually Looks Like

Here's a real (anonymized) output from my team's weekly engineering standup:

⚡ P0 ISSUES (Blocking Release)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. Safari iOS 16+ checkout timeout (BUG-2847)
   Impact: 12% mobile orders failing = ~$15K MRR at risk
   Root cause: Stripe webhook timeout (10s limit)
   Fix: payment-service/handlers.py:127 → timeout 10s→30s
   Owner: John | Blocked by: DevOps webhook config update
   Deadline: March 1 (hard — blocks App Store submission)
   ✅ Linear ticket PROD-482 created → assigned to John

🔄 IN PROGRESS
━━━━━━━━━━━━━━
2. API rate limiting overhaul (60% complete)
   Current: 100 req/min (enterprise clients hitting limits)
   New: Tiered — Standard: 100, Pro: 1000, Enterprise: 10,000
   Owner: Sarah | Blocked by: final tier pricing from Product
   Docs: docs/api/rate-limits.md needs update before deploy

📋 DECISIONS
━━━━━━━━━━━━
3. PostgreSQL > MongoDB for analytics
   Why: Cohort analysis queries need complex joins
   Migration deadline: Q2 start
   Owner: Mike (pgloader for migration, ~50M records)
   Risk: Data validation on legacy records

🚫 NOT DECISIONS (flagged for clarity)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- "Maybe we should just rewrite in Rust" → SARCASM
  Actual issue: Python dependency conflicts in CI/CD
  Real action: Debug pip install failures (DevOps)

🗓️ Next: March 1 — Mobile release go/no-go

Compare that to "Team discussed project updates and next steps" and tell me which one actually replaces having to attend the meeting.

Cost Comparison

Let's talk real numbers:

SolutionMonthly Cost (15-person team)
Otter.ai Business$450/month
Fireflies.ai Business$285/month
Fathom Pro$465/month
OpenClaw (self-hosted)~$30/month

The $30 breaks down to about $20 for a basic server and roughly $0.01 per hour of processed audio in LLM costs. For a team doing 20 hours of meetings per week, that's under $10/month in API calls.

Even if you add the one-time $29 for Felix's Starter Pack, you're still paying less than one month of any commercial alternative — and you own the infrastructure.

Getting Started Today

If you want to spin this up quickly, here's the path of least resistance:

  1. Install OpenClaw: pip install openclaw
  2. Grab Felix's OpenClaw Starter Pack for the pre-built meeting skills
  3. Configure your team context in context/team_context.py (15 minutes)
  4. Set up your integrations (Slack webhook + Linear/Jira API key)
  5. Process your first meeting: openclaw process transcript.txt --context "weekly standup"

The first time you see the output — specific decisions, assignable action items, auto-created tickets, relevant Slack notifications — you'll wonder why you ever tolerated "team discussed next steps."

Meeting notes should be more useful than attending the meeting. If they're not, your tool failed. OpenClaw doesn't fail.

Claw Mart Daily

Get one AI agent tip every morning

Free daily tips to make your OpenClaw agent smarter. No spam, unsubscribe anytime.

More From the Blog