文档

Granola

试用

通过 MCP 用自然语言查询 Granola 会议记录、列出会议、获取详情和原始转录,鉴权由 Maton API Key 自动管理。

它能做什么

所有请求走 https://api.maton.ai/granola/{tool-name},由 Maton 代理到 mcp.granola.ai 并自动注入凭证,鉴权使用 MATON_API_KEY 环境变量配 Bearer Token,绑定账号需先调 POST /connections 再打开返回的 url 完成 OAuth。当前共四个 MCP 工具:query_granola_meetings 支持自然语言对话式查询;list_meetings 返回会议 ID、标题、日期与参会人;get_meetings 按 ID 拉取摘要、决议和行动项;get_meeting_transcript 给出带时间戳的原始转录(仅付费套餐)。响应统一包装为 MCP 的 {content:[{type:text,text:...}], isError:false} 格式;Maton 侧限流约每分钟 100 次,免费套餐只能查到近 30 天笔记。

什么时候用它

  • 查本周分给我的会议行动项
  • 列出最近的会议及参会人
  • 按会议 ID 拉取摘要和决议
  • 获取某次会议的原始转录

技能文档

Granola MCP

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

Quick Start

python <<'EOF'
import urllib.request, os, json
data = json.dumps({'query': 'What action items came from my last meeting?'}).encode()
req = urllib.request.Request('https://api.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://api.maton.ai/granola/{tool-name}

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

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://api.maton.ai.

List Connections

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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 <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'granola', 'method': 'MCP'}).encode()
req = urllib.request.Request('https://api.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 <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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": "{connection_id}",
    "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 <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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 <<'EOF'
import urllib.request, os, json
data = json.dumps({'query': 'What were my action items?'}).encode()
req = urllib.request.Request('https://api.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', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

If you have multiple connections, always include this header to ensure requests go to the intended account.

Security & Permissions

  • Access is scoped to meeting notes, transcripts, and documents within the connected Granola account.
  • All write operations require explicit user approval. Before executing any create, update, or delete call, confirm the target resource and intended effect with the user.

MCP Reference

All MCP tools use POST method:

ToolDescriptionSchema
query_granola_meetingsChat with meeting notes using natural languageschema
list_meetingsList meetings with metadata and attendeesschema
get_meetingsRetrieve detailed content for specific meetingsschema
get_meeting_transcriptGet 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:\n**Feb 4, 2026 at 7:30 PM** - \"Team sync\" [[0]](https://notes.granola.ai/d/abc123)\n- Action item: Review Q1 roadmap\n- Action item: Schedule follow-up with engineering\n**Jan 27, 2026 at 1:04 AM** - \"Finance integration\" [[1]](https://notes.granola.ai/d/def456)\n- Discussed workflow automation platforms\n- 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": "\n\n    \n    John Doe (note creator) from Acme \n    Jane Smith from Acme \n    \n  \n\n\n    \n    John Doe (note creator) from Acme \n    \n  \n"
    }
  ],
  "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": "\n\n  \n  John Doe (note creator) from Acme \n  \n  \n  \n## Key Decisions\n- Approved Q1 roadmap\n- Budget increased by 15%\n\n## Action Items\n- @john: Review design specs by Friday\n- @jane: Schedule engineering sync\n\n\n"
    }
  ],
  "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": "\n[00:00:15] John: Let's get started with the Q1 planning...\n[00:01:23] Jane: I've prepared the budget breakdown...\n[00:03:45] John: That looks good. What about the timeline?\n"
    }
  ],
  "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://api.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://api.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

StatusMeaning
400Missing Granola connection
401Invalid or missing Maton API key
429Rate 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 <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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://api.maton.ai/granola/query_granola_meetings
  • Incorrect: https://api.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: [\n  {\n    \"code\": \"invalid_type\",\n    \"expected\": \"array\",\n    \"received\": \"undefined\",\n    \"path\": [\"meeting_ids\"],\n    \"message\": \"Required\"\n  }\n]"
    }
  ],
  "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

常见问题

怎么完成鉴权和绑定 Granola 账号?
设置环境变量 MATON_API_KEY,在请求头里用 Authorization: Bearer $MATON_API_KEY。绑定账号需 POST /connections(app=granola, method=MCP),拿到返回的 url 在浏览器里完成 OAuth;同时连多个账号时,要额外带 Maton-Connection 头指明目标连接。
免费套餐能拿到完整转录吗?
不能。get_meeting_transcript 仅对付费 Granola 套餐开放;免费账号最多也只能查到最近 30 天的笔记。
遇到错误码怎么处理?
401 表示 MATON_API_KEY 无效或缺失,400 表示还没建过 Granola 连接,429 是限流(约每分钟 100 次)。路径前缀必须是 /granola/,否则会被当成错误的应用名。

相关技能

通过托管 OAuth 代理调用 Fireflies.ai GraphQL 接口访问会议数据。

91 次安装4 星标

通过托管 OAuth 代理访问 Fathom API,获取会议录像、转写、摘要并管理 Webhook。

648 次安装12 星标

通过 OAuth 网关调度与管理 Zoom 会议、研讨会与云录制。

27 次安装1 星标

Granola (granola.ai). Use this skill for ANY Granola request — searching and reading data. Whenever a task involves Granola, use this skill instead of callin...

通过 Maton 网关和 MCP 协议接入 Notion,由平台代管 OAuth 凭据。

33 次安装

通过托管 OAuth 调用 Confluence Cloud API,管理页面、空间、博客、评论与附件。

43 次安装