Skip to content

Add Fireflies.ai skill for querying meeting transcripts#41

Merged
TechNickAI merged 3 commits intomainfrom
feat/fireflies-skill
Jan 30, 2026
Merged

Add Fireflies.ai skill for querying meeting transcripts#41
TechNickAI merged 3 commits intomainfrom
feat/fireflies-skill

Conversation

@TechNickAI
Copy link
Owner

Summary

Adds a new skill for querying Fireflies.ai meeting transcripts - recorded meetings with AI-generated summaries, action items, and searchable conversation history.

Features:

  • Python CLI tool using uv inline script dependencies for zero-setup execution
  • Query recent, today, or date-specific meetings
  • Search transcripts by keyword
  • Get full transcript with speaker attribution
  • Smart .env file loading from multiple locations (~/.env, ~/.clawdbot/clawdbot.json, ./.env, ./.env.local)
  • Beautiful rich terminal output with markdown formatting
  • Helpful setup instructions when API key is missing

Test plan

  • Script executes with help command
  • Setup instructions display correctly when API key missing
  • Script uses modern Python (3.11+, uv inline deps)
  • Test with actual FIREFLIES_API_KEY

🤖 Generated with Claude Code

Python CLI tool using uv inline script dependencies for zero-setup execution.
Features:
- Query recent, today, or date-specific meetings
- Search transcripts by keyword
- Get full transcript with speaker attribution
- Smart .env file loading from multiple locations
- Beautiful rich terminal output
- Helpful setup instructions when API key missing

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

Points LLMs to Context7 for GraphQL API lookups with full schema docs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Jan 30, 2026

PR Review: Fireflies.ai Skill

Overview

This PR adds a well-crafted skill for querying Fireflies.ai meeting transcripts. The implementation is clean, functional, and follows modern Python best practices.

✅ Strengths

Code Quality

  • Modern Python patterns: Uses Python 3.11+ features (union types with |, match/case statements)
  • Zero-setup execution: Clever use of uv run --script with inline PEP 723 dependencies
  • Excellent error handling: Clear user feedback with helpful setup instructions when API key is missing
  • Beautiful output: Rich terminal formatting with markdown rendering
  • Smart config loading: Multi-location .env file search with proper priority order

Documentation

  • Clear SKILL.md: Good use of frontmatter with triggers array
  • Helpful examples: Commands section shows all main use cases
  • User-friendly: Setup instructions are comprehensive and actionable

Security & Best Practices

  • API key handling: Proper environment variable usage
  • No hardcoded secrets: Configuration properly externalized
  • Appropriate timeout: 30s timeout prevents hanging requests
  • Error messages: Don't leak sensitive information

🔍 Issues & Recommendations

1. Input Validation Missing (Medium Priority)

The cmd_date() function accepts arbitrary date strings without validation:

def cmd_date(date_str: str) -> None:
    """Get meetings for a specific date."""
    from_date = f"{date_str}T00:00:00.000Z"
    to_date = f"{date_str}T23:59:59.999Z"

Issue: Invalid dates like "2026-99-99" will be passed to the API. While the API may reject it, local validation provides better UX.

Recommendation: Add date validation:

from datetime import datetime

def cmd_date(date_str: str) -> None:
    """Get meetings for a specific date."""
    try:
        datetime.strptime(date_str, "%Y-%m-%d")
    except ValueError:
        error("Invalid date format. Use YYYY-MM-DD (e.g., 2026-01-28)")
        sys.exit(1)
    from_date = f"{date_str}T00:00:00.000Z"
    to_date = f"{date_str}T23:59:59.999Z"
    # ...

2. Integer Overflow Risk (Low Priority)

In cmd_recent() at plugins/core/skills/fireflies/scripts/fireflies:396:

case "recent":
    limit = int(args[1]) if len(args) > 1 else 5
    cmd_recent(limit)

Issue: No validation that the integer is reasonable. User could pass fireflies recent 99999999999 which could:

  • Cause memory issues
  • Trigger API rate limits
  • Result in confusing error messages

Recommendation: Add bounds checking:

case "recent":
    limit = int(args[1]) if len(args) > 1 else 5
    if limit < 1 or limit > 100:
        error("Limit must be between 1 and 100")
        sys.exit(1)
    cmd_recent(limit)

3. Error Handling for Invalid Integer (Low Priority)

Same location - no try/except for int() conversion:

limit = int(args[1]) if len(args) > 1 else 5

Issue: fireflies recent abc will crash with an unhelpful ValueError: invalid literal for int() traceback.

Recommendation:

try:
    limit = int(args[1]) if len(args) > 1 else 5
except ValueError:
    error('Usage: fireflies recent [N] - N must be a number')
    sys.exit(1)

4. GraphQL Error Handling Could Be More Granular (Low Priority)

Currently all GraphQL errors are caught broadly at plugins/core/skills/fireflies/scripts/fireflies:177-186. API might return errors in the response body even with 200 status.

Recommendation: Consider checking for GraphQL errors in the response:

result = response.json()
if "errors" in result:
    error(f"GraphQL error: {result['errors']}")
    return None
return result

5. Documentation: Missing Version Note (Low Priority)

The SKILL.md frontmatter has version: 1.0.0 but doesn't document what changes would trigger version bumps. Consider adding a comment or version policy for future maintainers.

6. Test Coverage (Note)

The PR description mentions:

  • Script executes with help command
  • Setup instructions display correctly when API key missing
  • Script uses modern Python (3.11+, uv inline deps)
  • Test with actual FIREFLIES_API_KEY

The last item is still unchecked. While this is understandable for a PR, it would be good to validate with a real API key before merging.

🎯 Performance Considerations

  • Pagination: For large result sets, consider adding pagination support or warning users about large queries
  • Caching: Future enhancement could cache recent queries for faster repeated access
  • Rate limiting: Consider documenting API rate limits in SKILL.md

🔒 Security Considerations

Overall: Good security posture

  • ✅ API keys properly externalized
  • ✅ No sensitive data logged
  • ✅ HTTPS enforced for API calls
  • ✅ Bearer token authentication used correctly

📝 Code Style & Conventions

Matches repository patterns well:

  • ✅ Follows SKILL.md frontmatter conventions from CLAUDE.md
  • ✅ Uses # prettier-ignore for long descriptions
  • ✅ Triggers array matches expected format
  • ✅ Category (research) is appropriate

Minor suggestion: The description in SKILL.md:4 could be slightly more concise:

# Current:
description: "Use when finding meeting transcripts, searching Fireflies recordings, getting action items from calls, or answering 'what was discussed in the meeting' questions"

# Suggestion:
description: "Use when querying meeting transcripts, searching Fireflies recordings, extracting action items, or answering 'what was discussed' questions"

🎨 UX Considerations

Excellent UX overall:

  • Clear help text
  • Beautiful formatted output
  • Helpful error messages
  • Multi-location config search

Enhancement idea: Consider adding a progress indicator for slow API calls, though 30s timeout is reasonable for most queries.

🧪 Testing Recommendations

Before merging:

  1. Test with actual FIREFLIES_API_KEY (as noted in PR description)
  2. Test error scenarios: invalid dates, malformed API responses, network failures
  3. Verify behavior with meetings that have no summaries/action items
  4. Test with various date formats to ensure robustness

Verdict

Recommendation: Approve with minor changes

This is a solid implementation that adds valuable functionality. The issues identified are minor and easy to fix:

Must fix before merge:

  • Add input validation for date format and integer ranges

Nice to have:

  • Add GraphQL error checking in response body
  • Test with actual API key

Overall score: 8.5/10 - Well-structured, modern Python with good UX. Minor input validation improvements would make this production-ready.

Great work on the zero-dependency setup with uv and the helpful onboarding experience! 🎉

@claude
Copy link

claude bot commented Jan 30, 2026

Code Review: Fireflies.ai Skill

Overall, this is a well-crafted addition with clean code, good documentation, and thoughtful user experience. Here's my detailed feedback:

✅ Strengths

Excellent Documentation:

  • SKILL.md follows the project conventions perfectly with # prettier-ignore for the description
  • Clear triggers array with natural language phrases users would actually say
  • Well-structured sections (objective, when-to-use, prerequisites, commands)
  • Good examples that demonstrate the API clearly

Modern Python Implementation:

  • Uses uv inline script dependencies - zero-setup execution aligns with project philosophy
  • Python 3.11+ features (match statements, union type hints with |)
  • Clean separation of concerns with focused functions
  • Proper error handling with user-friendly messages

Great UX:

  • Helpful setup instructions when API key is missing (plugins/core/skills/fireflies/scripts/fireflies:54-86)
  • Multiple .env file locations checked in priority order (plugins/core/skills/fireflies/scripts/fireflies:28-33)
  • Rich terminal output with markdown formatting
  • Graceful fallbacks for missing data (or "Untitled", or "unknown")

🐛 Potential Issues

1. Input Validation Missing (Medium Priority)

The script doesn't validate user input, which could cause runtime errors:

  • cmd_recent() at line 396: int(args[1]) could raise ValueError for non-integer input

    # Current code:
    limit = int(args[1]) if len(args) > 1 else 5
    
    # Should be:
    try:
        limit = int(args[1]) if len(args) > 1 else 5
    except ValueError:
        error(f"Invalid limit: {args[1]}. Must be a number.")
        sys.exit(1)
  • cmd_date() at line 307: No validation that date_str is valid ISO format

    # Should validate date format:
    try:
        datetime.fromisoformat(date_str)
    except ValueError:
        error(f"Invalid date: {date_str}. Use YYYY-MM-DD format.")
        sys.exit(1)

2. Silent JSON Parsing Failure (Low Priority)

At line 42-47, JSON parsing errors are caught but continue silently. While this works for loading config files, it might hide configuration issues. Consider logging a warning:

except (json.JSONDecodeError, KeyError) as e:
    # Silent failure - consider logging for debugging
    console.print(f"[dim]Warning: Could not parse {env_path}: {e}[/dim]", file=sys.stderr)
    pass

3. Timezone Hardcoded to UTC (Low Priority)

The cmd_today() function at line 292 uses timezone.utc which might not match the user's local timezone. Consider using local timezone or documenting that "today" means "today UTC":

# Current uses UTC:
today = datetime.now(timezone.utc).replace(...)

# Consider local time:
today = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)

Or document in SKILL.md that dates are in UTC.

4. GraphQL Error Response Not Checked (Medium Priority)

The graphql() function at line 159-186 returns the full JSON response but doesn't check if it contains GraphQL errors. The API might return 200 OK with errors in the payload:

# After line 176:
result = response.json()
if "errors" in result:
    error(f"GraphQL errors: {result['errors']}")
    return None
return result

🔒 Security Considerations

API Key Exposure:

  • ✅ API key is loaded from env files (not hardcoded)
  • ✅ No API key in error messages or logs
  • ⚠️ Consider warning if API key is found in .env.local but repo has a .gitignore that doesn't ignore it

⚡ Performance Considerations

  • ✅ 30-second timeout is reasonable for API calls
  • ✅ Uses httpx with proper connection management
  • ℹ️ Large transcripts could be memory-intensive (line 240-243 loads all sentences into memory). This is fine for typical meetings but could be optimized if needed.

🧪 Test Coverage

Test Plan Status:

  • ✅ Help command works
  • ✅ Setup instructions display
  • ✅ Modern Python with uv
  • ❌ Not tested with actual API key

Recommendations:

  1. Add example of successful API response in a comment or test fixture
  2. Consider adding a --dry-run flag for testing without API calls
  3. Mock tests could verify command routing and error handling

📋 Best Practices

Follows Project Conventions:

  • ✅ SKILL.md format matches other skills (compared with youtube-transcript-analyzer)
  • ✅ Triggers array for natural language matching
  • ✅ Category correctly set to "research"
  • ✅ Version 1.0.0 appropriate for new skill

Python Style:

  • ✅ Type hints used consistently
  • ✅ Docstrings for all functions
  • ✅ Match statement for command routing (modern Python)
  • ⚠️ Consider adding __all__ export list if this becomes a module

🎯 Suggestions for Enhancement (Optional)

  1. Add color parameter - Let users customize skill color when it's added to marketplace
  2. Cache recent queries - Store last query results locally to avoid repeat API calls
  3. Export formats - Add options to export transcripts to markdown/JSON files
  4. Pagination - For large result sets, add --offset or --page parameters
  5. Fuzzy date matching - Support "yesterday", "last week" instead of just ISO dates

📝 Documentation Updates Needed

  1. In SKILL.md line 46, update the example date from 2026-01-28 to use a template like YYYY-MM-DD
  2. Consider adding a "Common Errors" section to SKILL.md
  3. Document that dates/times use UTC timezone

Recommendation: Approve with minor fixes

The critical issues are input validation and GraphQL error checking. These are straightforward fixes that would make the script more robust. Everything else is excellent quality.

Great work on the user experience - the setup instructions and multi-location .env loading are particularly thoughtful touches! 🔥

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 87f6b1ab25

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 41 to 45
try:
config = json.loads(env_path.read_text())
env_vars = config.get("env", {})
if "FIREFLIES_API_KEY" in env_vars:
return env_vars["FIREFLIES_API_KEY"]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow later env sources to override clawdbot.json

The loader returns immediately when clawdbot.json contains FIREFLIES_API_KEY, so the later locations in ENV_LOCATIONS (e.g., project .env / .env.local) never get a chance to override that value. This contradicts the stated priority order and will pick the wrong key in the common case where a user keeps a global clawdbot config but needs a project-specific Fireflies key. Consider deferring the return until after scanning all locations, or recording the value and allowing later sources to overwrite it.

Useful? React with 👍 / 👎.

- Fix env loading priority (Codex P2) - don't return early from JSON config
- Add GraphQL error checking for better API error messages
- Add date format validation with helpful error message
- Add integer validation for limit parameter
- Add rate limit error handling
- Add JSON parse warning for malformed config files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Jan 30, 2026

PR Review: Add Fireflies.ai skill for querying meeting transcripts

This is a well-crafted PR that adds a valuable skill to the project. The code demonstrates excellent Python style and follows modern patterns. Below are my findings organized by category.


✅ Strengths

Excellent Code Quality

  • Modern Python 3.11+ patterns throughout (union types, match/case statements)
  • Full PEP 8 compliance with consistent naming conventions
  • Comprehensive docstrings and type hints
  • Clean code organization with clear separation of concerns
  • Uses uv inline script dependencies for zero-setup execution

Good Security Practices

  • No SQL/command injection vulnerabilities
  • Parameterized GraphQL queries prevent injection
  • Input validation for dates and integers
  • HTTPS hardcoded for API communication

Strong SKILL.md Documentation

  • Follows project frontmatter conventions (prettier-ignore, "Use when..." format)
  • Goal-focused objective section
  • Clean XML tag structure for LLM parsing
  • Token-efficient with no wasted words

🔴 Security Issues

1. Sensitive Data Exposure - API Error Logging (Medium Severity)

Location: plugins/core/skills/fireflies/scripts/fireflies:197

Error messages include full API response text which could leak sensitive information:

error(f"API error: {e.response.status_code} - {e.response.text}")

Recommendation: Sanitize error messages:

error(f"API error: {e.response.status_code}")
# Don't include e.response.text

2. Setup Instructions Missing Security Warnings (Low Severity)

Location: plugins/core/skills/fireflies/scripts/fireflies:76-83

The setup instructions teach users to store API keys in plaintext without warning about file permissions or .gitignore.

Recommendation: Add security notes:

[yellow]Security Note: Never commit .env files to version control. Ensure .env is in .gitignore.[/yellow]

Option B: Add to ~/.env (recommended for persistent use)
[dim]echo "FIREFLIES_API_KEY=your-api-key-here" >> ~/.env
chmod 600 ~/.env  # Restrict file permissions[/dim]

🟡 Logic Bugs

1. GraphQL Error Array Indexing Without Check (Medium Severity)

Location: plugins/core/skills/fireflies/scripts/fireflies:187

Code assumes errors array has elements:

if "errors" in result:
    error(f"GraphQL error: {result['errors'][0].get('message', 'Unknown error')}")

Fix:

if "errors" in result:
    if result['errors']:
        error(f"GraphQL error: {result['errors'][0].get('message', 'Unknown error')}")
    else:
        error("GraphQL error: Unknown error (empty errors array)")
    return None

2. Fragile Timezone String Manipulation (Medium Severity)

Location: plugins/core/skills/fireflies/scripts/fireflies:312-313

Using .replace("+00:00", ".000Z") is brittle and won't work for other timezones:

"fromDate": today.isoformat().replace("+00:00", ".000Z"),

Fix:

"fromDate": today.strftime("%Y-%m-%dT%H:%M:%S.000Z"),

3. Missing Validation for Positive Limit (Low Severity)

Location: plugins/core/skills/fireflies/scripts/fireflies:419-421

cmd_recent doesn't validate positive numbers - allows fireflies recent 0 or fireflies recent -5.

Fix:

try:
    limit = int(args[1]) if len(args) > 1 else 5
    if limit <= 0:
        error("Limit must be a positive number")
        sys.exit(1)
except ValueError:
    error(f"Invalid limit: '{args[1]}'. Must be a number.")
    sys.exit(1)

📝 SKILL.md Improvements

1. Expand Trigger Phrases

The triggers array is good but missing natural user language:

triggers:
  - "fireflies"
  - "meeting transcript"
  - "meeting notes"
  - "what was discussed"
  - "action items"
  - "zoom call"
  - "teams meeting"
  - "google meet"
  # Add these:
  - "call notes"
  - "what happened in the meeting"
  - "meeting summary"
  - "recording"
  - "standup"
  - "sync"
  - "retro"

2. Remove Redundancy in <when-to-use>

Lines 23-30 largely restate the frontmatter description. Consider keeping only the "Clear triggers" examples or reframing to add new information.

3. Add Context7 Fallback

The <llm-api-reference> section assumes Context7 is available without providing fallback:

<llm-api-reference>
If you need to look up API details, use Context7 if available:
...

If Context7 is not configured, refer to https://docs.fireflies.ai directly.
</llm-api-reference>

4. Add Common Pitfalls Section

Both research and youtube-transcript-analyzer skills have error guidance. Add:

<common-pitfalls>
- This skill only works for meetings recorded by Fireflies (not arbitrary audio files)
- If no API key is found, the script will show setup instructions
- Empty search results indicate no transcripts match the query
</common-pitfalls>

🧪 Test Coverage

Missing: No test files found for this skill. Consider adding:

  • Unit tests for date parsing and validation
  • Mock tests for API interactions
  • Integration tests for CLI commands

📊 Summary

Category Status
Code Quality ✅ Excellent
Security 🟡 2 issues (1 medium, 1 low)
Logic 🟡 3 bugs (2 medium, 1 low)
Documentation ✅ Good with minor improvements
Test Coverage 🔴 Missing
Style/Conventions ✅ Excellent

Recommendation

This PR adds valuable functionality with well-written code. The issues found are fixable and mostly low-risk:

Must fix before merge:

  1. GraphQL error array indexing bug (could cause crashes)
  2. Timezone string manipulation bug (causes incorrect API queries)

Should fix before merge:
3. Sanitize error messages to prevent data leakage
4. Validate positive limit in cmd_recent
5. Add security warnings to setup instructions

Nice to have:
6. Expand SKILL.md trigger phrases
7. Add common-pitfalls section
8. Add test coverage

Once the "must fix" items are addressed, this is ready to merge. Great work on the implementation!

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

else:
load_dotenv(env_path, override=True)

return os.environ.get("FIREFLIES_API_KEY")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Environment variable priority inverted from documented behavior

Medium Severity

The load_api_key docstring claims environment variables have "highest priority" (item 5), but the implementation using load_dotenv(env_path, override=True) causes .env files to overwrite pre-existing environment variables. If a user explicitly sets export FIREFLIES_API_KEY=xxx and ~/.env contains a different value, the .env value wins instead. The actual priority is reversed from what's documented.

Fix in Cursor Fix in Web

variables = args[2] if len(args) > 2 else "{}"
cmd_raw(args[1], variables)
case "help" | "-h" | "--help" | _:
show_help()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unknown commands silently show help without error message

Low Severity

The match statement uses _ as a catch-all pattern combined with help commands, so any unrecognized command like fireflies tyop silently displays help instead of showing an "unknown command" error. Users won't know their command wasn't recognized and may be confused why their intended action didn't execute.

Fix in Cursor Fix in Web

return None
except httpx.RequestError as e:
error(f"Request failed: {e}")
return None
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing JSON decode error handling causes unhandled crash

Medium Severity

The graphql() function calls response.json() without catching json.JSONDecodeError. While httpx.HTTPStatusError and httpx.RequestError are handled, if the API returns a non-JSON response (HTML error page, truncated response, or malformed JSON) with HTTP 200, the script crashes with an unhandled exception. Other JSON parsing in this file (lines 50-54, 368-369) properly catches this error, making this an oversight.

Fix in Cursor Fix in Web

@TechNickAI TechNickAI merged commit 95ad521 into main Jan 30, 2026
6 checks passed
@TechNickAI TechNickAI deleted the feat/fireflies-skill branch January 30, 2026 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant