MCP Meeting Notes to Action Items Workflow
Extract action items from transcripts, verify referenced facts via search, and push tasks to project management tools via MCP.
MCP meeting notes workflows extract action items from transcripts, verify referenced facts via web search, and push tasks to project management tools -- all through Claude with MCP servers. The workflow turns a raw meeting transcript into verified action items with deadlines, owners, and current context in under 60 seconds.
The workflow architecture
Three MCP servers work together: filesystem (reads transcript files), web search (verifies claims and enriches context), and a project management integration (creates tasks). Claude orchestrates the flow by reading the transcript, identifying action items, and using tools as needed.
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-filesystem", "/Users/me/meetings"]
},
"search": {
"command": "npx",
"args": ["-y", "@anthropic/mcp-search"],
"env": { "SCAVIO_API_KEY": "sk-..." }
}
}
}Action item extraction
import os, requests, json, re
SCAVIO_KEY = os.environ["SCAVIO_API_KEY"]
HEADERS = {"x-api-key": SCAVIO_KEY}
def extract_action_items(transcript: str) -> list:
"""Extract action items from meeting transcript."""
# Pattern matching for common action item signals
action_signals = [
r"(?:will|going to|needs to|should|action item:?)s+(.+?)(?:.|$)",
r"(?:follow up|follow-up) (?:on|with)s+(.+?)(?:.|$)",
r"(?:deadline|due|by)s+(.+?)(?:.|$)",
r"(?:assigned to|owner:?)s+(w+.+?)(?:.|$)",
]
items = []
for line in transcript.split("\n"):
line = line.strip()
if not line:
continue
for pattern in action_signals:
matches = re.findall(pattern, line, re.IGNORECASE)
for match in matches:
items.append({
"raw_text": match.strip(),
"source_line": line[:100],
"needs_verification": False,
})
return items
# Example transcript
transcript = """
Sarah: We should switch from SerpAPI to something cheaper.
John will research alternatives by Friday.
Sarah: The new API needs to support Google Maps data.
Mike: Action item: test Scavio API for Maps coverage.
John: Follow up with the pricing team about the budget.
Sarah: Deadline for migration plan is May 20.
"""
items = extract_action_items(transcript)
for item in items:
print(f" - {item['raw_text']}")Verifying claims with search
def verify_and_enrich(items: list) -> list:
"""Verify referenced facts and add context."""
verification_keywords = ["pricing", "cost", "alternative", "api",
"tool", "platform", "version"]
for item in items:
text = item["raw_text"].lower()
if any(kw in text for kw in verification_keywords):
item["needs_verification"] = True
# Search for current information
resp = requests.post(
"https://api.scavio.dev/api/v1/search",
headers=HEADERS,
json={"query": item["raw_text"], "num_results": 3},
)
results = resp.json().get("organic_results", [])
if results:
item["verified_context"] = results[0]["snippet"]
item["reference_url"] = results[0]["link"]
return items
enriched_items = verify_and_enrich(items)
for item in enriched_items:
print(f"Task: {item['raw_text']}")
if item.get("verified_context"):
print(f" Context: {item['verified_context'][:80]}")
print(f" Ref: {item.get('reference_url', '')}")Structuring for task management
from datetime import datetime, timedelta
def structure_tasks(items: list) -> list:
"""Convert raw action items into structured tasks."""
tasks = []
for item in items:
task = {
"title": item["raw_text"][:80],
"description": item["source_line"],
"status": "todo",
"created": datetime.utcnow().isoformat(),
}
# Extract owner if mentioned
owner_match = re.search(r"(w+)s+(?:will|should|needs)", item["source_line"])
if owner_match:
task["assignee"] = owner_match.group(1)
# Extract deadline if mentioned
date_match = re.search(r"(?:by|deadline|due)s+([ws]+d+)", item["source_line"])
if date_match:
task["due_date"] = date_match.group(1).strip()
else:
# Default: 1 week from now
task["due_date"] = (datetime.utcnow() + timedelta(days=7)).strftime("%Y-%m-%d")
# Add verification context
if item.get("verified_context"):
task["context"] = item["verified_context"]
task["reference"] = item.get("reference_url", "")
tasks.append(task)
return tasks
tasks = structure_tasks(enriched_items)
print(json.dumps(tasks[:2], indent=2))Cost of the workflow
- Transcript processing: 0 credits (local computation)
- Search verification: 1-3 credits per meeting ($0.005-0.015)
- 10 meetings/week: $0.05-0.15/week in search costs
- Monthly total: under $1 for search verification
- Time saved: 15-30 minutes per meeting on manual action item extraction
Integration with project management
The structured tasks output as JSON that maps directly to Linear, Asana, or Notion API payloads. Add one more MCP server for your project management tool and Claude can push tasks directly after extracting and verifying them. No copy-paste, no manual entry.
Key takeaway
Meeting notes to action items is a three-step MCP workflow: read transcript, verify references via search, push structured tasks. The search step costs pennies but prevents the most common post-meeting failure: action items based on wrong assumptions about pricing, tooling, or timelines.