dsh-notion-workspaces
Bind each DSH workspace to its own Notion workspace over the official Notion MCP. / 把每个 DSH 工作区绑定到各自的 Notion 工作区(走官方 Notion MCP)。
English | 中文
The gap this fills
dsh-notion-mcp connects dsh to Notion, but it holds one Notion grant for a
whole DSH environment: it hardcodes the credential ref NOTION_OAUTH, one
serverName, and mounts its MCP client in the profile's global scope. Authorize
a second Notion workspace and it overwrites the first. DSH itself offers no
per-workspace settings or credential scope to layer on top — <cwd>/.env ranks
below the managed credential store, and a desktop host boots once for every
workspace it serves.
This plugin expresses the mapping in the one place DSH does offer the granularity: the agent scope.
How it works
- A binding maps a workspace path to a Notion grant: its own credential ref, its
own
serverName, its own OAuth callback port. - On
agent/created, the session'sheader.cwddecides which binding applies. - The MCP client is mounted under that agent's context, so the
mcp__<serverName>__*tools exist only in sessions of that workspace. A session in an unbound workspace sees no Notion tools at all.
Bindings are stored in $DSH_HOME/notion-workspaces.json; each grant is a
secret in the DSH credential store under its own ref. Access tokens are
refreshed in the background, and the agents holding a rotated token are
remounted so they never authenticate with a retired one.
Install
dsh plugin --profile desktop add github:moyu-777/dsh-notion-workspaces
desktop is the profile your agent runs in — swap it for web, headless, or
whatever you use. The repository ships plain JavaScript (lib/, client/) and
declares no build scripts, so there is no allowBuilds approval step.
Configure
- Click Notion at the sidebar foot, next to Settings. (The same editor is also a page under Settings → Notion 工作区.)
- Add a binding and pick the DSH workspace from the list.
- Press 授权 / Authorize. A browser tab opens on Notion's consent screen;
approve the workspace you want this DSH workspace connected to. The callback
lands on
127.0.0.1:<port>in the running host. - Repeat for each workspace. Tools appear in that workspace's sessions as
mcp__notion_study__*and so on.
Where state lives
| What | Where |
|---|---|
| Bindings (workspace path → grant) | $DSH_HOME/notion-workspaces.json |
| Per-binding OAuth grant | DSH credential store ($DSH_HOME/.credentials.yaml), one ref per binding |
| Diagnostics | $DSH_HOME/notion-workspaces-diag.log (safe to delete) |
Requirements
- DSH with the
desktoporwebprofile (any profile that has a web server gets the dialog; a minimal profile still getsdsh notion-workspaces login). - Node 22.13+.
- Network access to
https://mcp.notion.com.
What it touches
- Credentials: reads and writes its own refs in the DSH credential store.
- Network:
https://mcp.notion.comonly — OAuth discovery, dynamic client registration, token exchange/refresh, and the MCP stream. - Files:
$DSH_HOME/notion-workspaces.jsonand the diagnostics log. - No telemetry, no other hosts, no install-time scripts.
Known limitation
The per-workspace hover menu (… next to a workspace in the sidebar) has no
extension point: sidebar.workspaces is a single seat already claimed by the
shipped browser, and its menu items are hardcoded. Across the client's 69 slot
keys there is no per-workspace menu seat, so the entry point is the sidebar-foot
button and the settings page instead.
Attribution
The OAuth flow in lib/notion-oauth.js is adapted from
dsh-notion-mcp by mingzeng
(@mingzeng21), MIT licensed — the retained
copyright notice is in NOTICE. The differences here are that the
callback port and the credential ref are per binding, and the module is
restructured into named exports.
Disclaimer
An independent community plugin. It is not affiliated with, endorsed by, or sponsored by Notion Labs, Inc. "Notion" is a trademark of Notion Labs, Inc., used here only to describe what the plugin connects to. Your use of Notion's services remains governed by Notion's own terms.
License
中文
把每个 DSH 工作区绑定到各自的 Notion 工作区,走官方 Notion MCP。
它补的是什么缺口
dsh-notion-mcp 能把 dsh 接到 Notion,但它对整个 DSH 环境只持有一份 Notion
授权:凭证引用 NOTION_OAUTH、serverName 都是写死的,MCP 客户端挂在 profile 的全局
作用域里。再授权第二个 Notion 工作区会覆盖掉第一个。而 DSH 本身没有工作区级的设置或
凭证作用域可用——<cwd>/.env 的优先级低于可写凭证存储,桌面宿主也是一次启动服务所有
工作区。
本插件把「工作区 → Notion 工作区」这个映射做在 DSH 唯一提供该粒度的地方:agent 作用域。
工作原理
- 一条绑定把一个工作区路径映射到一份 Notion 授权:各自的凭证引用、各自的
serverName、各自的 OAuth 回调端口。 - 在
agent/created时,用会话的header.cwd决定该用哪条绑定。 - MCP 客户端挂在该 agent 自己的上下文里,所以
mcp__<serverName>__*工具只存在于 那个工作区的会话中。未绑定的工作区完全看不到 Notion 工具。
绑定存在 $DSH_HOME/notion-workspaces.json;每份授权是 DSH 凭证存储里一个独立的密钥。
访问令牌会在后台刷新,持有旧令牌的 agent 会被重新挂载,不会拿着已失效的令牌继续请求。
安装
dsh plugin --profile desktop add github:moyu-777/dsh-notion-workspaces
desktop 换成你实际跑 agent 的 profile。仓库里是纯 JavaScript(lib/、client/),
且没有声明任何构建脚本,所以不需要 allowBuilds 授权。
配置
- 点侧栏底部、设置旁边的 Notion 按钮(设置页里的「Notion 工作区」是同一个编辑器)。
- 新增一条绑定,从列表里选 DSH 工作区。
- 点「授权」。浏览器会打开 Notion 的授权页,批准你要连接的那个工作区即可;回调打到运行中
宿主的
127.0.0.1:<端口>。 - 每个工作区重复一次。之后该工作区的会话里就会出现
mcp__notion_study__*这类工具。
状态存放位置
| 内容 | 位置 |
|---|---|
| 绑定表(工作区路径 → 授权) | $DSH_HOME/notion-workspaces.json |
| 每条绑定的 OAuth 授权 | DSH 凭证存储($DSH_HOME/.credentials.yaml),一条绑定一个 ref |
| 诊断日志 | $DSH_HOME/notion-workspaces-diag.log(可随时删除) |
它触碰了什么
- 凭证:读写自己在 DSH 凭证存储里的 ref。
- 网络:仅
https://mcp.notion.com(OAuth 发现、动态客户端注册、令牌换取与刷新、MCP 流)。 - 文件:
$DSH_HOME/notion-workspaces.json与诊断日志。 - 无遥测、无其他主机、无安装期脚本。
已知限制
工作区的悬停菜单(侧栏工作区行上的「…」)没有扩展点:sidebar.workspaces 是
single 座位且已被内置组件占用,菜单项是硬编码的。客户端 69 个 slot 里没有任何
「单个工作区菜单项」座位,因此入口只能是侧栏底部按钮和设置页。
致谢
lib/notion-oauth.js 的 OAuth 流程改编自 mingzeng
(@mingzeng21)的
dsh-notion-mcp(MIT),保留的版权声明见
NOTICE。此处改动是回调端口与凭证引用都改为按绑定分配,并把模块重构为具名导出。
免责声明
独立的社区插件,与 Notion Labs, Inc. 无隶属、无背书、无赞助关系。「Notion」是 Notion Labs, Inc. 的商标,此处仅用于说明本插件连接的对象。你使用 Notion 服务仍受 Notion 自身条款约束。
No comments yet. Be the first to write one.