Skip to main content
Glama
README.md
# mcp-server-sample — メモを保存・検索する最小の MCP サーバー

メモを保存・検索するだけの、最小の MCP サーバーです。外部システムへは一切繋ぎません。
保存先は同じフォルダの `notes.json` 1ファイルだけです。

MCP の3つのプリミティブを、1つずつ持たせてあります。

| プリミティブ | 誰が決めるか | このサーバーでの中身 |
|---|---|---|
| **Tools** | モデルが判断する | `add_note`(メモを追加)/`search_notes`(メモを検索) |
| **Resources** | AI アプリが取得して渡す | `notes://all`(保存済みメモの全件) |
| **Prompts** | ユーザーが明示的に選ぶ | `weekly_review`(今週のふりかえり) |

## 必要なもの

- **Node.js 24 以上**(LTS。`node --version` で確認)
- git

## セットアップ

```bash
git clone https://github.com/utakatano/mcp-server-sample.git
cd mcp-server-sample
npm install
```

`npm install` が通れば準備完了です。**この時点では起動しません。**
MCP サーバーは AI アプリが起動するので、自分でターミナルから走らせる必要はありません。

## AI アプリに繋ぐ

### Claude Code

```bash
claude mcp add notes -- node /絶対パス/mcp-server-sample/index.js
```

`claude mcp list` で `✔ Connected` と出れば繋がっています。

### Claude Desktop

設定 → Developer → 「Edit Config」で `claude_desktop_config.json` を開き、次を追記します。

```json
{
  "mcpServers": {
    "notes": {
      "command": "node",
      "args": ["/絶対パス/mcp-server-sample/index.js"]
    }
  }
}
```

保存したら **Claude Desktop を完全に終了して起動し直します**(ウィンドウを閉じるだけでは反映されません)。

- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

## 動作確認

```
「来週までにネットワーク構成を確認する」とメモして
```

```
「ネットワーク」を含むメモを探して
```

`notes.json` が作られ、中身が増えていくのが確認できます。

## 保存先を変える

環境変数 `NOTES_FILE` に絶対パスを渡すと、保存先を変えられます。

```json
{
  "mcpServers": {
    "notes": {
      "command": "node",
      "args": ["/絶対パス/mcp-server-sample/index.js"],
      "env": { "NOTES_FILE": "/絶対パス/my-notes.json" }
    }
  }
}
```

## 繋がらないとき

まず**ログ**を見ます。原因はたいていここに出ています。

```bash
tail -20 ~/Library/Logs/Claude/mcp-server-notes.log   # macOS
# Windows: %APPDATA%\Claude\logs\mcp-server-notes.log
```

`Server started and connected successfully` のあとにエラーが続いていないかを見てください。

| ログに出ているもの | 原因 | 対処 |
|---|---|---|
| `Cannot find module '/.../index.js'` | `args` のパスが違う | リポジトリ直下で `pwd` を実行し、その出力+`/index.js` を貼り直す |
| `spawn node ENOENT` | AI アプリから `node` が見つからない。nvm / volta などで PATH がシェルの設定にしかない場合に起きる | `which node` の出力(絶対パス)を `command` にそのまま書く |
| `Cannot find package '@modelcontextprotocol/server'` | 依存が入っていない | リポジトリ直下で `npm ci` |
| ログが空、または更新されない | 設定が読み込まれていない | JSON の構文(カンマ・括弧)を確認し、**Claude Desktop を完全に終了**(macOS は ⌘Q)してから起動し直す |

**サーバー側か AI アプリ側かの切り分け**は、手元で直接叩くのが速いです。

```bash
printf '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28"}}}\n' \
  | node /絶対パス/mcp-server-sample/index.js
```

`add_note` と `search_notes` を含む JSON が返れば**サーバーは正常**です。その場合は AI アプリ側の設定(パス・JSON の書き方・再起動)を疑ってください。

## サプライチェーン対策

npm パッケージの乗っ取りを想定した設定を `.npmrc` に入れてあります。`npm install` / `npm ci` のたびに効きます。

| 設定 | 何をするか |
|---|---|
| `ignore-scripts=true` | インストール時に依存パッケージのライフサイクルスクリプト(`postinstall` など)を実行しない。乗っ取られたパッケージが最初に使う実行経路を塞ぐ。`npm start` / `npm run` は従来どおり動く(pre / post スクリプトだけが走らなくなる) |
| `save-exact=true` | `npm install <pkg>` が `package.json` に `^` を付けず、完全固定で書く |
| `min-release-age=7` | 公開から7日を過ぎたバージョンだけをインストールする。npm はこれを `before=<7日前の日時>` に変換して依存を解決する |

依存は `package.json` で**完全固定**(`@modelcontextprotocol/server` は `2.0.0`、`zod` は `4.4.3`)、
`package-lock.json` に `integrity` ハッシュ付きで記録してあります。
**lock のとおりに入れたいときは `npm install` ではなく `npm ci` を使ってください。**

依存を更新するときは、意図して1つずつ上げます。

```bash
npm outdated
npm install @modelcontextprotocol/server@2.1.0   # save-exact により完全固定で書かれる
npm ls --all                                      # 増えた依存を目で確認する
```

## ライセンス

MIT

TDQS

A3.5/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have completely distinct purposes: one creates/ stores a note, the other retrieves notes via search. There is no overlap or ambiguity between writing and searching.

Naming Consistency5/5

Both tool names follow a consistent verb_noun pattern (add_note, search_notes) using lowercase with underscores. The naming is predictable and clear.

Tool Count3/5

With only 2 tools, the set feels minimal. While the tools cover basic create and read/search operations, the server's purpose (saving and retrieving notes) could reasonably include more tools (e.g., update, delete, list tags) to avoid being overly thin.

Completeness2/5

The domain is a personal note-taking system, but only add and search operations are provided. Missing critical operations like update, delete, and get all notes (without search) create significant gaps that would frustrate or block a typical agent workflow.

Maintenance

ActivitySlowing
ResponsivenessNo issues