multi-workspace-for-notion 0.0.0-stage → 0.1.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.
Potentially problematic release.
This version of multi-workspace-for-notion might be problematic. Click here for more details.
- package/LICENSE +21 -0
- package/README.ko.md +238 -0
- package/README.md +239 -2
- package/package.json +45 -4
- package/plugin/server.mjs +20717 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 heoeunseo
|
|
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.ko.md
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
<h1 align="center">Multi-Workspace for Notion</h1>
|
|
2
|
+
|
|
3
|
+
<p align="center"><em>Claude Code 하나로 모든 Notion 워크스페이스를. 공식 도구는 그대로.</em></p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="https://img.shields.io/badge/version-0.1.0-111111?style=flat-square" alt="Version 0.1.0">
|
|
7
|
+
<img src="https://img.shields.io/badge/Claude%20Code-plugin-111111?style=flat-square" alt="Claude Code plugin">
|
|
8
|
+
<img src="https://img.shields.io/badge/platform-macOS-111111?style=flat-square" alt="macOS">
|
|
9
|
+
<img src="https://img.shields.io/badge/license-MIT-111111?style=flat-square" alt="MIT license">
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center"><sub><a href="README.md">English</a> · <a href="README.ko.md">한국어</a></sub></p>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
Claude Code에서 여러 Notion 워크스페이스를 동시에 쓸 수 있게 해 줍니다. 공식 Notion MCP 서버의 도구를 하나도 빠짐없이 그대로 씁니다.
|
|
17
|
+
|
|
18
|
+
> **상태: 개발 초기 (v0.1.0).** 워크스페이스 연결과 공식 도구 전달은 동작하며, 실제 워크스페이스 두 개를 Claude Code에 연결해 시험했습니다. 계획한 기능 중 아직 없는 것이 여럿 있습니다. [로드맵](#로드맵)과 [알려진 제약](#알려진-제약)을 참고하세요.
|
|
19
|
+
>
|
|
20
|
+
> 비공식 프로젝트입니다. Notion Labs, Inc.와 관계가 없고 Notion의 승인을 받지 않았습니다.
|
|
21
|
+
|
|
22
|
+
## 왜 만들었나
|
|
23
|
+
|
|
24
|
+
Notion 공식 MCP 커넥터는 연결 하나에 워크스페이스 하나만 붙습니다. 다른 워크스페이스를 쓰려면 연결을 끊고 다시 로그인해야 하고, 그동안 다른 대화에도 영향을 줍니다. claude.ai는 같은 URL(`https://mcp.notion.com/mcp`)로 커넥터를 하나 더 추가하는 것도 막습니다.
|
|
25
|
+
|
|
26
|
+
Claude Code에서는 같은 URL을 이름만 다르게 두 번 등록할 수 있습니다. 하지만 이런 문제가 있습니다.
|
|
27
|
+
|
|
28
|
+
- 연결마다 도구 전체(약 65개)가 복제됩니다. 워크스페이스가 2개면 약 130개, 3개면 약 195개가 됩니다.
|
|
29
|
+
- Notion 로그인 화면에서 실제로 어느 워크스페이스를 골랐는지 아무도 확인하지 않습니다. 그래서 `notion-work`라고 이름 붙인 연결이 개인 워크스페이스를 가리키고 있어도 모르고 지나갈 수 있습니다.
|
|
30
|
+
- 모든 워크스페이스를 한 번에 검색하는 것처럼 워크스페이스를 넘나드는 기능이 없습니다.
|
|
31
|
+
|
|
32
|
+
다른 오픈소스 프로젝트들은 Notion REST API를 직접 호출하고, 직접 만든 도구 몇 개만 제공합니다. 이 프로젝트는 공식 호스팅 서버 앞에 서서 공식 도구를 그대로 넘겨주므로, Notion이 도구를 바꾸면 자동으로 따라갑니다.
|
|
33
|
+
|
|
34
|
+
## 동작 방식
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
Claude Code
|
|
38
|
+
│ stdio (Claude가 서버를 자식 프로세스로 실행)
|
|
39
|
+
▼
|
|
40
|
+
Multi-Workspace for Notion (로컬 Node 프로세스)
|
|
41
|
+
│ 호출마다 workspace 값을 보고 보낼 곳을 고름
|
|
42
|
+
├──▶ mcp.notion.com [personal]
|
|
43
|
+
├──▶ mcp.notion.com [work]
|
|
44
|
+
└──▶ mcp.notion.com [...]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- **워크스페이스마다 OAuth 클라이언트 하나.** 워크스페이스를 연결하면 서버가 Notion MCP 서버에 클라이언트로 등록하고(Dynamic Client Registration), PKCE로 로그인하고, 임시 `localhost` 포트로 인증 결과를 받습니다.
|
|
48
|
+
- **고른 워크스페이스를 확인합니다.** 로그인 직후 `notion-get-self`를 호출해 실제 워크스페이스 이름과 ID를 기록합니다. 이미 연결된 워크스페이스를 또 고르면 거부합니다.
|
|
49
|
+
- **공식 도구를 한 번만 노출합니다.** 도구마다 필수 파라미터 `workspace` 하나가 더 붙습니다. 이 파라미터에 넣을 수 있는 값은 그 도구가 있는 워크스페이스뿐이라, 요금제에 따라 없는 도구가 엉뚱한 워크스페이스로 가지 않습니다. 그 밖의 호출 내용과 결과는 손대지 않고 그대로 전달합니다.
|
|
50
|
+
- **연결된 워크스페이스를 Claude에게 알려 줍니다.** 서버 안내문(instructions)에 각 워크스페이스의 별칭, 실제 이름, 설명을 넣습니다. 워크스페이스가 불분명하면 쓰기 전에 사용자에게 물으라는 내용도 넣고, 그 뒤에 Notion 공식 안내문을 붙입니다.
|
|
51
|
+
|
|
52
|
+
Claude가 보내는 호출은 이런 모양입니다.
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{ "name": "notion-search", "arguments": { "workspace": "work", "query": "roadmap" } }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 필요한 것
|
|
59
|
+
|
|
60
|
+
- macOS (내장 `security` 명령으로 키체인에 토큰을 저장합니다)
|
|
61
|
+
- Node.js 20 이상
|
|
62
|
+
- Claude Code
|
|
63
|
+
|
|
64
|
+
## Claude Code 플러그인으로 설치 (추천)
|
|
65
|
+
|
|
66
|
+
이 저장소는 Claude Code 플러그인 마켓플레이스입니다. 플러그인에 MCP 서버가 파일 하나로 묶여 들어 있어서 따로 빌드할 필요가 없습니다.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
claude plugin marketplace add heoeunseo08/multi-workspace-for-notion
|
|
70
|
+
claude plugin install multi-workspace@multi-workspace-for-notion
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
지금은 저장소가 비공개라서, 저장소를 읽을 수 있는 계정에서만 설치됩니다.
|
|
74
|
+
|
|
75
|
+
Claude Code 세션을 새로 연 뒤 워크스페이스마다 연결합니다.
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
/multi-workspace:workspace-add personal 개인 메모
|
|
79
|
+
/multi-workspace:workspace-add work 회사 위키
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
브라우저에 Notion 로그인 화면이 열리면, 이 별칭으로 연결할 워크스페이스를 골라 승인하세요. 그러면 Claude가 실제로 연결된 워크스페이스를 알려 줍니다. 의도한 워크스페이스가 아니면 지우고 다시 추가하세요. 새로 연결한 워크스페이스의 도구는 다음 대화부터 보입니다.
|
|
83
|
+
|
|
84
|
+
- 별칭은 영어 소문자나 숫자로 시작하고, 영어 소문자·숫자·`-`·`_`만 쓸 수 있습니다(최대 32자).
|
|
85
|
+
- 설명은 넣지 않아도 됩니다. Claude가 이 설명을 보고 워크스페이스를 고르므로, 그 워크스페이스에 무엇이 있는지 몇 마디 적어 두면 도움이 됩니다.
|
|
86
|
+
- 로그인은 최대 10분까지 기다립니다.
|
|
87
|
+
|
|
88
|
+
claude.ai Notion 커넥터도 켜져 있으면 Claude에게 Notion 도구가 두 벌 보입니다. 이 플러그인을 쓰는 곳에서는 그 커넥터를 꺼서 Claude가 헷갈리지 않게 하세요.
|
|
89
|
+
|
|
90
|
+
그다음에는 평소 말투로 요청하면 됩니다. 예를 들어 "회사 노션과 개인 노션에서 각각 '로드맵'을 검색해 줘"라고 하면, Claude가 별칭과 설명을 보고 `workspace` 값을 고릅니다.
|
|
91
|
+
|
|
92
|
+
## 스킬
|
|
93
|
+
|
|
94
|
+
| 스킬 | 하는 일 |
|
|
95
|
+
| --- | --- |
|
|
96
|
+
| `/multi-workspace:workspace-list` | 연결된 워크스페이스를 실제 이름, 설명, 상태와 함께 보여줍니다. |
|
|
97
|
+
| `/multi-workspace:workspace-add <별칭> [설명]` | 브라우저로 워크스페이스를 연결하고, 실제로 어느 워크스페이스를 골랐는지 보여줍니다. |
|
|
98
|
+
| `/multi-workspace:workspace-remove <별칭>` | 확인을 받은 뒤, 이 컴퓨터에서 그 워크스페이스의 토큰과 설정을 지우고 Notion 쪽 토큰도 해제합니다. |
|
|
99
|
+
| `/multi-workspace:workspace-rename <별칭> [새 별칭] [새 설명]` | 다시 로그인하지 않고 별칭이나 설명을 바꿉니다. |
|
|
100
|
+
| `/multi-workspace:workspace-check [별칭]` | 저장된 토큰으로 다시 로그인해서, 워크스페이스가 아직 동작하는지와 처음 연결한 그 워크스페이스가 맞는지 확인합니다. |
|
|
101
|
+
| `/multi-workspace:workspace-help` | 스킬, 도구, 요청 예를 한 화면에 보여줍니다. |
|
|
102
|
+
|
|
103
|
+
`workspace-add`와 `workspace-remove`는 직접 입력했을 때만 실행됩니다. Claude가 알아서 실행하지 않습니다.
|
|
104
|
+
|
|
105
|
+
새 세션을 열 때마다 `Notion: personal(허 은서의 Notion), work(회사)`처럼 연결 상태가 한 줄로 표시되고, 확인이 필요한 워크스페이스가 있으면 `workspace-check`를 안내합니다.
|
|
106
|
+
|
|
107
|
+
## Claude Desktop 확장(`.mcpb`, 아직 시험 전)
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm install
|
|
111
|
+
npm run pack:mcpb # multi-workspace-for-notion.mcpb 생성
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
이 파일을 Claude Desktop으로 열어 설치한 뒤, Claude에게 워크스페이스를 연결해 달라고 하면 됩니다(`workspace_connect`). Desktop에는 플러그인 스킬이 없으니 도구를 바로 씁니다. 아직 Claude Desktop에서 시험하지 않은 방법입니다.
|
|
115
|
+
|
|
116
|
+
## 소스에서 설치
|
|
117
|
+
|
|
118
|
+
코드를 고치거나 플러그인 없이 서버만 쓰고 싶을 때 이 방법을 씁니다.
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
git clone https://github.com/heoeunseo08/multi-workspace-for-notion.git
|
|
122
|
+
cd multi-workspace-for-notion
|
|
123
|
+
npm install
|
|
124
|
+
npm run build
|
|
125
|
+
node dist/index.js add personal "개인 메모"
|
|
126
|
+
claude mcp add --scope user multi-workspace -- node /absolute/path/to/multi-workspace-for-notion/dist/index.js
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
그다음 `claude mcp list`에서 `multi-workspace`가 연결됐는지 확인하세요.
|
|
130
|
+
|
|
131
|
+
## CLI 명령
|
|
132
|
+
|
|
133
|
+
| 명령 | 하는 일 |
|
|
134
|
+
| --- | --- |
|
|
135
|
+
| `node dist/index.js` | MCP 서버를 stdio로 실행합니다. Claude가 실행하는 명령이라 직접 쓸 일은 없습니다. |
|
|
136
|
+
| `node dist/index.js list` | 연결된 워크스페이스 목록을 보여줍니다: 별칭, 실제 워크스페이스 이름, 상태, 설명 |
|
|
137
|
+
| `node dist/index.js add <별칭> [설명...]` | 브라우저 로그인으로 워크스페이스를 연결합니다. |
|
|
138
|
+
| `node dist/index.js tools <별칭>` | 저장된 토큰으로 붙어서 워크스페이스를 확인하고 도구 목록을 보여줍니다. 연결이 아직 살아 있는지 확인할 때 씁니다. |
|
|
139
|
+
| `node dist/index.js rename <별칭> <새 별칭>` | 다시 로그인하지 않고 별칭을 바꿉니다. |
|
|
140
|
+
| `node dist/index.js remove <별칭>` | 이 컴퓨터에서 워크스페이스의 토큰과 설정을 지우고 Notion 쪽 토큰도 해제합니다. |
|
|
141
|
+
|
|
142
|
+
## Claude에게 보이는 도구
|
|
143
|
+
|
|
144
|
+
| 도구 | 설명 |
|
|
145
|
+
| --- | --- |
|
|
146
|
+
| 모든 공식 Notion 도구 | 이름, 설명, 옵션은 그대로이고 필수 파라미터 `workspace`가 하나 붙습니다. 읽기 도구가 그 워크스페이스에서 ID를 찾지 못하면 다른 워크스페이스에서 다시 시도하고, 어느 워크스페이스에서 찾았는지 알려 줍니다. 쓰기 도구는 고르지 않은 워크스페이스로 보내지 않습니다. |
|
|
147
|
+
| `search_all_workspaces` | 모든 워크스페이스에서 `notion-search`를 동시에 실행하고 결과를 워크스페이스별로 묶어 보여줍니다. 워크스페이스가 둘 이상 연결돼 있을 때만 보입니다. |
|
|
148
|
+
| `workspace_list` | 연결된 워크스페이스를 보여줍니다: 별칭, 설명, 실제 워크스페이스 이름과 ID, 상태, 연결을 마지막으로 확인한 시각 |
|
|
149
|
+
| `workspace_connect` | 브라우저로 워크스페이스를 연결합니다(최대 10분 기다림). |
|
|
150
|
+
| `workspace_disconnect` | 이 컴퓨터에서 워크스페이스의 토큰과 설정을 지우고 Notion 쪽 토큰도 해제합니다. 되돌릴 수 없는 작업으로 표시돼 있어 Claude가 먼저 확인을 받습니다. |
|
|
151
|
+
| `workspace_rename` | 다시 로그인하지 않고 별칭이나 설명을 바꿉니다. 새 별칭은 새 대화부터 쓸 수 있습니다. |
|
|
152
|
+
| `workspace_check` | 저장된 토큰으로 다시 로그인해서 워크스페이스를 확인하고 상태를 갱신합니다. |
|
|
153
|
+
|
|
154
|
+
## 데이터 저장 위치
|
|
155
|
+
|
|
156
|
+
| 무엇 | 어디 |
|
|
157
|
+
| --- | --- |
|
|
158
|
+
| OAuth 토큰과 클라이언트 등록 정보 | macOS 키체인. 서비스 `multi-workspace-for-notion`, 계정 `workspace:<별칭>` |
|
|
159
|
+
| 별칭, 설명, 실제 워크스페이스 이름과 ID | `~/.config/multi-workspace-for-notion/config.json` |
|
|
160
|
+
| 도구 목록과 안내문 캐시 | `~/.config/multi-workspace-for-notion/cache/` |
|
|
161
|
+
| 토큰 저장용 잠금 파일 | `~/.config/multi-workspace-for-notion/locks/` |
|
|
162
|
+
|
|
163
|
+
다른 폴더를 쓰려면 `MWN_CONFIG_DIR`을 설정하세요. 파일은 본인만 읽고 쓸 수 있는 권한으로 만들고, 토큰은 절대 들어가지 않습니다.
|
|
164
|
+
|
|
165
|
+
## 보안
|
|
166
|
+
|
|
167
|
+
- 서버는 Claude와 stdio로 통신하고, 평소에는 네트워크 포트를 열지 않습니다.
|
|
168
|
+
- 로그인하는 동안에만 인증 결과를 받는 서버가 `127.0.0.1`과 `::1`에서 기다립니다. 응답 하나만 받고, OAuth `state`를 확인한 뒤 바로 닫습니다.
|
|
169
|
+
- 토큰은 키체인에만 있습니다. `security` 명령의 표준 입력으로 넘기므로 프로세스 목록에도 보이지 않습니다.
|
|
170
|
+
- `remove`는 이 컴퓨터의 토큰을 먼저 지운 뒤 Notion 쪽 토큰을 해제합니다(RFC 7009). 오프라인 등으로 해제에 실패하면 결과에 표시되니, 그때는 Notion 설정의 연결(Connections) 메뉴에서 직접 해제하세요.
|
|
171
|
+
|
|
172
|
+
## 알려진 제약
|
|
173
|
+
|
|
174
|
+
- **claude.ai 웹과 모바일에서는 쓸 수 없습니다.** 웹과 모바일의 커스텀 커넥터는 원격 URL만 받습니다.
|
|
175
|
+
- **Claude Desktop은 아직 시험하지 않았습니다.**
|
|
176
|
+
- **macOS만 지원합니다.** 키체인을 쓰기 때문입니다.
|
|
177
|
+
- **새로 연결한 워크스페이스는 새 대화부터 보입니다.** Claude가 대화마다 도구 목록을 캐시합니다.
|
|
178
|
+
- **다른 세션이 토큰을 갱신하는 도중에 별칭을 바꾸면** 새 별칭에 Notion이 이미 바꾼 refresh 토큰이 남을 수 있습니다. 인증 저장, 별칭 변경, 연결 해제는 같은 잠금을 쓰므로 갱신 요청 자체가 별칭 변경과 겹칠 때만 생깁니다. 생기면 `workspace-check`가 알려 주고, 그 워크스페이스를 다시 연결해야 합니다.
|
|
179
|
+
- **MCP resources와 prompts는 넘겨주지 않습니다.** Notion의 `notion://docs/...` 문서는 `notion-fetch`로 읽을 수 있고, 서버가 Claude에게 그렇게 하라고 안내합니다.
|
|
180
|
+
- **시작할 때 워크스페이스마다 도구 목록을 받습니다**(워크스페이스 2개 기준 약 1초). 15초 안에 받지 못한 워크스페이스는 마지막으로 캐시해 둔 목록을 씁니다.
|
|
181
|
+
|
|
182
|
+
## 문제 해결
|
|
183
|
+
|
|
184
|
+
| 문제 | 해결 방법 |
|
|
185
|
+
| --- | --- |
|
|
186
|
+
| 워크스페이스 추가가 시간 초과로 끝남 | 로그인 화면이 실제로 열렸는지 확인하세요. CLI로 추가할 때는 출력된 주소로 직접 들어가 10분 안에 승인할 수 있습니다. |
|
|
187
|
+
| 다른 워크스페이스가 연결됨 | 지우고 다시 추가하면서 Notion 화면에서 맞는 워크스페이스를 고르세요. |
|
|
188
|
+
| "이미 연결되어 있습니다" 오류 | 그 Notion 워크스페이스가 다른 별칭으로 이미 연결돼 있습니다. `/multi-workspace:workspace-list`로 확인하세요. |
|
|
189
|
+
| 인증이 만료됐다는 오류로 호출이 실패함 | `/multi-workspace:workspace-check`로 확인한 뒤, 그 워크스페이스를 지우고 다시 추가하세요. |
|
|
190
|
+
| Claude가 엉뚱한 Notion 도구를 씀 | 이 플러그인을 쓰는 곳에서 claude.ai Notion 커넥터를 끄세요. |
|
|
191
|
+
|
|
192
|
+
## 로드맵
|
|
193
|
+
|
|
194
|
+
- [x] 워크스페이스 연결 (DCR, PKCE, localhost 콜백, 키체인, 워크스페이스 확인)
|
|
195
|
+
- [x] 공식 도구에 `workspace` 파라미터를 붙여 전달, 요금제에 따른 도구 차이 처리
|
|
196
|
+
- [x] 워크스페이스 관리를 MCP 도구와 플러그인 스킬로: 연결, 해제, 확인
|
|
197
|
+
- [x] `workspace_rename`: 다시 로그인하지 않고 별칭이나 설명 바꾸기
|
|
198
|
+
- [x] `search_all_workspaces`: 모든 워크스페이스를 한 번에 검색하고 결과에 출처 표시
|
|
199
|
+
- [x] 토큰 갱신에 파일 잠금을 걸어 여러 프로세스가 같은 워크스페이스를 안전하게 쓰기
|
|
200
|
+
- [x] 페이지 ID로 하는 호출이 실패하면 그 페이지가 실제로 있는 워크스페이스로 다시 보내기
|
|
201
|
+
- [x] 워크스페이스를 지울 때 Notion 쪽 접근 권한도 해제
|
|
202
|
+
- [x] Claude Code 플러그인
|
|
203
|
+
- [x] 패키징: npm 패키지는 의존성 없이 묶은 서버 하나만 담고, `npm run pack:mcpb`로 Claude Desktop 확장을 만든다
|
|
204
|
+
- [ ] npm에 배포하고, Claude Desktop에서 확장 시험하기
|
|
205
|
+
|
|
206
|
+
## 개발
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
npm install
|
|
210
|
+
npm run typecheck
|
|
211
|
+
npm test # 단위 테스트
|
|
212
|
+
npm run build # dist/로 컴파일하고 plugin/server.mjs로 묶음
|
|
213
|
+
npm run dev # 소스에서 바로 MCP 서버(stdio) 실행
|
|
214
|
+
npm run dev -- list # 소스에서 바로 CLI 실행
|
|
215
|
+
npm run pack:mcpb # Claude Desktop 확장
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
| 파일 | 역할 |
|
|
219
|
+
| --- | --- |
|
|
220
|
+
| `src/index.ts` | 진입점. 인자가 없으면 MCP 서버, 있으면 CLI |
|
|
221
|
+
| `src/server.ts` | MCP 서버, 도구 목록, 안내문 |
|
|
222
|
+
| `src/management.ts` | 워크스페이스 관리 도구 |
|
|
223
|
+
| `src/proxy.ts` | 워크스페이스별 도구 목록을 합치고 호출을 보낼 곳을 고름 |
|
|
224
|
+
| `src/upstream.ts` | 워크스페이스별 업스트림 세션, 도구 목록 캐시 |
|
|
225
|
+
| `src/connect.ts` | 워크스페이스 연결, 다시 붙기, 지우기 |
|
|
226
|
+
| `src/lock.ts` | 인증 저장을 감싸는, 서버 프로세스끼리 공유하는 잠금 |
|
|
227
|
+
| `src/oauth.ts` | 키체인을 쓰는 OAuth 클라이언트 |
|
|
228
|
+
| `src/callback-server.ts` | 인증 결과를 받는 임시 서버 |
|
|
229
|
+
| `src/keychain.ts` | `security` 명령으로 키체인에 저장 |
|
|
230
|
+
| `src/notion.ts` | 공식 Notion MCP 서버에 붙는 클라이언트 세션 |
|
|
231
|
+
| `src/config.ts` | 비밀이 아닌 설정 파일 |
|
|
232
|
+
| `plugin/server.mjs` | 플러그인이 실행하는, 하나로 묶은 서버 파일. `src/`를 고치면 `npm run build`로 다시 만들어 함께 커밋합니다. |
|
|
233
|
+
| `manifest.json`, `.mcpbignore` | Claude Desktop 확장 매니페스트와 거기서 뺄 파일 |
|
|
234
|
+
| `.claude-plugin/`, `skills/` | 플러그인 정보, 마켓플레이스 항목, 스킬 |
|
|
235
|
+
|
|
236
|
+
## 라이선스
|
|
237
|
+
|
|
238
|
+
[MIT](LICENSE)
|
package/README.md
CHANGED
|
@@ -1,3 +1,240 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center">Multi-Workspace for Notion</h1>
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="center"><em>One Claude Code, every Notion workspace. The official tools, untouched.</em></p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="https://img.shields.io/badge/version-0.1.0-111111?style=flat-square" alt="Version 0.1.0">
|
|
7
|
+
<img src="https://img.shields.io/badge/Claude%20Code-plugin-111111?style=flat-square" alt="Claude Code plugin">
|
|
8
|
+
<img src="https://img.shields.io/badge/platform-macOS-111111?style=flat-square" alt="macOS">
|
|
9
|
+
<img src="https://img.shields.io/badge/license-MIT-111111?style=flat-square" alt="MIT license">
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center"><sub><a href="README.md">English</a> · <a href="README.ko.md">한국어</a></sub></p>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
Use several Notion workspaces at the same time from Claude Code, with every tool the official Notion MCP server offers.
|
|
17
|
+
|
|
18
|
+
> **Status: early development (v0.1.0).** Connecting workspaces and proxying the official tools work and have been tested with two real workspaces in Claude Code. Several planned pieces are still missing; see [Roadmap](#roadmap) and [Known limitations](#known-limitations).
|
|
19
|
+
>
|
|
20
|
+
> This is an unofficial project. It is not affiliated with or endorsed by Notion Labs, Inc.
|
|
21
|
+
|
|
22
|
+
## Why
|
|
23
|
+
|
|
24
|
+
Notion's official MCP connector links one workspace per connection. To switch, you disconnect and sign in again, which affects every other conversation too. claude.ai also refuses to add a second connector with the same URL (`https://mcp.notion.com/mcp`).
|
|
25
|
+
|
|
26
|
+
Claude Code does let you register that URL twice under different names, but:
|
|
27
|
+
|
|
28
|
+
- every connection copies the full tool set (about 65 tools), so two workspaces mean about 130 tools and three mean about 195;
|
|
29
|
+
- nothing checks which workspace you actually picked on Notion's sign-in page, so `notion-work` can quietly end up pointing at your personal workspace;
|
|
30
|
+
- nothing works across workspaces, such as searching all of them at once.
|
|
31
|
+
|
|
32
|
+
Other open-source projects call the Notion REST API directly and expose a handful of hand-written tools. This project instead sits in front of the official hosted server, so you get the official tools as they are, and pick up Notion's changes to them automatically.
|
|
33
|
+
|
|
34
|
+
## How it works
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
Claude Code
|
|
38
|
+
│ stdio (Claude starts the server as a child process)
|
|
39
|
+
▼
|
|
40
|
+
Multi-Workspace for Notion (local Node process)
|
|
41
|
+
│ routes each call by its `workspace` argument
|
|
42
|
+
├──▶ mcp.notion.com [personal]
|
|
43
|
+
├──▶ mcp.notion.com [work]
|
|
44
|
+
└──▶ mcp.notion.com [...]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- **One OAuth client per workspace.** When you connect a workspace, the server registers itself with Notion's MCP server (Dynamic Client Registration), signs in with PKCE, and receives the callback on a temporary `localhost` port.
|
|
48
|
+
- **Checks the workspace you picked.** Right after sign-in it calls `notion-get-self` and records the real workspace name and ID. Picking a workspace that is already connected is refused.
|
|
49
|
+
- **Exposes the official tools once.** Each tool gets one extra, required `workspace` parameter. Its allowed values are the workspaces that have that tool, so tools missing from some plans can't be sent to the wrong workspace. Everything else about the call and its result passes through unchanged.
|
|
50
|
+
- **Tells Claude what is connected.** The server's instructions list each workspace's alias, real name and description, ask Claude to confirm the workspace before writing when it is unclear, and then include Notion's own instructions.
|
|
51
|
+
|
|
52
|
+
What Claude sends looks like this:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{ "name": "notion-search", "arguments": { "workspace": "work", "query": "roadmap" } }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Requirements
|
|
59
|
+
|
|
60
|
+
- macOS (tokens are stored in the Keychain through the built-in `security` command)
|
|
61
|
+
- Node.js 20 or newer
|
|
62
|
+
- Claude Code
|
|
63
|
+
|
|
64
|
+
## Install as a Claude Code plugin (recommended)
|
|
65
|
+
|
|
66
|
+
The repository is a Claude Code plugin marketplace. The plugin ships the MCP server as one bundled file, so there is nothing to build.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
claude plugin marketplace add heoeunseo08/multi-workspace-for-notion
|
|
70
|
+
claude plugin install multi-workspace@multi-workspace-for-notion
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The repository is private for now, so this works only for accounts that can read it.
|
|
74
|
+
|
|
75
|
+
Start a new Claude Code session, then connect each workspace:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
/multi-workspace:workspace-add personal My personal notes
|
|
79
|
+
/multi-workspace:workspace-add work Company wiki
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Your browser opens Notion's sign-in page: choose the workspace you want for this alias and approve. Claude then shows which workspace was actually connected. If it is not the one you meant, remove it and add it again. Tools for a newly connected workspace appear in the next conversation.
|
|
83
|
+
|
|
84
|
+
- An alias starts with a lowercase letter or digit and may contain lowercase letters, digits, `-` and `_` (up to 32 characters).
|
|
85
|
+
- The description is optional. Claude sees it, so a few words about what lives in the workspace help it choose.
|
|
86
|
+
- Sign-in waits up to 10 minutes.
|
|
87
|
+
|
|
88
|
+
If the claude.ai Notion connector is also enabled, Claude sees two sets of Notion tools. Turn that connector off where you use this plugin so Claude doesn't mix them up.
|
|
89
|
+
|
|
90
|
+
Then ask in plain language, for example "Search for 'roadmap' in both my work and personal Notion". Claude picks the `workspace` value from the aliases and descriptions.
|
|
91
|
+
|
|
92
|
+
## Skills
|
|
93
|
+
|
|
94
|
+
| Skill | What it does |
|
|
95
|
+
| --- | --- |
|
|
96
|
+
| `/multi-workspace:workspace-list` | Shows connected workspaces with their real names, descriptions and status. |
|
|
97
|
+
| `/multi-workspace:workspace-add <alias> [description]` | Connects a workspace through the browser and shows which workspace you actually picked. |
|
|
98
|
+
| `/multi-workspace:workspace-remove <alias>` | Asks for confirmation, then deletes the workspace's tokens and settings from this computer and revokes the tokens on Notion's side. |
|
|
99
|
+
| `/multi-workspace:workspace-rename <alias> [new-alias] [description]` | Changes an alias or description without signing in again. |
|
|
100
|
+
| `/multi-workspace:workspace-check [alias]` | Signs in again with the saved tokens and checks each workspace still works and is the one you connected. |
|
|
101
|
+
| `/multi-workspace:workspace-help` | Shows the skills, tools and example requests on one screen. |
|
|
102
|
+
|
|
103
|
+
`workspace-add` and `workspace-remove` run only when you type them; Claude doesn't start them on its own.
|
|
104
|
+
|
|
105
|
+
Each new session also starts with a one-line status, such as `Notion: personal(My Notion), work(Acme)`, and points you to `workspace-check` when a workspace needs attention.
|
|
106
|
+
|
|
107
|
+
## Claude Desktop extension (`.mcpb`, not tested yet)
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm install
|
|
111
|
+
npm run pack:mcpb # writes multi-workspace-for-notion.mcpb
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Open the file with Claude Desktop to install it, then ask Claude to connect a workspace (`workspace_connect`). Desktop has no plugin skills, so use the tools directly. This path has not been tested in Claude Desktop yet.
|
|
115
|
+
|
|
116
|
+
## Install from source
|
|
117
|
+
|
|
118
|
+
Use this to work on the code, or to run the server without the plugin.
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
git clone https://github.com/heoeunseo08/multi-workspace-for-notion.git
|
|
122
|
+
cd multi-workspace-for-notion
|
|
123
|
+
npm install
|
|
124
|
+
npm run build
|
|
125
|
+
node dist/index.js add personal "My personal notes"
|
|
126
|
+
claude mcp add --scope user multi-workspace -- node /absolute/path/to/multi-workspace-for-notion/dist/index.js
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Then check that `multi-workspace` shows as connected in `claude mcp list`.
|
|
130
|
+
|
|
131
|
+
## CLI reference
|
|
132
|
+
|
|
133
|
+
| Command | What it does |
|
|
134
|
+
| --- | --- |
|
|
135
|
+
| `node dist/index.js` | Runs the MCP server over stdio. Claude runs this; you don't need to. |
|
|
136
|
+
| `node dist/index.js list` | Lists connected workspaces: alias, real workspace name, status, description. |
|
|
137
|
+
| `node dist/index.js add <alias> [description...]` | Connects a workspace through the browser. |
|
|
138
|
+
| `node dist/index.js tools <alias>` | Signs in with the saved tokens, confirms the workspace, and lists its tools. Useful to check a connection still works. |
|
|
139
|
+
| `node dist/index.js rename <alias> <new-alias>` | Changes an alias without signing in again. |
|
|
140
|
+
| `node dist/index.js remove <alias>` | Deletes the workspace's tokens and settings from this computer and revokes the tokens on Notion's side. |
|
|
141
|
+
|
|
142
|
+
CLI messages are currently in Korean.
|
|
143
|
+
|
|
144
|
+
## Tools exposed to Claude
|
|
145
|
+
|
|
146
|
+
| Tool | Description |
|
|
147
|
+
| --- | --- |
|
|
148
|
+
| Every official Notion tool | Same name, description and options, plus a required `workspace` parameter. If a read-only tool can't find an ID in that workspace, it is retried in the others and the result says which workspace has it. Write tools are never sent to a workspace you didn't pick. |
|
|
149
|
+
| `search_all_workspaces` | Runs `notion-search` in every workspace at once and groups the results by workspace. Shown when two or more workspaces are connected. |
|
|
150
|
+
| `workspace_list` | Shows the connected workspaces: alias, description, real workspace name and ID, status, and when the connection was last confirmed. |
|
|
151
|
+
| `workspace_connect` | Connects a workspace through the browser (waits up to 10 minutes). |
|
|
152
|
+
| `workspace_disconnect` | Deletes a workspace's tokens and settings from this computer and revokes the tokens on Notion's side. Marked destructive, so Claude asks first. |
|
|
153
|
+
| `workspace_rename` | Changes an alias or description without signing in again. A new alias is usable from the next conversation. |
|
|
154
|
+
| `workspace_check` | Signs in again with the saved tokens, confirms the workspace and updates its status. |
|
|
155
|
+
|
|
156
|
+
## Where data is stored
|
|
157
|
+
|
|
158
|
+
| What | Where |
|
|
159
|
+
| --- | --- |
|
|
160
|
+
| OAuth tokens and client registration | macOS Keychain, service `multi-workspace-for-notion`, account `workspace:<alias>` |
|
|
161
|
+
| Aliases, descriptions, real workspace names and IDs | `~/.config/multi-workspace-for-notion/config.json` |
|
|
162
|
+
| Cached tool lists and instructions | `~/.config/multi-workspace-for-notion/cache/` |
|
|
163
|
+
| Lock files for saving tokens | `~/.config/multi-workspace-for-notion/locks/` |
|
|
164
|
+
|
|
165
|
+
Set `MWN_CONFIG_DIR` to use a different directory. Files are written with owner-only permissions and never contain tokens.
|
|
166
|
+
|
|
167
|
+
## Security
|
|
168
|
+
|
|
169
|
+
- The server talks to Claude over stdio and opens no network port in normal use.
|
|
170
|
+
- While you sign in, a callback server listens on `127.0.0.1` and `::1` only. It accepts one response, checks the OAuth `state`, then closes.
|
|
171
|
+
- Tokens live only in the Keychain. They are written through `security`'s standard input, so they never appear in the process list.
|
|
172
|
+
- `remove` deletes the tokens from this computer first, then revokes them on Notion's side (RFC 7009). If revoking fails, for example offline, the result says so; remove the connection in Notion's settings under Connections.
|
|
173
|
+
|
|
174
|
+
## Known limitations
|
|
175
|
+
|
|
176
|
+
- **claude.ai web and mobile are not supported.** Their custom connectors accept only remote URLs.
|
|
177
|
+
- **Claude Desktop is not tested yet.**
|
|
178
|
+
- **macOS only**, because of the Keychain.
|
|
179
|
+
- **A newly connected workspace appears in new conversations.** Claude caches the tool list per conversation.
|
|
180
|
+
- **Renaming a workspace while another session is refreshing its token** can leave the new alias with a refresh token Notion has already replaced. Credential saves, renames and disconnects share a lock, so this needs the refresh request itself to overlap the rename; if it happens, `workspace-check` reports it and the workspace has to be connected again.
|
|
181
|
+
- **MCP resources and prompts are not proxied.** Notion's `notion://docs/...` documents can still be read with `notion-fetch`; the server tells Claude to do so.
|
|
182
|
+
- **Startup fetches each workspace's tool list** (about a second for two workspaces). If a workspace can't be reached within 15 seconds, the last cached list is used.
|
|
183
|
+
|
|
184
|
+
## Troubleshooting
|
|
185
|
+
|
|
186
|
+
| Problem | What to do |
|
|
187
|
+
| --- | --- |
|
|
188
|
+
| Adding a workspace times out | Make sure the sign-in page actually opened. With the CLI, you can open the printed URL yourself and approve within 10 minutes. |
|
|
189
|
+
| The wrong workspace was connected | Remove it, then add it again and choose the right workspace on Notion's page. |
|
|
190
|
+
| "already connected" | That Notion workspace is already linked under another alias. Check with `/multi-workspace:workspace-list`. |
|
|
191
|
+
| Calls fail with an expired-sign-in error | Run `/multi-workspace:workspace-check`, then remove and add the workspace again. |
|
|
192
|
+
| Claude uses the wrong Notion tools | Turn off the claude.ai Notion connector where you use this plugin. |
|
|
193
|
+
|
|
194
|
+
## Roadmap
|
|
195
|
+
|
|
196
|
+
- [x] Connect workspaces (DCR, PKCE, localhost callback, Keychain, workspace check)
|
|
197
|
+
- [x] Proxy the official tools with a `workspace` parameter and per-plan availability
|
|
198
|
+
- [x] Workspace management as MCP tools and plugin skills: connect, disconnect, check
|
|
199
|
+
- [x] `workspace_rename`: change an alias or description without signing in again
|
|
200
|
+
- [x] `search_all_workspaces`: search every workspace at once, results labelled by workspace
|
|
201
|
+
- [x] File lock around token refresh so several processes can share a workspace safely
|
|
202
|
+
- [x] Retry calls that use a page ID in the workspace that actually owns the page
|
|
203
|
+
- [x] Revoke access on Notion's side when removing a workspace
|
|
204
|
+
- [x] Claude Code plugin
|
|
205
|
+
- [x] Packaging: the npm package ships only the bundled server, with no dependencies; `npm run pack:mcpb` builds a Claude Desktop extension
|
|
206
|
+
- [ ] Publish to npm, and test the extension in Claude Desktop
|
|
207
|
+
|
|
208
|
+
## Development
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
npm install
|
|
212
|
+
npm run typecheck
|
|
213
|
+
npm test # unit tests
|
|
214
|
+
npm run build # compiles to dist/ and bundles plugin/server.mjs
|
|
215
|
+
npm run dev # MCP server over stdio, from source
|
|
216
|
+
npm run dev -- list # CLI, from source
|
|
217
|
+
npm run pack:mcpb # Claude Desktop extension
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
| File | Role |
|
|
221
|
+
| --- | --- |
|
|
222
|
+
| `src/index.ts` | Entry point: MCP server without arguments, CLI otherwise |
|
|
223
|
+
| `src/server.ts` | MCP server, tool list, instructions |
|
|
224
|
+
| `src/management.ts` | Workspace management tools |
|
|
225
|
+
| `src/proxy.ts` | Merges workspaces' tool lists and routes calls |
|
|
226
|
+
| `src/upstream.ts` | Upstream session per workspace, tool list cache |
|
|
227
|
+
| `src/connect.ts` | Connect, reopen and remove a workspace |
|
|
228
|
+
| `src/lock.ts` | Lock shared by server processes, around credential saves |
|
|
229
|
+
| `src/oauth.ts` | OAuth client provider backed by the Keychain |
|
|
230
|
+
| `src/callback-server.ts` | Temporary OAuth callback server |
|
|
231
|
+
| `src/keychain.ts` | Keychain storage through `security` |
|
|
232
|
+
| `src/notion.ts` | Client session to the official Notion MCP server |
|
|
233
|
+
| `src/config.ts` | Non-secret settings file |
|
|
234
|
+
| `plugin/server.mjs` | Bundled server the plugin runs. Rebuild with `npm run build` and commit it whenever `src/` changes. |
|
|
235
|
+
| `manifest.json`, `.mcpbignore` | Claude Desktop extension manifest and the files it leaves out |
|
|
236
|
+
| `.claude-plugin/`, `skills/` | Plugin manifest, marketplace entry and skills |
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
[MIT](LICENSE)
|
package/package.json
CHANGED
|
@@ -1,6 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "multi-workspace-for-notion",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"dev": "tsx src/index.ts",
|
|
6
|
+
"typecheck": "tsc --noEmit",
|
|
7
|
+
"build": "tsc -p tsconfig.build.json && npm run bundle",
|
|
8
|
+
"start": "node dist/index.js",
|
|
9
|
+
"test": "node --import tsx --test 'src/**/*.test.ts'",
|
|
10
|
+
"bundle": "esbuild src/index.ts --bundle --platform=node --format=esm --target=node20 --legal-comments=none --outfile=plugin/server.mjs --banner:js=\"import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);\"",
|
|
11
|
+
"pack:mcpb": "npm run build && npx -y @anthropic-ai/mcpb@2 pack . multi-workspace-for-notion.mcpb",
|
|
12
|
+
"prepublishOnly": "npm run build"
|
|
13
|
+
},
|
|
14
|
+
"type": "module",
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
17
|
+
"@types/node": "^26.6.5",
|
|
18
|
+
"esbuild": "^0.28.2",
|
|
19
|
+
"tsx": "^4.23.15",
|
|
20
|
+
"typescript": "^7.0.2",
|
|
21
|
+
"zod": "^4.6.7"
|
|
22
|
+
},
|
|
23
|
+
"description": "Use several Notion workspaces at once from Claude Code and Claude Desktop, with the official Notion MCP tools",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"author": "heoeunseo",
|
|
26
|
+
"bin": {
|
|
27
|
+
"multi-workspace-for-notion": "plugin/server.mjs"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"plugin/server.mjs"
|
|
31
|
+
],
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=20"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"mcp",
|
|
37
|
+
"notion",
|
|
38
|
+
"claude"
|
|
39
|
+
],
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/heoeunseo08/multi-workspace-for-notion.git"
|
|
43
|
+
},
|
|
44
|
+
"os": [
|
|
45
|
+
"darwin"
|
|
46
|
+
]
|
|
47
|
+
}
|