@joe-broadhead/opencode-granola 0.0.0-stage → 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/LICENSE +21 -0
- package/README.md +169 -2
- package/dist/index.js +1591 -0
- package/dist/tui.js +370 -0
- package/package.json +57 -4
- package/skills/granola/SKILL.md +76 -0
- package/skills/granola-meeting-brief/SKILL.md +51 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
4
|
+
|
|
5
|
+
## [0.0.0] - 2026-11-01
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Registers Granola's official MCP server, `https://mcp.granola.ai/mcp`, under the name `granola`, so Granola's own
|
|
10
|
+
tools appear as `granola_<tool>` (`tools.granola.<tool>` in Code Mode). An existing `mcp.servers.granola` entry is
|
|
11
|
+
never overwritten; status reports one that points at another server.
|
|
12
|
+
- Sign-in through `/connect`, where the server is listed as Granola, or `opencode mcp auth granola`. `/connect` shows
|
|
13
|
+
"Sign in required" when Granola rejects the stored sign-in.
|
|
14
|
+
- Default permission rules, inserted into every agent directly after its base allow rule: `granola_*` asks, and
|
|
15
|
+
Granola's ten known reads are allowed. Your `permissions` and saved "Always allow" answers override them, and
|
|
16
|
+
agents without a base allow, such as Explore, keep their own rules.
|
|
17
|
+
- Granola's `sign_out` tool is hidden; sign out with `opencode mcp logout granola`.
|
|
18
|
+
- The `export_markdown` tool, which saves the notes, transcripts or both of 1 to 20 meetings to one Markdown file
|
|
19
|
+
after a permission prompt. Inputs `meeting_ids`, `content`, `path` and `overwrite`; files of at most 8 MB, written
|
|
20
|
+
atomically with mode `0600`. Without transcripts on the Granola plan, the file holds the notes and says so.
|
|
21
|
+
- `/granola-status`, which shows the connection, workspace, tools, agents without the default rules with the block to
|
|
22
|
+
paste, the host check and the next step.
|
|
23
|
+
- A terminal UI status dialog: the palette entry "Granola: Status" and `/granola`. It reads the read-only RPC method
|
|
24
|
+
`granola.meetings/status`.
|
|
25
|
+
- The skills `granola` and `granola-meeting-brief`.
|
|
26
|
+
- Options `exportDirectory` (default `Granola` in the home folder) and `allowUntestedHost` (default `false`).
|
|
27
|
+
- A host check that refuses OpenCode outside `>=2.2.3 <2.3.0` with `HOST_UNTESTED`, unless
|
|
28
|
+
`allowUntestedHost` is set. Every error carries a code, a message and one next step.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Joe Broadhead
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,170 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Granola for OpenCode
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Ask OpenCode about your Granola meetings, read their notes and transcripts, and save them as Markdown, through
|
|
4
|
+
Granola's official MCP server.
|
|
5
|
+
|
|
6
|
+
Unofficial; not affiliated with Granola.
|
|
7
|
+
|
|
8
|
+
## Requirements
|
|
9
|
+
|
|
10
|
+
- OpenCode `>=2.2.3 <2.3.0`, tested on 2.2.3 and 2.2.4. On another version the plugin refuses to start; see
|
|
11
|
+
[Troubleshooting](#troubleshooting).
|
|
12
|
+
- macOS or Linux.
|
|
13
|
+
- A Granola account. Granola's free plan includes the last 30 days of meeting history; transcripts and folders are
|
|
14
|
+
paid features.
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
opencode plugin add @joe-broadhead/opencode-granola
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This adds the plugin to your global OpenCode config. Restart OpenCode afterwards.
|
|
23
|
+
|
|
24
|
+
## Sign in
|
|
25
|
+
|
|
26
|
+
1. Run `/connect` and choose **Granola**, listed under MCP.
|
|
27
|
+
2. Press `o` or Enter to open Granola's sign-in page in your browser, then approve there.
|
|
28
|
+
3. Run `/granola-status`. It shows `Granola: connected` and the number of Granola tools available.
|
|
29
|
+
|
|
30
|
+
On the CLI, `opencode mcp auth granola` opens the sign-in page automatically. `/mcps` works too. There is
|
|
31
|
+
nothing to configure first: Granola registers OpenCode's sign-in itself.
|
|
32
|
+
|
|
33
|
+
When Granola rejects a stored sign-in, `/connect` shows Granola as "Sign in required"; choose it to sign in again. To
|
|
34
|
+
sign out, run `opencode mcp logout granola`. Granola's own `sign_out` tool is hidden, so the model cannot sign you out.
|
|
35
|
+
|
|
36
|
+
## Use
|
|
37
|
+
|
|
38
|
+
Ask in plain language, for example "What did we decide about the launch in last week's meetings?" or "Brief me for my
|
|
39
|
+
call with Acme." The `granola` skill teaches the model how to find, read and cite meetings, and the
|
|
40
|
+
`granola-meeting-brief` skill how to prepare a sourced brief.
|
|
41
|
+
|
|
42
|
+
Granola's tools appear as `granola_<tool>`, or `tools.granola.<tool>` in Code Mode. Granola decides which tools your
|
|
43
|
+
account gets. On the free plan:
|
|
44
|
+
|
|
45
|
+
- meeting history covers the last 30 days;
|
|
46
|
+
- transcripts and folders are paid features, so the transcript and folder tools fail with Granola's own message.
|
|
47
|
+
|
|
48
|
+
The plugin adds one tool, `export_markdown` (`granola_export_markdown`). It saves the notes, transcripts or both of 1
|
|
49
|
+
to 20 meetings to one Markdown file in your export folder, without passing the text through the conversation, and asks
|
|
50
|
+
before it writes. Its inputs are `meeting_ids`, `content` (`notes`, `transcript` or `both`), an optional `path` inside
|
|
51
|
+
the export folder, and `overwrite`. When your plan has no transcripts, the file holds the notes and says that
|
|
52
|
+
transcripts are not available on your Granola plan.
|
|
53
|
+
|
|
54
|
+
To see the connection, the workspace, the tools and the next step:
|
|
55
|
+
|
|
56
|
+
- `/granola-status` posts the status in the session.
|
|
57
|
+
- In the terminal UI, the command palette entry **Granola: Status**, or `/granola`, opens the same status in a dialog.
|
|
58
|
+
Press `r` to refresh and `Esc` to close.
|
|
59
|
+
|
|
60
|
+
The workspace name comes from the most recent Granola account read since OpenCode started, and is kept in memory
|
|
61
|
+
only. Until then, status says the workspace is unknown; ask the agent to check your Granola account.
|
|
62
|
+
|
|
63
|
+
## Permissions
|
|
64
|
+
|
|
65
|
+
| Kind | Tools | Default |
|
|
66
|
+
| --- | --- | --- |
|
|
67
|
+
| Reads | `get_account_info`, `list_meeting_folders`, `list_meetings`, `search_meetings`, `get_meetings`, `get_meeting_transcript`, `search_transcripts`, `query_granola_meetings`, `get_meeting_attachment`, `list_templates` | run without asking |
|
|
68
|
+
| Changes and sends | `create_folder`, `update_folder`, `add_note_to_folder`, `remove_note_from_folder`, `update_private_notes`, `generate_summary`, `give_feedback` | ask first |
|
|
69
|
+
| The plugin's export | `export_markdown` | asks first |
|
|
70
|
+
| New tools | any Granola tool this plugin version does not know yet | ask first; status names them |
|
|
71
|
+
| Hidden | `sign_out` | removed; use `opencode mcp logout granola` |
|
|
72
|
+
|
|
73
|
+
The plugin inserts these rules into each agent, directly after the agent's base "allow everything" rule. Your own
|
|
74
|
+
`permissions` and your saved "Always allow" answers override them, and a `deny` you configure always wins. Agents
|
|
75
|
+
without the base rule, such as Explore, are left unchanged, and Plan keeps its restrictions.
|
|
76
|
+
|
|
77
|
+
For example, to let one write run without asking:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"permissions": [
|
|
82
|
+
{ "action": "granola_create_folder", "resource": "*", "effect": "allow" }
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Agents defined only in your own config are created after plugins start, so they miss the default rules, and Granola's
|
|
88
|
+
writes would run there without asking. Status names each such agent and gives the block to paste first in that agent's
|
|
89
|
+
own `permissions`. Do not put the block in the top-level `permissions`, which would loosen Explore.
|
|
90
|
+
|
|
91
|
+
In `opencode run` and other runs where nobody can answer, a call that would ask is refused; reads still work.
|
|
92
|
+
|
|
93
|
+
## Configure
|
|
94
|
+
|
|
95
|
+
Two options, both optional: `exportDirectory`, an absolute path for exports (default: `Granola` in your home
|
|
96
|
+
folder), and `allowUntestedHost`. The
|
|
97
|
+
[configuration guide](https://github.com/joe-broadhead/opencode-granola/blob/HEAD/docs/configuration.md) covers them,
|
|
98
|
+
the full rule block, recipes, the export and every error code.
|
|
99
|
+
|
|
100
|
+
## Organisation rollout
|
|
101
|
+
|
|
102
|
+
Granola needs no client ID or app registration, so an organisation only installs the plugin for its members. Put the
|
|
103
|
+
plugin in the system config, which outranks each member's own config: `/etc/opencode/opencode.json` on Linux, or
|
|
104
|
+
`/Library/Application Support/opencode/opencode.json` on macOS.
|
|
105
|
+
|
|
106
|
+
```jsonc
|
|
107
|
+
{
|
|
108
|
+
"plugins": [
|
|
109
|
+
{
|
|
110
|
+
"package": "@joe-broadhead/opencode-granola",
|
|
111
|
+
"options": { "exportDirectory": "<an absolute path>/Granola" }
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Each member then signs in once with `/connect` → Granola. A managed `mcp.servers.granola` entry for
|
|
118
|
+
`https://mcp.granola.ai/mcp` is used as it is.
|
|
119
|
+
|
|
120
|
+
## Troubleshooting
|
|
121
|
+
|
|
122
|
+
Each connection state, as `/granola-status` shows it:
|
|
123
|
+
|
|
124
|
+
| Status | Code | What to do |
|
|
125
|
+
| --- | --- | --- |
|
|
126
|
+
| not configured | `NOT_REGISTERED` | Retry in a few seconds; if it persists, check that `plugins` in your OpenCode config lists the Granola plugin and that no `mcp.servers.granola` entry points elsewhere. |
|
|
127
|
+
| connecting | `CONNECTING` | Retry in a few seconds. |
|
|
128
|
+
| sign-in required | `AUTH_REQUIRED` | Run `/connect` and choose Granola, or run `opencode mcp auth granola` in a terminal. |
|
|
129
|
+
| failed | `CONNECTION_FAILED` | Reconnect Granola from `/mcps`, and if it keeps failing, run `/connect` and choose Granola to sign in again. |
|
|
130
|
+
| disabled | `DISABLED` | Remove `disabled: true` from `mcp.servers.granola` in your OpenCode config. |
|
|
131
|
+
| conflict | none | Remove `mcp.servers.granola` from your OpenCode config to use Granola's official server. |
|
|
132
|
+
|
|
133
|
+
**`MCP server not found: granola` from `opencode mcp auth granola`, right after OpenCode starts.** Plugins are still
|
|
134
|
+
loading for a few seconds. Run it again, or use `/connect`, which updates live.
|
|
135
|
+
|
|
136
|
+
**A tool says your Granola plan does not include it, or `TOOL_UNAVAILABLE`.** Granola's free plan has no
|
|
137
|
+
transcripts or folders, and covers the last 30 days of meetings. Older meetings are not found.
|
|
138
|
+
|
|
139
|
+
**`HOST_UNTESTED`.** The plugin refuses to start on an OpenCode version outside `>=2.2.3 <2.3.0`, including
|
|
140
|
+
development builds. Use a tested OpenCode version, or set the plugin option `allowUntestedHost: true` to run anyway;
|
|
141
|
+
status then shows `host untested`.
|
|
142
|
+
|
|
143
|
+
**`OPTIONS_INVALID`.** A plugin option has an unknown name or a wrong type. The message names the option.
|
|
144
|
+
|
|
145
|
+
**Status shows `conflict`.** Your config defines `mcp.servers.granola` for a different server, and the plugin never
|
|
146
|
+
overwrites it. An entry for Granola's official URL is used as it is.
|
|
147
|
+
|
|
148
|
+
**Status lists Agents without default rules.** See [Permissions](#permissions).
|
|
149
|
+
|
|
150
|
+
Granola uses the workspace that is active in your Granola app; meetings in other workspaces do not appear. The plugin
|
|
151
|
+
supports one Granola account.
|
|
152
|
+
|
|
153
|
+
## Uninstall
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
opencode mcp logout granola
|
|
157
|
+
opencode plugin remove @joe-broadhead/opencode-granola
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Restart OpenCode afterwards. Files you exported stay in your export folder.
|
|
161
|
+
|
|
162
|
+
## Links
|
|
163
|
+
|
|
164
|
+
- [Configuration](https://github.com/joe-broadhead/opencode-granola/blob/HEAD/docs/configuration.md)
|
|
165
|
+
- [Architecture](https://github.com/joe-broadhead/opencode-granola/blob/HEAD/docs/architecture.md)
|
|
166
|
+
- [Contributing](https://github.com/joe-broadhead/opencode-granola/blob/HEAD/CONTRIBUTING.md)
|
|
167
|
+
- [Security](https://github.com/joe-broadhead/opencode-granola/blob/HEAD/SECURITY.md)
|
|
168
|
+
- [Changelog](https://github.com/joe-broadhead/opencode-granola/blob/HEAD/CHANGELOG.md)
|
|
169
|
+
- [License](https://github.com/joe-broadhead/opencode-granola/blob/HEAD/LICENSE)
|
|
170
|
+
- [Issues](https://github.com/joe-broadhead/opencode-granola/issues)
|