multi-workspace-for-notion 0.1.1 → 0.2.1

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/README.ko.md CHANGED
@@ -3,7 +3,7 @@
3
3
  <p align="center"><em>Claude Code 하나로 모든 Notion 워크스페이스를. 공식 도구는 그대로.</em></p>
4
4
 
5
5
  <p align="center">
6
- <img src="https://img.shields.io/badge/version-0.1.1-111111?style=flat-square" alt="Version 0.1.1">
6
+ <img src="https://img.shields.io/badge/version-0.2.1-111111?style=flat-square" alt="Version 0.2.1">
7
7
  <img src="https://img.shields.io/badge/Claude%20Code-plugin-111111?style=flat-square" alt="Claude Code plugin">
8
8
  <img src="https://img.shields.io/badge/platform-macOS-111111?style=flat-square" alt="macOS">
9
9
  <img src="https://img.shields.io/badge/license-MIT-111111?style=flat-square" alt="MIT license">
@@ -15,7 +15,7 @@
15
15
 
16
16
  Claude Code에서 여러 Notion 워크스페이스를 동시에 쓸 수 있게 해 줍니다. 공식 Notion MCP 서버의 도구를 하나도 빠짐없이 그대로 씁니다.
17
17
 
18
- > **상태: 개발 초기 (v0.1.1).** 워크스페이스 연결과 공식 도구 전달은 동작하며, 실제 워크스페이스 두 개를 Claude Code에 연결해 시험했습니다. 계획한 기능 중 아직 없는 것이 여럿 있습니다. [로드맵](#로드맵)과 [알려진 제약](#알려진-제약)을 참고하세요.
18
+ > **상태: 개발 초기 (v0.2.1).** 워크스페이스 연결과 공식 도구 전달은 동작하며, 실제 워크스페이스를 Claude Code와 Claude Desktop에 연결해 시험했습니다. 계획한 기능 중 아직 없는 것이 여럿 있습니다. [로드맵](#로드맵)과 [알려진 제약](#알려진-제약)을 참고하세요.
19
19
  >
20
20
  > 비공식 프로젝트입니다. Notion Labs, Inc.와 관계가 없고 Notion의 승인을 받지 않았습니다.
21
21
 
@@ -26,7 +26,7 @@ Notion 공식 MCP 커넥터는 연결 하나에 워크스페이스 하나만 붙
26
26
  Claude Code에서는 같은 URL을 이름만 다르게 두 번 등록할 수 있습니다. 하지만 이런 문제가 있습니다.
27
27
 
28
28
  - 연결마다 도구 전체(약 65개)가 복제됩니다. 워크스페이스가 2개면 약 130개, 3개면 약 195개가 됩니다.
29
- - Notion 로그인 화면에서 실제로 어느 워크스페이스를 골랐는지 아무도 확인하지 않습니다. 그래서 `notion-work`라고 이름 붙인 연결이 개인 워크스페이스를 가리키고 있어도 모르고 지나갈 수 있습니다.
29
+ - 연결마다 이름을 직접 붙여야 하고, Notion 로그인 화면에서 실제로 어느 워크스페이스를 골랐는지는 아무도 확인하지 않습니다. 그래서 `notion-work`라고 이름 붙인 연결이 개인 워크스페이스를 가리키고 있어도 모르고 지나갈 수 있습니다.
30
30
  - 모든 워크스페이스를 한 번에 검색하는 것처럼 워크스페이스를 넘나드는 기능이 없습니다.
31
31
 
32
32
  다른 오픈소스 프로젝트들은 Notion REST API를 직접 호출하고, 직접 만든 도구 몇 개만 제공합니다. 이 프로젝트는 공식 호스팅 서버 앞에 서서 공식 도구를 그대로 넘겨주므로, Notion이 도구를 바꾸면 자동으로 따라갑니다.
@@ -39,20 +39,21 @@ Claude Code
39
39
  ▼
40
40
  Multi-Workspace for Notion (로컬 Node 프로세스)
41
41
  │ 호출마다 workspace 값을 보고 보낼 곳을 고름
42
- ├──▶ mcp.notion.com [personal]
43
- ├──▶ mcp.notion.com [work]
42
+ ├──▶ mcp.notion.com [허 은서의 Notion]
43
+ ├──▶ mcp.notion.com [회사]
44
44
  └──▶ mcp.notion.com [...]
45
45
  ```
46
46
 
47
47
  - **워크스페이스마다 OAuth 클라이언트 하나.** 워크스페이스를 연결하면 서버가 Notion MCP 서버에 클라이언트로 등록하고(Dynamic Client Registration), PKCE로 로그인하고, 임시 `localhost` 포트로 인증 결과를 받습니다.
48
48
  - **고른 워크스페이스를 확인합니다.** 로그인 직후 `notion-get-self`를 호출해 실제 워크스페이스 이름과 ID를 기록합니다. 이미 연결된 워크스페이스를 또 고르면 거부합니다.
49
49
  - **공식 도구를 한 번만 노출합니다.** 도구마다 필수 파라미터 `workspace` 하나가 더 붙습니다. 이 파라미터에 넣을 수 있는 값은 그 도구가 있는 워크스페이스뿐이라, 요금제에 따라 없는 도구가 엉뚱한 워크스페이스로 가지 않습니다. 그 밖의 호출 내용과 결과는 손대지 않고 그대로 전달합니다.
50
- - **연결된 워크스페이스를 Claude에게 알려 줍니다.** 서버 안내문(instructions)에 각 워크스페이스의 별칭, 실제 이름, 설명을 넣습니다. 워크스페이스가 불분명하면 쓰기 전에 사용자에게 물으라는 내용도 넣고, 그 뒤에 Notion 공식 안내문을 붙입니다.
50
+ - **Notion의 이름을 그대로 씁니다.** 워크스페이스는 로그인 직후 받아 온 Notion에서의 이름으로 불립니다. 따로 이름을 지을 필요가 없고, 이름과 실제 워크스페이스가 어긋날 일도 없습니다. 연결된 워크스페이스 두 개의 이름이 같으면, 뒤에 연결한 쪽에 `허 은서의 Notion (bc2300ea)`처럼 ID 앞부분이 붙습니다.
51
+ - **연결된 워크스페이스를 Claude에게 알려 줍니다.** 서버 안내문(instructions)에 각 워크스페이스의 이름과 설명을 넣습니다. 워크스페이스가 불분명하면 쓰기 전에 사용자에게 물으라는 내용도 넣고, 그 뒤에 Notion 공식 안내문을 붙입니다.
51
52
 
52
53
  Claude가 보내는 호출은 이런 모양입니다.
53
54
 
54
55
  ```json
55
- { "name": "notion-search", "arguments": { "workspace": "work", "query": "roadmap" } }
56
+ { "name": "notion-search", "arguments": { "workspace": "회사", "query": "roadmap" } }
56
57
  ```
57
58
 
58
59
  ## 필요한 것
@@ -75,36 +76,35 @@ claude plugin install multi-workspace@multi-workspace-for-notion
75
76
  Claude Code 세션을 새로 연 뒤 워크스페이스마다 연결합니다.
76
77
 
77
78
  ```
78
- /multi-workspace:workspace-add personal 개인 메모
79
- /multi-workspace:workspace-add work 회사 위키
79
+ /multi-workspace:workspace-add 개인 메모
80
+ /multi-workspace:workspace-add 회사 위키
80
81
  ```
81
82
 
82
- 브라우저에 Notion 로그인 화면이 열리면, 이 별칭으로 연결할 워크스페이스를 골라 승인하세요. 그러면 Claude가 실제로 연결된 워크스페이스를 알려 줍니다. 의도한 워크스페이스가 아니면 지우고 다시 추가하세요. 새로 연결한 워크스페이스의 도구는 다음 대화부터 보입니다.
83
+ 브라우저에 Notion 로그인 화면이 열리면, 연결할 워크스페이스를 골라 승인하세요. 그 워크스페이스는 Notion에서의 이름으로 불립니다. 브라우저가 안 열렸을 때를 위해 Claude가 로그인 링크도 보여 줍니다. 승인했다고 Claude에게 말하면 실제로 연결된 워크스페이스를 알려 줍니다. 의도한 워크스페이스가 아니면 지우고 다시 추가하세요. 새 워크스페이스는 같은 대화에서 바로 쓸 수 있습니다.
83
84
 
84
- - 별칭은 영어 소문자나 숫자로 시작하고, 영어 소문자·숫자·`-`·`_`만 쓸 수 있습니다(최대 32자).
85
85
  - 설명은 넣지 않아도 됩니다. Claude가 이 설명을 보고 워크스페이스를 고르므로, 그 워크스페이스에 무엇이 있는지 몇 마디 적어 두면 도움이 됩니다.
86
86
  - 로그인은 최대 10분까지 기다립니다.
87
+ - 별칭을 직접 붙이던 0.1.x에서 올라오면, 처음 시작할 때 기존 연결이 Notion 워크스페이스 이름으로 자동으로 바뀝니다. 다시 로그인할 필요는 없습니다.
87
88
 
88
89
  claude.ai Notion 커넥터도 켜져 있으면 Claude에게 Notion 도구가 두 벌 보입니다. 이 플러그인을 쓰는 곳에서는 그 커넥터를 꺼서 Claude가 헷갈리지 않게 하세요.
89
90
 
90
- 그다음에는 평소 말투로 요청하면 됩니다. 예를 들어 "회사 노션과 개인 노션에서 각각 '로드맵'을 검색해 줘"라고 하면, Claude가 별칭과 설명을 보고 `workspace` 값을 고릅니다.
91
+ 그다음에는 평소 말투로 요청하면 됩니다. 예를 들어 "회사 노션과 개인 노션에서 각각 '로드맵'을 검색해 줘"라고 하면, Claude가 워크스페이스 이름과 설명을 보고 `workspace` 값을 고릅니다.
91
92
 
92
93
  ## 스킬
93
94
 
94
95
  | 스킬 | 하는 일 |
95
96
  | --- | --- |
96
97
  | `/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 [별칭]` | 저장된 토큰으로 다시 로그인해서, 워크스페이스가 아직 동작하는지와 처음 연결한 그 워크스페이스가 맞는지 확인합니다. |
98
+ | `/multi-workspace:workspace-add [설명]` | 브라우저로 워크스페이스를 연결하고, 실제로 어느 워크스페이스를 골랐는지 보여줍니다. |
99
+ | `/multi-workspace:workspace-remove <이름>` | 확인을 받은 뒤, 이 컴퓨터에서 그 워크스페이스의 토큰과 설정을 지우고 Notion 쪽 토큰도 해제합니다. |
100
+ | `/multi-workspace:workspace-check [이름]` | 저장된 토큰으로 다시 로그인해서, 워크스페이스가 아직 동작하는지와 처음 연결한 그 워크스페이스가 맞는지 확인합니다. |
101
101
  | `/multi-workspace:workspace-help` | 스킬, 도구, 요청 예를 한 화면에 보여줍니다. |
102
102
 
103
103
  `workspace-add`와 `workspace-remove`는 직접 입력했을 때만 실행됩니다. Claude가 알아서 실행하지 않습니다.
104
104
 
105
- 새 세션을 열 때마다 `Notion: personal(허 은서의 Notion), work(회사)`처럼 연결 상태가 한 줄로 표시되고, 확인이 필요한 워크스페이스가 있으면 `workspace-check`를 안내합니다.
105
+ 새 세션을 열 때마다 `Notion: 허 은서의 Notion, 회사`처럼 연결 상태가 한 줄로 표시되고, 확인이 필요한 워크스페이스가 있으면 `workspace-check`를 안내합니다.
106
106
 
107
- ## Claude Desktop 확장(`.mcpb`, 아직 시험 전)
107
+ ## Claude Desktop 확장(`.mcpb`)
108
108
 
109
109
  [최신 릴리스](https://github.com/heoeunseo08/multi-workspace-for-notion/releases/latest)에서 `multi-workspace-for-notion.mcpb`를 받거나, 직접 빌드합니다.
110
110
 
@@ -113,7 +113,7 @@ npm install
113
113
  npm run pack:mcpb # multi-workspace-for-notion.mcpb 생성
114
114
  ```
115
115
 
116
- 이 파일을 Claude Desktop으로 열어 설치한 뒤, Claude에게 워크스페이스를 연결해 달라고 하면 됩니다(`workspace_connect`). Desktop에는 플러그인 스킬이 없으니 도구를 바로 씁니다. 아직 Claude Desktop에서 시험하지 않은 방법입니다.
116
+ 이 파일을 Claude Desktop으로 열어 설치한 뒤, Claude에게 워크스페이스를 연결해 달라고 하면 됩니다(`workspace_connect`). Desktop에는 플러그인 스킬이 없으니 도구를 바로 씁니다.
117
117
 
118
118
  ## 소스에서 설치
119
119
 
@@ -124,8 +124,8 @@ git clone https://github.com/heoeunseo08/multi-workspace-for-notion.git
124
124
  cd multi-workspace-for-notion
125
125
  npm install
126
126
  npm run build
127
- node dist/index.js add personal "개인 메모"
128
- claude mcp add --scope user multi-workspace -- node /absolute/path/to/multi-workspace-for-notion/dist/index.js
127
+ node plugin/server.mjs add "개인 메모"
128
+ claude mcp add --scope user multi-workspace -- node /absolute/path/to/multi-workspace-for-notion/plugin/server.mjs
129
129
  ```
130
130
 
131
131
  그다음 `claude mcp list`에서 `multi-workspace`가 연결됐는지 확인하세요.
@@ -134,12 +134,11 @@ claude mcp add --scope user multi-workspace -- node /absolute/path/to/multi-work
134
134
 
135
135
  | 명령 | 하는 일 |
136
136
  | --- | --- |
137
- | `node dist/index.js` | MCP 서버를 stdio로 실행합니다. Claude가 실행하는 명령이라 직접 쓸 일은 없습니다. |
138
- | `node dist/index.js list` | 연결된 워크스페이스 목록을 보여줍니다: 별칭, 실제 워크스페이스 이름, 상태, 설명 |
139
- | `node dist/index.js add <별칭> [설명...]` | 브라우저 로그인으로 워크스페이스를 연결합니다. |
140
- | `node dist/index.js tools <별칭>` | 저장된 토큰으로 붙어서 워크스페이스를 확인하고 도구 목록을 보여줍니다. 연결이 아직 살아 있는지 확인할 때 씁니다. |
141
- | `node dist/index.js rename <별칭> <새 별칭>` | 다시 로그인하지 않고 별칭을 바꿉니다. |
142
- | `node dist/index.js remove <별칭>` | 이 컴퓨터에서 워크스페이스의 토큰과 설정을 지우고 Notion 쪽 토큰도 해제합니다. |
137
+ | `node plugin/server.mjs` | MCP 서버를 stdio로 실행합니다. Claude가 실행하는 명령이라 직접 쓸 일은 없습니다. |
138
+ | `node plugin/server.mjs list` | 연결된 워크스페이스 목록을 보여줍니다: 이름, 상태, 설명 |
139
+ | `node plugin/server.mjs add [설명...]` | 브라우저 로그인으로 워크스페이스를 연결합니다. |
140
+ | `node plugin/server.mjs tools <이름>` | 저장된 토큰으로 붙어서 워크스페이스를 확인하고 도구 목록을 보여줍니다. 연결이 아직 살아 있는지 확인할 때 씁니다. |
141
+ | `node plugin/server.mjs remove <이름>` | 이 컴퓨터에서 워크스페이스의 토큰과 설정을 지우고 Notion 쪽 토큰도 해제합니다. |
143
142
 
144
143
  ## Claude에게 보이는 도구
145
144
 
@@ -147,18 +146,17 @@ claude mcp add --scope user multi-workspace -- node /absolute/path/to/multi-work
147
146
  | --- | --- |
148
147
  | 모든 공식 Notion 도구 | 이름, 설명, 옵션은 그대로이고 필수 파라미터 `workspace`가 하나 붙습니다. 읽기 도구가 그 워크스페이스에서 ID를 찾지 못하면 다른 워크스페이스에서 다시 시도하고, 어느 워크스페이스에서 찾았는지 알려 줍니다. 쓰기 도구는 고르지 않은 워크스페이스로 보내지 않습니다. |
149
148
  | `search_all_workspaces` | 모든 워크스페이스에서 `notion-search`를 동시에 실행하고 결과를 워크스페이스별로 묶어 보여줍니다. 워크스페이스가 둘 이상 연결돼 있을 때만 보입니다. |
150
- | `workspace_list` | 연결된 워크스페이스를 보여줍니다: 별칭, 설명, 실제 워크스페이스 이름과 ID, 상태, 연결을 마지막으로 확인한 시각 |
151
- | `workspace_connect` | 브라우저로 워크스페이스를 연결합니다(최대 10분 기다림). |
149
+ | `workspace_list` | 연결된 워크스페이스를 보여줍니다: 이름, ID, 설명, 상태, 연결을 마지막으로 확인한 시각 |
150
+ | `workspace_connect` | 워크스페이스 연결을 시작하고 로그인 링크를 바로 돌려줍니다. 다시 부르면 결과를 받습니다(로그인은 최대 10분 기다림). |
152
151
  | `workspace_disconnect` | 이 컴퓨터에서 워크스페이스의 토큰과 설정을 지우고 Notion 쪽 토큰도 해제합니다. 되돌릴 수 없는 작업으로 표시돼 있어 Claude가 먼저 확인을 받습니다. |
153
- | `workspace_rename` | 다시 로그인하지 않고 별칭이나 설명을 바꿉니다. 새 별칭은 새 대화부터 쓸 수 있습니다. |
154
152
  | `workspace_check` | 저장된 토큰으로 다시 로그인해서 워크스페이스를 확인하고 상태를 갱신합니다. |
155
153
 
156
154
  ## 데이터 저장 위치
157
155
 
158
156
  | 무엇 | 어디 |
159
157
  | --- | --- |
160
- | OAuth 토큰과 클라이언트 등록 정보 | macOS 키체인. 서비스 `multi-workspace-for-notion`, 계정 `workspace:<별칭>` |
161
- | 별칭, 설명, 실제 워크스페이스 이름과 ID | `~/.config/multi-workspace-for-notion/config.json` |
158
+ | OAuth 토큰과 클라이언트 등록 정보 | macOS 키체인. 서비스 `multi-workspace-for-notion`, 계정 `workspace:<워크스페이스 ID>` |
159
+ | 워크스페이스 이름, ID, 설명 | `~/.config/multi-workspace-for-notion/config.json` |
162
160
  | 도구 목록과 안내문 캐시 | `~/.config/multi-workspace-for-notion/cache/` |
163
161
  | 토큰 저장용 잠금 파일 | `~/.config/multi-workspace-for-notion/locks/` |
164
162
 
@@ -174,10 +172,8 @@ claude mcp add --scope user multi-workspace -- node /absolute/path/to/multi-work
174
172
  ## 알려진 제약
175
173
 
176
174
  - **claude.ai 웹과 모바일에서는 쓸 수 없습니다.** 웹과 모바일의 커스텀 커넥터는 원격 URL만 받습니다.
177
- - **Claude Desktop은 아직 시험하지 않았습니다.**
178
175
  - **macOS만 지원합니다.** 키체인을 쓰기 때문입니다.
179
- - **새로 연결한 워크스페이스는 새 대화부터 보입니다.** Claude가 대화마다 도구 목록을 캐시합니다.
180
- - **다른 세션이 토큰을 갱신하는 도중에 별칭을 바꾸면** 새 별칭에 Notion이 이미 바꾼 refresh 토큰이 남을 수 있습니다. 인증 저장, 별칭 변경, 연결 해제는 같은 잠금을 쓰므로 갱신 요청 자체가 별칭 변경과 겹칠 때만 생깁니다. 생기면 `workspace-check`가 알려 주고, 그 워크스페이스를 다시 연결해야 합니다.
176
+ - **이미 열려 있는 다른 세션은 다시 시작해야 바뀐 워크스페이스를 봅니다.** 연결과 해제는 그 작업을 한 세션에서는 바로 반영되지만, 동시에 떠 있는 다른 세션은 다시 시작할 때까지 예전 목록을 씁니다.
181
177
  - **MCP resources와 prompts는 넘겨주지 않습니다.** Notion의 `notion://docs/...` 문서는 `notion-fetch`로 읽을 수 있고, 서버가 Claude에게 그렇게 하라고 안내합니다.
182
178
  - **시작할 때 워크스페이스마다 도구 목록을 받습니다**(워크스페이스 2개 기준 약 1초). 15초 안에 받지 못한 워크스페이스는 마지막으로 캐시해 둔 목록을 씁니다.
183
179
 
@@ -187,7 +183,7 @@ claude mcp add --scope user multi-workspace -- node /absolute/path/to/multi-work
187
183
  | --- | --- |
188
184
  | 워크스페이스 추가가 시간 초과로 끝남 | 로그인 화면이 실제로 열렸는지 확인하세요. CLI로 추가할 때는 출력된 주소로 직접 들어가 10분 안에 승인할 수 있습니다. |
189
185
  | 다른 워크스페이스가 연결됨 | 지우고 다시 추가하면서 Notion 화면에서 맞는 워크스페이스를 고르세요. |
190
- | "이미 연결되어 있습니다" 오류 | 그 Notion 워크스페이스가 다른 별칭으로 이미 연결돼 있습니다. `/multi-workspace:workspace-list`로 확인하세요. |
186
+ | "이미 연결되어 있습니다" 오류 | 그 Notion 워크스페이스는 이미 연결돼 있습니다. `/multi-workspace:workspace-list`로 확인하세요. |
191
187
  | 인증이 만료됐다는 오류로 호출이 실패함 | `/multi-workspace:workspace-check`로 확인한 뒤, 그 워크스페이스를 지우고 다시 추가하세요. |
192
188
  | Claude가 엉뚱한 Notion 도구를 씀 | 이 플러그인을 쓰는 곳에서 claude.ai Notion 커넥터를 끄세요. |
193
189
 
@@ -196,14 +192,13 @@ claude mcp add --scope user multi-workspace -- node /absolute/path/to/multi-work
196
192
  - [x] 워크스페이스 연결 (DCR, PKCE, localhost 콜백, 키체인, 워크스페이스 확인)
197
193
  - [x] 공식 도구에 `workspace` 파라미터를 붙여 전달, 요금제에 따른 도구 차이 처리
198
194
  - [x] 워크스페이스 관리를 MCP 도구와 플러그인 스킬로: 연결, 해제, 확인
199
- - [x] `workspace_rename`: 다시 로그인하지 않고 별칭이나 설명 바꾸기
200
195
  - [x] `search_all_workspaces`: 모든 워크스페이스를 한 번에 검색하고 결과에 출처 표시
201
196
  - [x] 토큰 갱신에 파일 잠금을 걸어 여러 프로세스가 같은 워크스페이스를 안전하게 쓰기
202
197
  - [x] 페이지 ID로 하는 호출이 실패하면 그 페이지가 실제로 있는 워크스페이스로 다시 보내기
203
198
  - [x] 워크스페이스를 지울 때 Notion 쪽 접근 권한도 해제
204
199
  - [x] Claude Code 플러그인
205
200
  - [x] 패키징: npm 패키지는 의존성 없이 묶은 서버 하나만 담고, `npm run pack:mcpb`로 Claude Desktop 확장을 만든다
206
- - [ ] npm에 배포하고, Claude Desktop에서 확장 시험하기
201
+ - [x] npm에 배포하고, Claude Desktop에서 확장 시험하기
207
202
 
208
203
  ## 개발
209
204
 
@@ -211,7 +206,8 @@ claude mcp add --scope user multi-workspace -- node /absolute/path/to/multi-work
211
206
  npm install
212
207
  npm run typecheck
213
208
  npm test # 단위 테스트
214
- npm run build # dist/로 컴파일하고 plugin/server.mjs로 묶음
209
+ npm run build # src/를 plugin/server.mjs 하나로 묶음
210
+ npm run check:bundle # 커밋한 뒤: 커밋된 묶음 파일이 src/와 다르면 실패
215
211
  npm run dev # 소스에서 바로 MCP 서버(stdio) 실행
216
212
  npm run dev -- list # 소스에서 바로 CLI 실행
217
213
  npm run pack:mcpb # Claude Desktop 확장
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  <p align="center"><em>One Claude Code, every Notion workspace. The official tools, untouched.</em></p>
4
4
 
5
5
  <p align="center">
6
- <img src="https://img.shields.io/badge/version-0.1.1-111111?style=flat-square" alt="Version 0.1.1">
6
+ <img src="https://img.shields.io/badge/version-0.2.1-111111?style=flat-square" alt="Version 0.2.1">
7
7
  <img src="https://img.shields.io/badge/Claude%20Code-plugin-111111?style=flat-square" alt="Claude Code plugin">
8
8
  <img src="https://img.shields.io/badge/platform-macOS-111111?style=flat-square" alt="macOS">
9
9
  <img src="https://img.shields.io/badge/license-MIT-111111?style=flat-square" alt="MIT license">
@@ -15,7 +15,7 @@
15
15
 
16
16
  Use several Notion workspaces at the same time from Claude Code, with every tool the official Notion MCP server offers.
17
17
 
18
- > **Status: early development (v0.1.1).** 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).
18
+ > **Status: early development (v0.2.1).** Connecting workspaces and proxying the official tools work and have been tested with real workspaces in Claude Code and Claude Desktop. Several planned pieces are still missing; see [Roadmap](#roadmap) and [Known limitations](#known-limitations).
19
19
  >
20
20
  > This is an unofficial project. It is not affiliated with or endorsed by Notion Labs, Inc.
21
21
 
@@ -26,7 +26,7 @@ Notion's official MCP connector links one workspace per connection. To switch, y
26
26
  Claude Code does let you register that URL twice under different names, but:
27
27
 
28
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;
29
+ - you name each connection yourself, and 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
30
  - nothing works across workspaces, such as searching all of them at once.
31
31
 
32
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.
@@ -39,20 +39,21 @@ Claude Code
39
39
  ▼
40
40
  Multi-Workspace for Notion (local Node process)
41
41
  │ routes each call by its `workspace` argument
42
- ├──▶ mcp.notion.com [personal]
43
- ├──▶ mcp.notion.com [work]
42
+ ├──▶ mcp.notion.com [My Notion]
43
+ ├──▶ mcp.notion.com [Acme]
44
44
  └──▶ mcp.notion.com [...]
45
45
  ```
46
46
 
47
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
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
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.
50
+ - **Uses Notion's own names.** A workspace is called by its name in Notion, read right after sign-in, so there is nothing to name and nothing that can point at the wrong workspace. If two connected workspaces share a name, the second gets the start of its ID, such as `My Notion (bc2300ea)`.
51
+ - **Tells Claude what is connected.** The server's instructions list each workspace's name and description, ask Claude to confirm the workspace before writing when it is unclear, and then include Notion's own instructions.
51
52
 
52
53
  What Claude sends looks like this:
53
54
 
54
55
  ```json
55
- { "name": "notion-search", "arguments": { "workspace": "work", "query": "roadmap" } }
56
+ { "name": "notion-search", "arguments": { "workspace": "Acme", "query": "roadmap" } }
56
57
  ```
57
58
 
58
59
  ## Requirements
@@ -75,36 +76,35 @@ The repository is private for now, so this works only for accounts that can read
75
76
  Start a new Claude Code session, then connect each workspace:
76
77
 
77
78
  ```
78
- /multi-workspace:workspace-add personal My personal notes
79
- /multi-workspace:workspace-add work Company wiki
79
+ /multi-workspace:workspace-add My personal notes
80
+ /multi-workspace:workspace-add Company wiki
80
81
  ```
81
82
 
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
+ Your browser opens Notion's sign-in page: choose the workspace you want and approve. It is then called by its name in Notion. Claude also shows the sign-in link, in case the browser didn't open. Tell Claude when you've approved; it then shows which workspace was actually connected. If it is not the one you meant, remove it and add it again. The new workspace works in the same conversation.
83
84
 
84
- - An alias starts with a lowercase letter or digit and may contain lowercase letters, digits, `-` and `_` (up to 32 characters).
85
85
  - The description is optional. Claude sees it, so a few words about what lives in the workspace help it choose.
86
86
  - Sign-in waits up to 10 minutes.
87
+ - Upgrading from 0.1.x, where you named each workspace yourself: on first start your connections are renamed after their Notion workspaces, without signing in again.
87
88
 
88
89
  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
 
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
+ Then ask in plain language, for example "Search for 'roadmap' in both my work and personal Notion". Claude picks the `workspace` value from the workspace names and descriptions.
91
92
 
92
93
  ## Skills
93
94
 
94
95
  | Skill | What it does |
95
96
  | --- | --- |
96
97
  | `/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. |
98
+ | `/multi-workspace:workspace-add [description]` | Connects a workspace through the browser and shows which workspace you actually picked. |
99
+ | `/multi-workspace:workspace-remove <name>` | Asks for confirmation, then deletes the workspace's tokens and settings from this computer and revokes the tokens on Notion's side. |
100
+ | `/multi-workspace:workspace-check [name]` | Signs in again with the saved tokens and checks each workspace still works and is the one you connected. |
101
101
  | `/multi-workspace:workspace-help` | Shows the skills, tools and example requests on one screen. |
102
102
 
103
103
  `workspace-add` and `workspace-remove` run only when you type them; Claude doesn't start them on its own.
104
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.
105
+ Each new session also starts with a one-line status, such as `Notion: My Notion, Acme`, and points you to `workspace-check` when a workspace needs attention.
106
106
 
107
- ## Claude Desktop extension (`.mcpb`, not tested yet)
107
+ ## Claude Desktop extension (`.mcpb`)
108
108
 
109
109
  Download `multi-workspace-for-notion.mcpb` from the [latest release](https://github.com/heoeunseo08/multi-workspace-for-notion/releases/latest), or build it yourself:
110
110
 
@@ -113,7 +113,7 @@ npm install
113
113
  npm run pack:mcpb # writes multi-workspace-for-notion.mcpb
114
114
  ```
115
115
 
116
- 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.
116
+ 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.
117
117
 
118
118
  ## Install from source
119
119
 
@@ -124,8 +124,8 @@ git clone https://github.com/heoeunseo08/multi-workspace-for-notion.git
124
124
  cd multi-workspace-for-notion
125
125
  npm install
126
126
  npm run build
127
- node dist/index.js add personal "My personal notes"
128
- claude mcp add --scope user multi-workspace -- node /absolute/path/to/multi-workspace-for-notion/dist/index.js
127
+ node plugin/server.mjs add "My personal notes"
128
+ claude mcp add --scope user multi-workspace -- node /absolute/path/to/multi-workspace-for-notion/plugin/server.mjs
129
129
  ```
130
130
 
131
131
  Then check that `multi-workspace` shows as connected in `claude mcp list`.
@@ -134,12 +134,11 @@ Then check that `multi-workspace` shows as connected in `claude mcp list`.
134
134
 
135
135
  | Command | What it does |
136
136
  | --- | --- |
137
- | `node dist/index.js` | Runs the MCP server over stdio. Claude runs this; you don't need to. |
138
- | `node dist/index.js list` | Lists connected workspaces: alias, real workspace name, status, description. |
139
- | `node dist/index.js add <alias> [description...]` | Connects a workspace through the browser. |
140
- | `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. |
141
- | `node dist/index.js rename <alias> <new-alias>` | Changes an alias without signing in again. |
142
- | `node dist/index.js remove <alias>` | Deletes the workspace's tokens and settings from this computer and revokes the tokens on Notion's side. |
137
+ | `node plugin/server.mjs` | Runs the MCP server over stdio. Claude runs this; you don't need to. |
138
+ | `node plugin/server.mjs list` | Lists connected workspaces: name, status, description. |
139
+ | `node plugin/server.mjs add [description...]` | Connects a workspace through the browser. |
140
+ | `node plugin/server.mjs tools <name>` | Signs in with the saved tokens, confirms the workspace, and lists its tools. Useful to check a connection still works. |
141
+ | `node plugin/server.mjs remove <name>` | Deletes the workspace's tokens and settings from this computer and revokes the tokens on Notion's side. |
143
142
 
144
143
  CLI messages are currently in Korean.
145
144
 
@@ -149,18 +148,17 @@ CLI messages are currently in Korean.
149
148
  | --- | --- |
150
149
  | 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. |
151
150
  | `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. |
152
- | `workspace_list` | Shows the connected workspaces: alias, description, real workspace name and ID, status, and when the connection was last confirmed. |
153
- | `workspace_connect` | Connects a workspace through the browser (waits up to 10 minutes). |
151
+ | `workspace_list` | Shows the connected workspaces: name, ID, description, status, and when the connection was last confirmed. |
152
+ | `workspace_connect` | Starts connecting a workspace and returns the sign-in link at once; call it again for the result (sign-in waits up to 10 minutes). |
154
153
  | `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. |
155
- | `workspace_rename` | Changes an alias or description without signing in again. A new alias is usable from the next conversation. |
156
154
  | `workspace_check` | Signs in again with the saved tokens, confirms the workspace and updates its status. |
157
155
 
158
156
  ## Where data is stored
159
157
 
160
158
  | What | Where |
161
159
  | --- | --- |
162
- | OAuth tokens and client registration | macOS Keychain, service `multi-workspace-for-notion`, account `workspace:<alias>` |
163
- | Aliases, descriptions, real workspace names and IDs | `~/.config/multi-workspace-for-notion/config.json` |
160
+ | OAuth tokens and client registration | macOS Keychain, service `multi-workspace-for-notion`, account `workspace:<workspace ID>` |
161
+ | Workspace names, IDs and descriptions | `~/.config/multi-workspace-for-notion/config.json` |
164
162
  | Cached tool lists and instructions | `~/.config/multi-workspace-for-notion/cache/` |
165
163
  | Lock files for saving tokens | `~/.config/multi-workspace-for-notion/locks/` |
166
164
 
@@ -176,10 +174,8 @@ Set `MWN_CONFIG_DIR` to use a different directory; point it at a private, owner-
176
174
  ## Known limitations
177
175
 
178
176
  - **claude.ai web and mobile are not supported.** Their custom connectors accept only remote URLs.
179
- - **Claude Desktop is not tested yet.**
180
177
  - **macOS only**, because of the Keychain.
181
- - **A newly connected workspace appears in new conversations.** Claude caches the tool list per conversation.
182
- - **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.
178
+ - **Other open sessions see workspace changes after a restart.** A connect or disconnect takes effect at once in the session that made it; other running sessions keep their old list until they restart.
183
179
  - **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.
184
180
  - **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.
185
181
 
@@ -189,7 +185,7 @@ Set `MWN_CONFIG_DIR` to use a different directory; point it at a private, owner-
189
185
  | --- | --- |
190
186
  | 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. |
191
187
  | The wrong workspace was connected | Remove it, then add it again and choose the right workspace on Notion's page. |
192
- | "already connected" | That Notion workspace is already linked under another alias. Check with `/multi-workspace:workspace-list`. |
188
+ | "already connected" | That Notion workspace is already connected. Check with `/multi-workspace:workspace-list`. |
193
189
  | Calls fail with an expired-sign-in error | Run `/multi-workspace:workspace-check`, then remove and add the workspace again. |
194
190
  | Claude uses the wrong Notion tools | Turn off the claude.ai Notion connector where you use this plugin. |
195
191
 
@@ -198,14 +194,13 @@ Set `MWN_CONFIG_DIR` to use a different directory; point it at a private, owner-
198
194
  - [x] Connect workspaces (DCR, PKCE, localhost callback, Keychain, workspace check)
199
195
  - [x] Proxy the official tools with a `workspace` parameter and per-plan availability
200
196
  - [x] Workspace management as MCP tools and plugin skills: connect, disconnect, check
201
- - [x] `workspace_rename`: change an alias or description without signing in again
202
197
  - [x] `search_all_workspaces`: search every workspace at once, results labelled by workspace
203
198
  - [x] File lock around token refresh so several processes can share a workspace safely
204
199
  - [x] Retry calls that use a page ID in the workspace that actually owns the page
205
200
  - [x] Revoke access on Notion's side when removing a workspace
206
201
  - [x] Claude Code plugin
207
202
  - [x] Packaging: the npm package ships only the bundled server, with no dependencies; `npm run pack:mcpb` builds a Claude Desktop extension
208
- - [ ] Publish to npm, and test the extension in Claude Desktop
203
+ - [x] Publish to npm, and test the extension in Claude Desktop
209
204
 
210
205
  ## Development
211
206
 
@@ -213,7 +208,8 @@ Set `MWN_CONFIG_DIR` to use a different directory; point it at a private, owner-
213
208
  npm install
214
209
  npm run typecheck
215
210
  npm test # unit tests
216
- npm run build # compiles to dist/ and bundles plugin/server.mjs
211
+ npm run build # bundles src/ into plugin/server.mjs
212
+ npm run check:bundle # after committing: fails if the committed bundle doesn't match src/
217
213
  npm run dev # MCP server over stdio, from source
218
214
  npm run dev -- list # CLI, from source
219
215
  npm run pack:mcpb # Claude Desktop extension
package/package.json CHANGED
@@ -1,15 +1,14 @@
1
1
  {
2
2
  "name": "multi-workspace-for-notion",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "scripts": {
5
5
  "dev": "tsx src/index.ts",
6
6
  "typecheck": "tsc --noEmit",
7
- "build": "tsc -p tsconfig.build.json && npm run bundle",
8
- "start": "node dist/index.js",
7
+ "build": "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);\"",
9
8
  "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
9
  "pack:mcpb": "npm run build && npx -y @anthropic-ai/mcpb@2 pack . multi-workspace-for-notion.mcpb",
12
- "prepublishOnly": "npm run build"
10
+ "prepublishOnly": "npm run build",
11
+ "check:bundle": "npm run build && git diff --exit-code --stat plugin/server.mjs"
13
12
  },
14
13
  "type": "module",
15
14
  "devDependencies": {