mmm-mcp-server 0.1.0 → 0.1.2
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.en.md +228 -0
- package/README.md +28 -60
- package/dist/src/domain/levels.js +3 -1
- package/dist/src/domain/levelsMode.js +8 -7
- package/dist/src/server.js +1 -1
- package/dist/src/tools/autoStructureThought.js +1 -1
- package/dist/src/tools/deleteElements.js +8 -4
- package/dist/src/tools/editElement.js +1 -1
- package/dist/src/tools/importMarkdownContext.js +1 -1
- package/dist/src/tools/listElements.js +6 -1
- package/dist/src/tools/moveElement.js +7 -3
- package/dist/src/tools/updateTaskStatus.js +1 -1
- package/package.json +2 -1
package/README.en.md
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# mmm-mcp-server
|
|
2
|
+
|
|
3
|
+
[日本語](README.md) | English
|
|
4
|
+
|
|
5
|
+
A tool that lets you read and write your own maps in Matryoshka Mind Map (a mind map / TODO app) directly from conversations with AI agents. Because it is built on the Model Context Protocol (MCP) open standard, it works with any MCP-compatible AI agent, not just Claude Desktop and Claude Code (**tested on Claude Desktop and Claude Code**; for other clients, see their documentation on how to register an MCP server).
|
|
6
|
+
|
|
7
|
+
- Say "Show me my current maps" and it lists your maps.
|
|
8
|
+
- Turn ideas from your conversation directly into a hierarchical mind map.
|
|
9
|
+
- Just say "I finished task X" to check it off your TODO list.
|
|
10
|
+
- Import long notes or Markdown straight into a map.
|
|
11
|
+
|
|
12
|
+
This tool runs entirely on your computer, with no always-on server. It starts only when needed and accesses your own maps with your own login credentials (the developer cannot see your data).
|
|
13
|
+
|
|
14
|
+
> **For users who installed via `git clone` before September 30, 2026**: Due to a data format migration in the app, older versions will fail when writing to maps. Please replace the registration in Step 5 below with `npx -y mmm-mcp-server` (you do not need to log in again). If you want to keep using your cloned copy, run `git pull && npm install && npm run build` in the `mmm_mcp` folder and restart your AI agent.
|
|
15
|
+
|
|
16
|
+
> This guide walks you through every step, starting with how to open the terminal (the window where you type commands), so that you can follow along even if you are not used to working with a computer.
|
|
17
|
+
>
|
|
18
|
+
> **Supported OS**: It should work on both macOS and Windows. It runs purely on Node.js and does not depend on OS-specific features. However, **it has only been tested on real machines running macOS.** If you notice anything while trying it on Windows, please let us know via an Issue in this repository. Steps that differ by OS (opening the terminal and installing Node.js) are described separately for macOS and Windows. All other commands are the same on both.
|
|
19
|
+
|
|
20
|
+
## 1. Prerequisites
|
|
21
|
+
|
|
22
|
+
- A Matryoshka Mind Map account (**anonymous-only accounts cannot be used.** Make sure you can log in with Google, Apple, or an email address. You can also link one later with the "Link email address" feature in the app).
|
|
23
|
+
- An MCP-compatible AI agent (tested with Claude Desktop / Claude Code; other MCP-compatible clients should generally work too).
|
|
24
|
+
- Node.js (the runtime that runs the tool; you will install it in Step 3).
|
|
25
|
+
|
|
26
|
+
## 2. Open the Terminal
|
|
27
|
+
|
|
28
|
+
### On macOS
|
|
29
|
+
|
|
30
|
+
1. Press `Command` + `Space` on your keyboard (opens Spotlight search).
|
|
31
|
+
2. Type "Terminal".
|
|
32
|
+
3. Click "Terminal" in the results, or press Enter.
|
|
33
|
+
|
|
34
|
+
### On Windows
|
|
35
|
+
|
|
36
|
+
1. Press the `Windows` key on your keyboard (opens Start menu search).
|
|
37
|
+
2. Type "PowerShell".
|
|
38
|
+
3. Click "Windows PowerShell" in the results, or press Enter.
|
|
39
|
+
|
|
40
|
+
Once a dark (or light) window opens, you are ready. For the rest of the steps, paste the commands into this window one line at a time and press Enter (the commands themselves are the same on macOS and Windows).
|
|
41
|
+
|
|
42
|
+
## 3. Install Node.js
|
|
43
|
+
|
|
44
|
+
Check whether Node.js is already installed with this command:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
node --version
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
If a version number of `v18` or higher is displayed (e.g., `v20.11.0`), it is already installed. If you see an error like "command not found", download the installer from:
|
|
51
|
+
|
|
52
|
+
https://nodejs.org/
|
|
53
|
+
|
|
54
|
+
The site shows two large buttons. Click the one labeled **"LTS"** to download (the `.pkg` installer for macOS or the `.msi` installer for Windows is chosen automatically for your OS). Double-click the downloaded file and follow the on-screen instructions (on macOS: "Continue" → "Agree" → "Install"; on Windows: "Next" → "I accept..." → "Install").
|
|
55
|
+
|
|
56
|
+
When the installation is finished, go back to the terminal and check again:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
node --version
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 4. Log In
|
|
63
|
+
|
|
64
|
+
Choose one of the following three options based on how you usually log in to the Matryoshka Mind Map app. **None of these methods require any setup on your part beforehand.** The first run downloads the tool, so it may take a moment.
|
|
65
|
+
|
|
66
|
+
### If you log in with Google
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npx -y -p mmm-mcp-server mmm-login login --method google
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Your browser opens automatically; log in with the Google account you usually use.
|
|
73
|
+
|
|
74
|
+
### If you log in with Apple
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npx -y -p mmm-mcp-server mmm-login login --method apple
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Your browser opens automatically; log in with your Apple ID.
|
|
81
|
+
|
|
82
|
+
### If you log in with an email address and password
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npx -y -p mmm-mcp-server mmm-login login --method email
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
You will be asked for your email address and password (the password is not shown on screen).
|
|
89
|
+
|
|
90
|
+
> **If you get a "wrong password" error**, it does not necessarily mean you mistyped your password. If your account signs in to the app with Google or Apple and has no email/password credentials at all, you get the same error. If that may be the case, try the "Google" or "Apple" steps above.
|
|
91
|
+
|
|
92
|
+
Once you have logged in, you do not need to log in again each time (your credentials are stored only on your computer, in a form that only you can read).
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npx -y -p mmm-mcp-server mmm-login status
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
shows your login status. To log out:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npx -y -p mmm-mcp-server mmm-login logout
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## 5. Register It with Your AI Agent
|
|
105
|
+
|
|
106
|
+
Below are the instructions for Claude Desktop and Claude Code, which have been tested. If you use another MCP-compatible client (e.g., Codex), in most cases you only need to register the server launch command (`npx -y mmm-mcp-server`) in that client's MCP server settings. See your client's documentation for the exact steps.
|
|
107
|
+
|
|
108
|
+
### Claude Code
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
claude mcp add mmm -- npx -y mmm-mcp-server
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Claude Desktop
|
|
115
|
+
|
|
116
|
+
Open the Claude Desktop configuration file (`claude_desktop_config.json`) and add the following under `mcpServers`:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"mcpServers": {
|
|
121
|
+
"mmm": {
|
|
122
|
+
"command": "npx",
|
|
123
|
+
"args": ["-y", "mmm-mcp-server"]
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Save the file and restart Claude Desktop.
|
|
130
|
+
|
|
131
|
+
## 6. Try It Out
|
|
132
|
+
|
|
133
|
+
Try talking to your AI agent like this:
|
|
134
|
+
|
|
135
|
+
- "Show me my Matryoshka maps."
|
|
136
|
+
- "Add a task called [task] to the [map name] map."
|
|
137
|
+
- "I finished the [task] task in the [map name] map."
|
|
138
|
+
- "I'll paste my notes in Markdown; import them into the [map name] map."
|
|
139
|
+
|
|
140
|
+
**Only the first time the contents of a map (the element text) are read**, the tool asks for your permission before returning the actual contents. This is out of consideration for personal information that the contents may contain.
|
|
141
|
+
|
|
142
|
+
Instead of the contents, the tool returns only an instruction: "confirm directly with the user, then call again with `confirmed: true`." This is best-effort: the server has no way to verify whether the agent actually asked you, so whether the confirmation happens properly depends on the AI agent you use. Once confirmed, the same map is not confirmed again while that server is running (roughly one conversation).
|
|
143
|
+
|
|
144
|
+
(Previously, MCP's standard confirmation dialog, "elicitation", was also used to enforce this. However, some clients advertised support without actually showing a dialog, so contents became unreadable without the user ever seeing a confirmation screen. It was removed on 2026-09-03 in favor of the approach above.)
|
|
145
|
+
|
|
146
|
+
## Keeping Your Maps Tidy
|
|
147
|
+
|
|
148
|
+
Letting an AI agent write your maps is convenient, but left alone the maps tend to become hard to read. Paste the following into the instruction file your AI agent loads every time (for Claude Code, `~/.claude/CLAUDE.md`) to keep the writing style consistent:
|
|
149
|
+
|
|
150
|
+
```markdown
|
|
151
|
+
## How to write in mmm
|
|
152
|
+
|
|
153
|
+
- Keep each element short enough to read in one line. Do not pack in explanations.
|
|
154
|
+
If you want to keep reasons or notes, put them one level down as child elements.
|
|
155
|
+
- Put a URL in its own element. Do not mix it with text like "Docs here: https://...".
|
|
156
|
+
Create an element named "Docs" and put only the URL as its child.
|
|
157
|
+
- Order reminder items chronologically. Name them by when to do them, such as
|
|
158
|
+
"Right after release", "In 2 weeks", or "When X happens".
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
The reasons:
|
|
162
|
+
|
|
163
|
+
- **One line per element**: Matryoshka shows elements nested inside each other, so long elements hurt readability and lose the benefit of drilling down through the hierarchy.
|
|
164
|
+
- **Do not mix URLs with text**: A URL in the same element as other text is not treated as a link in the app, so tapping it does nothing.
|
|
165
|
+
- **Chronological order**: Compared with ordering by task name, checking items off in order makes it easier to notice anything you missed.
|
|
166
|
+
|
|
167
|
+
## Troubleshooting
|
|
168
|
+
|
|
169
|
+
| Symptom | Cause / Solution |
|
|
170
|
+
|---|---|
|
|
171
|
+
| `node --version` says "command not found" | Node.js from Step 3 is not installed yet. After installing, close the terminal and open it again. |
|
|
172
|
+
| "Wrong password" when logging in | See the note in Step 4. Try logging in with Google or Apple instead. |
|
|
173
|
+
| The agent does not operate on your maps when asked | Check that the registration in Step 5 is correct. Claude Desktop needs a restart after registration. |
|
|
174
|
+
| The agent will not show map contents / stops at the confirmation | Check that you answered "yes" when asked for permission to read. |
|
|
175
|
+
| The AI cannot load a large map | With several hundred elements or more, the `list_elements` response gets large and may not fit in one go. Some AI agents handle this by saving it to a file and reading only the parts they need. If it happens often, split the map (swiping left on a top-level element turns it and everything under it into a separate map). |
|
|
176
|
+
|
|
177
|
+
## Advanced Example: Recording Tasks per Folder Automatically
|
|
178
|
+
|
|
179
|
+
What follows is **just one example of how it can be used**. It is not a standard workflow recommended for everyone, but shows what becomes possible with this kind of setup. Feel free to ignore it if it does not suit you.
|
|
180
|
+
|
|
181
|
+
**Goal**: Pair each folder (project) you work on in Claude Code with a map of the same name, and have the AI agent record and update tasks that come up during work in that map in real time, without asking.
|
|
182
|
+
|
|
183
|
+
> Setting (2) below uses Claude Code's "global CLAUDE.md", an instruction file that is always loaded. If your AI agent has a similar feature for instructions loaded every time, the same idea should apply.
|
|
184
|
+
|
|
185
|
+
### Setup
|
|
186
|
+
|
|
187
|
+
**(1) Re-register the mmm server so it is available in every folder**
|
|
188
|
+
|
|
189
|
+
When registering with Claude Code in Step 5, the `mmm` tool is only available in the current folder by default. To use it no matter which folder you start `claude` in, register it with `--scope user`:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
claude mcp add mmm --scope user -- npx -y mmm-mcp-server
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**(2) Write the workflow rules in your global CLAUDE.md (`~/.claude/CLAUDE.md`)**
|
|
196
|
+
|
|
197
|
+
For example, add something like this:
|
|
198
|
+
|
|
199
|
+
```markdown
|
|
200
|
+
## Task management with mmm
|
|
201
|
+
|
|
202
|
+
Record tasks that come up in the working folder in mmm (the Matryoshka Mind Map
|
|
203
|
+
integration) and manage them in real time.
|
|
204
|
+
|
|
205
|
+
- Use the working folder name as the map title.
|
|
206
|
+
- Check with list_maps whether a map with the same name exists. If not, create it
|
|
207
|
+
right away with create_map(title=folder name, isTodo=true) without confirming
|
|
208
|
+
the title (confirmation is not required for this workflow only).
|
|
209
|
+
- Calling list_elements to see existing tasks asks for confirmation only the first
|
|
210
|
+
time the map is read in that process. After that, add and update tasks in real
|
|
211
|
+
time with auto_structure_thought / update_task_status.
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Why this works
|
|
215
|
+
|
|
216
|
+
- `create_map` takes the title directly as an argument; "confirm in the conversation before calling" is only a recommended behavior for AI agents written in the tool description. A more specific instruction in CLAUDE.md takes priority, so maps can be created automatically without confirmation.
|
|
217
|
+
- Only `list_elements`, which reads map contents, has confirmation enforced on the server side out of consideration for confidential information (see "Try It Out" above). This does not change with the per-folder workflow: confirmation happens once, the first time a map is read in that process.
|
|
218
|
+
|
|
219
|
+
### Caveats
|
|
220
|
+
|
|
221
|
+
- Maps are created automatically for every folder, so work-log style maps will mix in with your carefully curated mind maps. Some people may find this cluttered. Adjust it to suit you, for example by using a separate account or limiting it to certain folders.
|
|
222
|
+
- Skipping confirmation for `create_map` applies only when you spell out this workflow in your own CLAUDE.md. Without any setup, the agent confirms in the conversation before creating a map, as usual.
|
|
223
|
+
|
|
224
|
+
## About This Tool
|
|
225
|
+
|
|
226
|
+
- Your login credentials (refresh token) are stored only on your computer (macOS: `~/.config/mmm-mcp/credentials.json`, Windows: `C:\Users\<username>\.config\mmm-mcp\credentials.json`) and are never sent anywhere else.
|
|
227
|
+
- Your map contents are read from and written to your Firebase account directly, without going through any third-party server, including the developer's (only when logging in with Apple, the last step of login goes through a signing-only relay server, but your map contents never pass through it).
|
|
228
|
+
- There is no always-running process; it runs only while you are in a conversation with your AI agent.
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# mmm-mcp-server
|
|
2
2
|
|
|
3
|
+
日本語 | [English](README.en.md)
|
|
4
|
+
|
|
3
5
|
Matryoshka Mind Map(マトリョシカ、マインドマップ/TODOアプリ)の自分のマップを、
|
|
4
6
|
AIエージェントとの会話から直接読み書きできるようにするツールです。MCP
|
|
5
7
|
(Model Context Protocol)という共通規格に対応したツールなので、Claude
|
|
@@ -16,15 +18,17 @@ Desktop・Claude Codeに限らず、MCPに対応したAIエージェントであ
|
|
|
16
18
|
起動し、あなた自身のログイン情報であなた自身のマップにアクセスします(開発者側は
|
|
17
19
|
あなたのデータを見ることができません)。
|
|
18
20
|
|
|
19
|
-
> **2026年9月30
|
|
20
|
-
>
|
|
21
|
-
> `
|
|
21
|
+
> **2026年9月30日より前に `git clone` で導入した方へ**: アプリ側のデータ形式の
|
|
22
|
+
> 切り替えに伴い、古い版ではマップへの書き込みが失敗するようになります。下の手順5の
|
|
23
|
+
> 登録を `npx -y mmm-mcp-server` に置き換えてください(ログインし直す必要はありません)。
|
|
24
|
+
> clone したまま使い続ける場合は、`mmm_mcp` フォルダで `git pull && npm install && npm run build`
|
|
25
|
+
> を実行してからAIエージェントを再起動してください。
|
|
22
26
|
|
|
23
27
|
> このページは、ある程度パソコン操作に慣れていない方でも迷わず進められるよう、
|
|
24
28
|
> ターミナル(コマンドを打つ画面)の開き方から順に説明しています。
|
|
25
29
|
>
|
|
26
|
-
> **対応OS**: macOS・Windowsの両方で動作するはずです。Node.js
|
|
27
|
-
>
|
|
30
|
+
> **対応OS**: macOS・Windowsの両方で動作するはずです。Node.jsだけで動く
|
|
31
|
+
> ツールで、OS固有の機能には依存していません。ただし**実機での動作
|
|
28
32
|
> 確認はmacOSでのみ行っています。** Windowsで試して気づいた点があれば、
|
|
29
33
|
> このリポジトリのIssueで教えてください。手順のうち、操作方法がOSで
|
|
30
34
|
> 異なる箇所(ターミナルの開き方・Node.jsのインストール)はmacOS/Windows
|
|
@@ -85,42 +89,16 @@ https://nodejs.org/
|
|
|
85
89
|
node --version
|
|
86
90
|
```
|
|
87
91
|
|
|
88
|
-
## 4.
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
git clone https://github.com/nhorie-canal/mmm_mcp.git
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
コマンドの実行が終わったら、作られたフォルダに移動します。
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
cd mmm_mcp
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
## 5. セットアップする
|
|
101
|
-
|
|
102
|
-
必要な部品を取り込みます(少し時間がかかります)。
|
|
103
|
-
|
|
104
|
-
```bash
|
|
105
|
-
npm install
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
続けて、使える状態にビルドします。
|
|
109
|
-
|
|
110
|
-
```bash
|
|
111
|
-
npm run build
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
## 6. ログインする
|
|
92
|
+
## 4. ログインする
|
|
115
93
|
|
|
116
94
|
Matryoshka Mind Mapアプリで普段どのログイン方法を使っているかに合わせて、
|
|
117
95
|
次の3つから選んでください。**いずれの方法も、あなた自身が事前に何かを準備する
|
|
118
|
-
必要はありません。**
|
|
96
|
+
必要はありません。** 初回はツールのダウンロードが入るので、少し時間がかかります。
|
|
119
97
|
|
|
120
98
|
### Googleでログインしている場合
|
|
121
99
|
|
|
122
100
|
```bash
|
|
123
|
-
|
|
101
|
+
npx -y -p mmm-mcp-server mmm-login login --method google
|
|
124
102
|
```
|
|
125
103
|
|
|
126
104
|
ブラウザが自動で開くので、いつも使っているGoogleアカウントでログインします。
|
|
@@ -128,7 +106,7 @@ node dist/bin/login.js login --method google
|
|
|
128
106
|
### Appleでログインしている場合
|
|
129
107
|
|
|
130
108
|
```bash
|
|
131
|
-
|
|
109
|
+
npx -y -p mmm-mcp-server mmm-login login --method apple
|
|
132
110
|
```
|
|
133
111
|
|
|
134
112
|
こちらもブラウザが自動で開くので、Apple IDでログインします。
|
|
@@ -136,7 +114,7 @@ node dist/bin/login.js login --method apple
|
|
|
136
114
|
### メールアドレスとパスワードでログインしている場合
|
|
137
115
|
|
|
138
116
|
```bash
|
|
139
|
-
|
|
117
|
+
npx -y -p mmm-mcp-server mmm-login login --method email
|
|
140
118
|
```
|
|
141
119
|
|
|
142
120
|
メールアドレスとパスワードを聞かれるので入力してください(パスワードは
|
|
@@ -153,37 +131,27 @@ node dist/bin/login.js login --method email
|
|
|
153
131
|
あなたのパソコンの中だけに、あなた以外読めない形で保存されます)。
|
|
154
132
|
|
|
155
133
|
```bash
|
|
156
|
-
|
|
134
|
+
npx -y -p mmm-mcp-server mmm-login status
|
|
157
135
|
```
|
|
158
136
|
|
|
159
137
|
でログイン状態を確認できます。ログアウトしたい場合は次のコマンドです。
|
|
160
138
|
|
|
161
139
|
```bash
|
|
162
|
-
|
|
140
|
+
npx -y -p mmm-mcp-server mmm-login logout
|
|
163
141
|
```
|
|
164
142
|
|
|
165
|
-
##
|
|
143
|
+
## 5. AIエージェントにMatryoshkaを教える
|
|
166
144
|
|
|
167
145
|
ここでは動作確認済みのClaude Desktop / Claude Codeへの登録方法を示します。
|
|
168
146
|
他のMCP対応クライアント(例: Codexなど)を使っている場合も、多くは同じように
|
|
169
|
-
「サーバーを起動するコマンド」(`
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
このステップで、あなたが今どこのフォルダにいるかによって次のコマンドの一部が
|
|
174
|
-
変わります。次のコマンドで今いる場所(絶対パス)を確認してください。
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
pwd
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
表示された場所(例: `/Users/あなたの名前/mmm_mcp`)を、以下の
|
|
181
|
-
`<mmm_mcpのパス>`の部分に置き換えて使います。
|
|
147
|
+
「サーバーを起動するコマンド」(`npx -y mmm-mcp-server`)をそのクライアントの
|
|
148
|
+
MCPサーバー設定に登録するだけで使えるはずです。具体的な登録方法はお使いの
|
|
149
|
+
クライアントのドキュメントを確認してください。
|
|
182
150
|
|
|
183
151
|
### Claude Codeを使っている場合
|
|
184
152
|
|
|
185
153
|
```bash
|
|
186
|
-
claude mcp add mmm --
|
|
154
|
+
claude mcp add mmm -- npx -y mmm-mcp-server
|
|
187
155
|
```
|
|
188
156
|
|
|
189
157
|
### Claude Desktopを使っている場合
|
|
@@ -195,8 +163,8 @@ Claude Desktopの設定ファイル(`claude_desktop_config.json`)を開き
|
|
|
195
163
|
{
|
|
196
164
|
"mcpServers": {
|
|
197
165
|
"mmm": {
|
|
198
|
-
"command": "
|
|
199
|
-
"args": ["
|
|
166
|
+
"command": "npx",
|
|
167
|
+
"args": ["-y", "mmm-mcp-server"]
|
|
200
168
|
}
|
|
201
169
|
}
|
|
202
170
|
}
|
|
@@ -204,7 +172,7 @@ Claude Desktopの設定ファイル(`claude_desktop_config.json`)を開き
|
|
|
204
172
|
|
|
205
173
|
保存したらClaude Desktopを再起動してください。
|
|
206
174
|
|
|
207
|
-
##
|
|
175
|
+
## 6. 使ってみる
|
|
208
176
|
|
|
209
177
|
AIエージェントとの会話で、次のように話しかけてみてください。
|
|
210
178
|
|
|
@@ -260,8 +228,8 @@ AIエージェントに任せると楽な反面、そのままだと読みにく
|
|
|
260
228
|
| 症状 | 原因・対処 |
|
|
261
229
|
|---|---|
|
|
262
230
|
| `node --version`が「command not found」になる | 手順3のNode.jsインストールがまだ。インストール後、ターミナルを一度閉じて開き直す |
|
|
263
|
-
| ログイン時に「パスワードが違います」と出る | 手順
|
|
264
|
-
| 話しかけてもマップ操作をしてくれない | 手順
|
|
231
|
+
| ログイン時に「パスワードが違います」と出る | 手順4の補足を参照。Google/Appleでログインし直してみる |
|
|
232
|
+
| 話しかけてもマップ操作をしてくれない | 手順5の登録が正しいか確認する。Claude Desktopは登録後に再起動が必要 |
|
|
265
233
|
| マップの中身を教えてくれない・確認だけで止まる | 「読んでいいですか」の確認に「はい」と答えているか確認する |
|
|
266
234
|
| 大きなマップをAIが読み込めない | 要素が数百を超えると`list_elements`の応答が大きくなり、一度に受け取れないことがある。AIエージェントによっては、いったんファイルに保存して必要な部分だけ読む形で対応する。頻繁に起きるならマップを分ける(最上位の要素を左スワイプすると、配下ごと独立したマップになる) |
|
|
267
235
|
|
|
@@ -284,12 +252,12 @@ AIエージェントに任せると楽な反面、そのままだと読みにく
|
|
|
284
252
|
|
|
285
253
|
**(1) mmmサーバーを全フォルダ共通で使えるように登録し直す**
|
|
286
254
|
|
|
287
|
-
手順
|
|
255
|
+
手順5でClaude Codeに登録するとき、そのままだと今いるフォルダでしか
|
|
288
256
|
`mmm`ツールが使えません。どのフォルダで`claude`を起動しても使えるように
|
|
289
257
|
するには、`--scope user`を付けて登録します。
|
|
290
258
|
|
|
291
259
|
```bash
|
|
292
|
-
claude mcp add mmm --scope user --
|
|
260
|
+
claude mcp add mmm --scope user -- npx -y mmm-mcp-server
|
|
293
261
|
```
|
|
294
262
|
|
|
295
263
|
**(2) グローバルのCLAUDE.md(`~/.claude/CLAUDE.md`)に運用ルールを書く**
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
// そのまま兄弟順。子を持つ要素だけドキュメントが存在する(無ければ葉)。
|
|
9
9
|
//
|
|
10
10
|
// MCPは「新形式のみ対応」(移行ロジックはDart側だけに持たせる)。levels/root
|
|
11
|
-
//
|
|
11
|
+
// が無いマップに対する操作は、切替前(bodiesとlevelsの両方へ書く間)だけ、
|
|
12
|
+
// アプリで一度開いてもらうよう案内して止める。切替後は空のマップとして扱う
|
|
13
|
+
// (levelsMode.tsのreadLevelsSnapshot)。
|
|
12
14
|
export class LevelsNotInitializedError extends Error {
|
|
13
15
|
constructor(title) {
|
|
14
16
|
super(`「${title}」はまだ新形式(levels)のデータがありません。` +
|
|
@@ -9,16 +9,17 @@
|
|
|
9
9
|
// アプリで足した要素が見つからず、bodiesを読み取り専用にするルールの適用後は
|
|
10
10
|
// コミットごと失敗する。呼び出しのたびに読み直すので、MCPサーバーを
|
|
11
11
|
// 再起動しなくても切替に追従する。
|
|
12
|
-
import { LevelsNotInitializedError } from "./levels.js";
|
|
13
12
|
import { levelsSnapshotFromDocs } from "./levelsOps.js";
|
|
14
13
|
export async function isLevelsOnly(client) {
|
|
15
14
|
const config = await client.getDocument("config/app");
|
|
16
15
|
return config?.data.migrationEnabled !== false;
|
|
17
16
|
}
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
/**
|
|
18
|
+
* levels全件を読む。levels/rootが無いマップは空のマップとして扱う
|
|
19
|
+
* (rootへの最初の書き込みは、存在しないことを前提条件にした新規作成になる)。
|
|
20
|
+
* 切替後はアプリでマップを開いてもrootが作られないので、「アプリで開いて」と
|
|
21
|
+
* 止めると中身の無い古いマップへ永久に書き込めなくなる。
|
|
22
|
+
*/
|
|
23
|
+
export async function readLevelsSnapshot(client, levelsPath) {
|
|
24
|
+
return levelsSnapshotFromDocs(await client.listDocuments(levelsPath));
|
|
24
25
|
}
|
package/dist/src/server.js
CHANGED
|
@@ -12,7 +12,7 @@ import { registerDeleteElements } from "./tools/deleteElements.js";
|
|
|
12
12
|
import { registerMoveElement } from "./tools/moveElement.js";
|
|
13
13
|
const server = new McpServer({
|
|
14
14
|
name: "matryoshka-mindmap",
|
|
15
|
-
version: "0.1.
|
|
15
|
+
version: "0.1.2",
|
|
16
16
|
}, {
|
|
17
17
|
instructions: "このサーバーはリアルタイム同期を行わない。各ツールは呼び出された瞬間の" +
|
|
18
18
|
"Firestoreの状態を返すだけで、アプリ側でユーザーが直接行った変更は" +
|
|
@@ -35,7 +35,7 @@ export function registerAutoStructureThought(server) {
|
|
|
35
35
|
if (await isLevelsOnly(client)) {
|
|
36
36
|
let levelsPathResult = "";
|
|
37
37
|
await client.runOptimistic(async () => {
|
|
38
|
-
const snapshot = await readLevelsSnapshot(client, levelsPath
|
|
38
|
+
const snapshot = await readLevelsSnapshot(client, levelsPath);
|
|
39
39
|
if (targetParentId !== null && !locateInLevels(snapshot, targetParentId)) {
|
|
40
40
|
throw new Error(`parentElementId(${targetParentId})がこのマップに見つかりません。list_elementsで確認してください。`);
|
|
41
41
|
}
|
|
@@ -23,10 +23,14 @@ export function registerDeleteElements(server) {
|
|
|
23
23
|
assertCanEditMap(map, session);
|
|
24
24
|
const levelsPath = levelsPathOf(map);
|
|
25
25
|
const bodiesPath = bodiesPathOf(map);
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
// 切替後はrootが無いマップを空のマップとして扱うので、この確認は切替前だけ。
|
|
27
|
+
const levelsOnly = await isLevelsOnly(client);
|
|
28
|
+
if (!levelsOnly) {
|
|
29
|
+
assertLevelsRootExists(await levelsDocExists(client, levelsPath, "root"), map.header.title);
|
|
30
|
+
}
|
|
31
|
+
if (levelsOnly) {
|
|
28
32
|
if (confirmed !== true) {
|
|
29
|
-
const snapshot = await readLevelsSnapshot(client, levelsPath
|
|
33
|
+
const snapshot = await readLevelsSnapshot(client, levelsPath);
|
|
30
34
|
const allTargets = new Set();
|
|
31
35
|
const targets = [];
|
|
32
36
|
for (const elementId of elementIds) {
|
|
@@ -61,7 +65,7 @@ export function registerDeleteElements(server) {
|
|
|
61
65
|
let levelsTotal = 0;
|
|
62
66
|
await client.runOptimistic(async () => {
|
|
63
67
|
levelsDeleted.length = 0;
|
|
64
|
-
const snapshot = await readLevelsSnapshot(client, levelsPath
|
|
68
|
+
const snapshot = await readLevelsSnapshot(client, levelsPath);
|
|
65
69
|
for (const elementId of elementIds) {
|
|
66
70
|
if (!locateInLevels(snapshot, elementId))
|
|
67
71
|
continue; // 既に削除済み(リトライ時など)
|
|
@@ -21,7 +21,7 @@ export function registerEditElement(server) {
|
|
|
21
21
|
if (await isLevelsOnly(client)) {
|
|
22
22
|
let levelsPathResult = null;
|
|
23
23
|
await client.runOptimistic(async () => {
|
|
24
|
-
const snapshot = await readLevelsSnapshot(client, levelsPath
|
|
24
|
+
const snapshot = await readLevelsSnapshot(client, levelsPath);
|
|
25
25
|
const { writes, found } = buildLevelsPatchWrites(levelsPath, snapshot, [
|
|
26
26
|
{ elementId, patch: { detail } },
|
|
27
27
|
]);
|
|
@@ -35,7 +35,7 @@ export function registerImportMarkdownContext(server) {
|
|
|
35
35
|
if (await isLevelsOnly(client)) {
|
|
36
36
|
let levelsPathResult = "";
|
|
37
37
|
await client.runOptimistic(async () => {
|
|
38
|
-
const snapshot = await readLevelsSnapshot(client, levelsPath
|
|
38
|
+
const snapshot = await readLevelsSnapshot(client, levelsPath);
|
|
39
39
|
if (targetParentId !== null && !locateInLevels(snapshot, targetParentId)) {
|
|
40
40
|
throw new Error(`parentElementId(${targetParentId})がこのマップに見つかりません。list_elementsで確認してください。`);
|
|
41
41
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { getContext } from "../mcpContext.js";
|
|
3
3
|
import { resolveMap, levelsPathOf } from "../domain/mapResolver.js";
|
|
4
|
+
import { isLevelsOnly } from "../domain/levelsMode.js";
|
|
4
5
|
import { assertLevelsInitialized, buildTreeFromLevels, readAllLevelDocs, } from "../domain/levels.js";
|
|
5
6
|
// ElementNodeの`done`を`checked`という名前で公開する(仕様書の用語に合わせる)。
|
|
6
7
|
function toChecked(nodes) {
|
|
@@ -78,7 +79,11 @@ export function registerListElements(server) {
|
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
81
|
const levelsById = await readAllLevelDocs(client, levelsPathOf(map));
|
|
81
|
-
|
|
82
|
+
// 切替前はrootが無ければ未移行(bodiesに中身があり得る)なので止める。
|
|
83
|
+
// 切替後はアプリで開いてもrootが作られないので、空のマップとして返す。
|
|
84
|
+
if (!(await isLevelsOnly(client))) {
|
|
85
|
+
assertLevelsInitialized(levelsById, map.header.title);
|
|
86
|
+
}
|
|
82
87
|
const tree = buildTreeFromLevels(levelsById);
|
|
83
88
|
return {
|
|
84
89
|
content: [
|
|
@@ -25,17 +25,21 @@ export function registerMoveElement(server) {
|
|
|
25
25
|
assertCanEditMap(map, session);
|
|
26
26
|
const levelsPath = levelsPathOf(map);
|
|
27
27
|
const bodiesPath = bodiesPathOf(map);
|
|
28
|
-
|
|
28
|
+
// 切替後はrootが無いマップを空のマップとして扱うので、この確認は切替前だけ。
|
|
29
|
+
const levelsOnly = await isLevelsOnly(client);
|
|
30
|
+
if (!levelsOnly) {
|
|
31
|
+
assertLevelsRootExists(await levelsDocExists(client, levelsPath, "root"), map.header.title);
|
|
32
|
+
}
|
|
29
33
|
if (elementId === newParentElementId) {
|
|
30
34
|
throw new Error("要素を自分自身の子にすることはできません。");
|
|
31
35
|
}
|
|
32
36
|
if (elementId === afterElementId) {
|
|
33
37
|
throw new Error("afterElementIdにelementId自身は指定できません。");
|
|
34
38
|
}
|
|
35
|
-
if (
|
|
39
|
+
if (levelsOnly) {
|
|
36
40
|
let levelsPathResult = null;
|
|
37
41
|
await client.runOptimistic(async () => {
|
|
38
|
-
const snapshot = await readLevelsSnapshot(client, levelsPath
|
|
42
|
+
const snapshot = await readLevelsSnapshot(client, levelsPath);
|
|
39
43
|
if (afterElementId !== null && !locateInLevels(snapshot, afterElementId)) {
|
|
40
44
|
throw new Error(`afterElementId(${afterElementId})がこのマップに見つかりません。`);
|
|
41
45
|
}
|
|
@@ -30,7 +30,7 @@ export function registerUpdateTaskStatus(server) {
|
|
|
30
30
|
if (await isLevelsOnly(client)) {
|
|
31
31
|
let levelsResults = [];
|
|
32
32
|
await client.runOptimistic(async () => {
|
|
33
|
-
const snapshot = await readLevelsSnapshot(client, levelsPath
|
|
33
|
+
const snapshot = await readLevelsSnapshot(client, levelsPath);
|
|
34
34
|
const { writes, found } = buildLevelsPatchWrites(levelsPath, snapshot, updates.map((u) => ({ elementId: u.elementId, patch: { done: u.checked } })));
|
|
35
35
|
levelsResults = updates.map((u) => ({
|
|
36
36
|
elementId: u.elementId,
|
package/package.json
CHANGED