← Back to Skills Marketplace
byungkyu

Granola

by byungkyu · GitHub ↗ · v1.0.1
cross-platform ✓ Security Clean
467
Downloads
0
Stars
0
Active Installs
2
Versions
Install in OpenClaw
/install granola-api
Description
Granola MCP integration with managed authentication. Use this skill when users want to search meeting content, get meeting summaries, find action items, or r...
README (SKILL.md)

Granola MCP

Access Granola via MCP (Model Context Protocol) with managed authentication.

Quick Start

python \x3C\x3C'EOF'
import urllib.request, os, json
data = json.dumps({'query': 'What action items came from my last meeting?'}).encode()
req = urllib.request.Request('https://gateway.maton.ai/granola/query_granola_meetings', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Base URL

https://gateway.maton.ai/granola/{tool-name}

Replace {tool-name} with the MCP tool name (e.g., query_granola_meetings). The gateway proxies requests to mcp.granola.ai and automatically injects your credentials.

Authentication

All requests require the Maton API key:

Authorization: Bearer $MATON_API_KEY

Environment Variable: Set your API key as MATON_API_KEY:

export MATON_API_KEY="YOUR_API_KEY"

Getting Your API Key

  1. Sign in or create an account at maton.ai
  2. Go to maton.ai/settings
  3. Copy your API key

Connection Management

Manage your Granola MCP connections at https://ctrl.maton.ai.

List Connections

python \x3C\x3C'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=granola&method=MCP&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Create Connection

python \x3C\x3C'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'granola', 'method': 'MCP'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Get Connection

python \x3C\x3C'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Response:

{
  "connection": {
    "connection_id": "8a413c45-6427-45d9-b69d-8118ce62ffce",
    "status": "PENDING",
    "creation_time": "2026-02-24T11:34:46.204677Z",
    "url": "https://connect.maton.ai/?session_token=...",
    "app": "granola",
    "method": "MCP",
    "metadata": {}
  }
}

Open the returned url in a browser to complete OAuth authorization.

Delete Connection

python \x3C\x3C'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Specifying Connection

If you have multiple Granola connections, you must specify which MCP connection to use with the Maton-Connection header:

python \x3C\x3C'EOF'
import urllib.request, os, json
data = json.dumps({'query': 'What were my action items?'}).encode()
req = urllib.request.Request('https://gateway.maton.ai/granola/query_granola_meetings', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('Maton-Connection', '8a413c45-6427-45d9-b69d-8118ce62ffce')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

IMPORTANT: If omitted, the gateway uses the default (oldest) active connection, which may fail if it's not an MCP connection.

MCP Reference

All MCP tools use POST method:

Tool Description Schema
query_granola_meetings Chat with meeting notes using natural language schema
list_meetings List meetings with metadata and attendees schema
get_meetings Retrieve detailed content for specific meetings schema
get_meeting_transcript Get raw transcript (paid tiers only) schema

Query Meetings

Chat with your meeting notes using natural language queries:

POST /granola/query_granola_meetings
Content-Type: application/json

{
  "query": "What action items came from my meetings this week?"
}

Response:

{
  "content": [
    {
      "type": "text",
      "text": "You had 2 recent meetings:\
**Feb 4, 2026 at 7:30 PM** - \"Team sync\" [[0]](https://notes.granola.ai/d/abc123)\
- Action item: Review Q1 roadmap\
- Action item: Schedule follow-up with engineering\
**Jan 27, 2026 at 1:04 AM** - \"Finance integration\" [[1]](https://notes.granola.ai/d/def456)\
- Discussed workflow automation platforms\
- Action item: Evaluate n8n vs Zapier"
    }
  ],
  "isError": false
}

Use cases:

  • "What action items were assigned to me?"
  • "Summarize my meetings from last week"
  • "What did we discuss about the product launch?"
  • "Find all mentions of budget in my meetings"

List Meetings

List your meetings with metadata including IDs, titles, dates, and attendees:

POST /granola/list_meetings
Content-Type: application/json

{}

Response:

{
  "content": [
    {
      "type": "text",
      "text": "\x3Cmeetings_data from=\"Jan 27, 2026\" to=\"Feb 4, 2026\" count=\"2\">\
\x3Cmeeting id=\"0dba4400-50f1-4262-9ac7-89cd27b79371\" title=\"Team sync\" date=\"Feb 4, 2026 7:30 PM\">\
    \x3Cknown_participants>\
    John Doe (note creator) from Acme \[email protected]>\
    Jane Smith from Acme \[email protected]>\
    \x3C/known_participants>\
  \x3C/meeting>\
\
\x3Cmeeting id=\"4ebc086f-ba8d-49e8-8cd1-ed81ac8f2e3b\" title=\"Finance integration\" date=\"Jan 27, 2026 1:04 AM\">\
    \x3Cknown_participants>\
    John Doe (note creator) from Acme \[email protected]>\
    \x3C/known_participants>\
  \x3C/meeting>\
\x3C/meetings_data>"
    }
  ],
  "isError": false
}

Response fields in XML format:

  • meetings_data: Container with from, to date range and count
  • meeting: Individual meeting with id, title, and date attributes
  • known_participants: List of attendees with name, role, company, and email

Get Meetings

Retrieve detailed content for specific meetings by ID:

POST /granola/get_meetings
Content-Type: application/json

{
  "meeting_ids": ["0dba4400-50f1-4262-9ac7-89cd27b79371"]
}

Response:

{
  "content": [
    {
      "type": "text",
      "text": "\x3Cmeetings_data from=\"Feb 4, 2026\" to=\"Feb 4, 2026\" count=\"1\">\
\x3Cmeeting id=\"0dba4400-50f1-4262-9ac7-89cd27b79371\" title=\"Team sync\" date=\"Feb 4, 2026 7:30 PM\">\
  \x3Cknown_participants>\
  John Doe (note creator) from Acme \[email protected]>\
  \x3C/known_participants>\
  \
  \x3Csummary>\
## Key Decisions\
- Approved Q1 roadmap\
- Budget increased by 15%\
\
## Action Items\
- @john: Review design specs by Friday\
- @jane: Schedule engineering sync\
\x3C/summary>\
\x3C/meeting>\
\x3C/meetings_data>"
    }
  ],
  "isError": false
}

Response includes:

  • Meeting metadata (id, title, date, participants)
  • summary: AI-generated meeting summary with key decisions and action items
  • Enhanced notes and private notes (when available)

Get Meeting Transcript

Retrieve the raw transcript for a specific meeting (paid tiers only):

POST /granola/get_meeting_transcript
Content-Type: application/json

{
  "meeting_id": "0dba4400-50f1-4262-9ac7-89cd27b79371"
}

Response (paid tier):

{
  "content": [
    {
      "type": "text",
      "text": "\x3Ctranscript meeting_id=\"0dba4400-50f1-4262-9ac7-89cd27b79371\">\
[00:00:15] John: Let's get started with the Q1 planning...\
[00:01:23] Jane: I've prepared the budget breakdown...\
[00:03:45] John: That looks good. What about the timeline?\
\x3C/transcript>"
    }
  ],
  "isError": false
}

Response (free tier):

{
  "content": [
    {
      "type": "text",
      "text": "Transcripts are only available to paid Granola tiers"
    }
  ],
  "isError": true
}

Code Examples

JavaScript

const response = await fetch('https://gateway.maton.ai/granola/query_granola_meetings', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${process.env.MATON_API_KEY}`
  },
  body: JSON.stringify({
    query: 'What were the action items from my last meeting?'
  })
});
const data = await response.json();
console.log(data.content[0].text);

Python

import os
import requests

# Query meeting notes
response = requests.post(
    'https://gateway.maton.ai/granola/query_granola_meetings',
    headers={
        'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
        'Content-Type': 'application/json'
    },
    json={
        'query': 'What were the action items from my last meeting?'
    }
)
print(response.json())

Error Handling

Status Meaning
400 Missing Granola connection
401 Invalid or missing Maton API key
429 Rate limited (approx 100 req/min)

Troubleshooting: API Key Issues

  1. Check that the MATON_API_KEY environment variable is set:
echo $MATON_API_KEY
  1. Verify the API key is valid by listing connections:
python \x3C\x3C'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Troubleshooting: Invalid App Name

  1. Ensure your URL path starts with granola. For example:
  • Correct: https://gateway.maton.ai/granola/query_granola_meetings
  • Incorrect: https://gateway.maton.ai/query_granola_meetings

Troubleshooting: MCP Parameter Errors

MCP tools return validation errors when required parameters are missing:

{
  "content": [
    {
      "type": "text",
      "text": "MCP error -32602: Input validation error: Invalid arguments for tool get_meetings: [\
  {\
    \"code\": \"invalid_type\",\
    \"expected\": \"array\",\
    \"received\": \"undefined\",\
    \"path\": [\"meeting_ids\"],\
    \"message\": \"Required\"\
  }\
]"
    }
  ],
  "isError": true
}

Notes

  • All IDs are UUIDs (with or without hyphens)
  • MCP tool responses wrap content in {"content": [{"type": "text", "text": "..."}], "isError": false} format
  • Users can only query their own meeting notes; shared notes from others are not accessible
  • Basic (free) plan users are limited to notes from the last 30 days
  • The get_meeting_transcript tool is only available on paid Granola tiers

Resources

Usage Guidance
This skill appears coherent: it only needs MATON_API_KEY to call Maton gateway endpoints for Granola. Before installing, confirm the Maton domains (gateway.maton.ai, ctrl.maton.ai, connect.maton.ai) are legitimate for your organization, ensure the API key you provide has the minimum necessary scope, avoid using highly privileged keys, and be aware that requesting transcripts or detailed meeting content can expose sensitive information—rotate and revoke the key if you stop using the skill. If you need higher assurance, verify Maton's privacy policies or test the integration with a throwaway account/key first.
Capability Analysis
Type: OpenClaw Skill Name: granola-api Version: 1.0.1 The skill bundle provides an integration with Granola MCP via the Maton API. It requires a `MATON_API_KEY` from environment variables, which is a standard and expected practice for API integrations. All network communications are directed to legitimate `maton.ai` and `granola.ai` domains, consistent with the skill's purpose. The code examples in `SKILL.md` use standard libraries for HTTP requests and JSON handling, without any signs of arbitrary code execution, shell injection, or attempts to access unrelated sensitive data. The `SKILL.md` content is purely instructional and does not contain any prompt injection attempts designed to manipulate the AI agent into malicious actions. The JSON schemas are well-defined, restricting inputs to expected types and formats. No evidence of intentional harmful behavior was found.
Capability Assessment
Purpose & Capability
Name/description (Granola MCP integration) match the provided endpoints, example calls, and JSON schemas. The only required secret is MATON_API_KEY which is needed to call maton.ai gateway endpoints — this is coherent with the stated purpose.
Instruction Scope
SKILL.md contains concrete HTTP examples that only read the declared MATON_API_KEY and call Maton/Gra nola endpoints. It does not instruct reading other local files, scanning system state, or sending data to unrelated external endpoints. The instructions are scoped to listing/querying/creating/deleting Granola MCP connections and querying meeting content.
Install Mechanism
No install spec and no code files beyond schemas and documentation; the skill is instruction-only so nothing is written to disk or automatically installed. This is the lowest-risk install model.
Credentials
The skill requests a single environment variable (MATON_API_KEY). That key is necessary and proportionate for the documented gateway calls. No unrelated credentials, config paths, or broad secret scavenging are requested.
Persistence & Privilege
always is false and the skill does not request persistent modifications to agent/system configuration. It does not attempt to modify other skills or system-wide settings.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install granola-api
  3. After installation, invoke the skill by name or use /granola-api
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v1.0.1
- Added MCP (Model Context Protocol) support for Granola integration with managed authentication. - Introduced four MCP tools: query_granola_meetings, list_meetings, get_meetings, and get_meeting_transcript, each with its own request schema. - All authentication and connection flows now require explicit MCP method and connection ID for multi-connection environments. - Documentation updated with concise tool reference, example requests, and response formats. - Improved clarity for API usage and connection management flows.
v1.0.0
Initial release of the granola-api skill, providing Granola meeting content access with managed OAuth. - Query meeting notes, search meeting content, list meetings, and retrieve transcripts from Granola using a unified API. - Managed OAuth authentication and connection lifecycle via Maton API key. - Supports four main MCP tools: query_granola_meetings, list_meetings, and more. - Includes code examples for meeting queries, managing connections, and specifying active connections. - Designed for easy integration with existing Python scripts and third-party platforms.
Metadata
Slug granola-api
Version 1.0.1
License
All-time Installs 0
Active Installs 0
Total Versions 2
Frequently Asked Questions

What is Granola?

Granola MCP integration with managed authentication. Use this skill when users want to search meeting content, get meeting summaries, find action items, or r... It is an AI Agent Skill for Claude Code / OpenClaw, with 467 downloads so far.

How do I install Granola?

Run "/install granola-api" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is Granola free?

Yes, Granola is completely free (open-source). You can download, install and use it at no cost.

Which platforms does Granola support?

Granola is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created Granola?

It is built and maintained by byungkyu (@byungkyu); the current version is v1.0.1.

💬 Comments