feat: add list_my_notes / get_note_stats / list_note_likes tools#1
Open
smithshiro wants to merge 1 commit into
Open
feat: add list_my_notes / get_note_stats / list_note_likes tools#1smithshiro wants to merge 1 commit into
smithshiro wants to merge 1 commit into
Conversation
note.com の非公式内部APIを利用して、記事一覧と統計情報を取得する3つの
新しいMCPツールを追加しました。投稿専用だった既存のMCPに加えて、自分の
記事の状況やリアクションを確認できるようになります。
## 追加ツール
- **list_my_notes**: 自分 (または任意のurlname) の記事一覧を取得。
タイトル、URL、公開日、スキ数、コメント数、ハッシュタグを返します。
`include_views: true` で /api/v1/stats/pv から閲覧数を追加取得。
urlname を省略すると note.com のホームから自動検出します。
- **get_note_stats**: 特定記事の統計を /api/v3/notes/{key} から取得。
スキ数(匿名含む)、コメント数、SNSシェア数、ハッシュタグ、著者情報。
`include_views: true` で自分の記事に限り閲覧数も付与。
- **list_note_likes**: 特定記事にスキを付けたユーザー一覧を取得
(/api/v3/notes/{key}/likes)。プロフィール情報付き。匿名スキは除外。
## 実装詳細
- 既存の `note-state.json` (Playwright storage state) を再利用し、
cookie 認証をそのまま引き継ぐ `withNoteContext` ヘルパーを追加
- `context.request` 経由で内部APIを呼ぶことで UI スクレイピングを
行わず高速に取得
- urlname 自動検出は `window.__NUXT__.state` から探索
- `note` パラメータは key (nXXXXXX) でも URL でも受け付け可
- ページネーション対応 (`page`, `all_pages`)
## 注意事項
- note.com の非公式API を利用しているため、将来の仕様変更で動作
しなくなる可能性があります
- `view_count` は自分の記事のみダッシュボードAPIから取得可能です
- `anonymous_like_count` のユーザー情報は note.com が公開して
いないため list_note_likes の結果には含まれません
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
何ができるようになるか
このPRを入れると、note-post-mcp が**「記事を投稿するだけ」から「自分の note 全体をLLMから確認できる」**ようになります。
具体的には、Claude / Cursor などの MCP クライアントから自然言語で以下のようなことが聞けるようになります:
既存の認証 (
~/.note-state.json) をそのまま使うので追加のセットアップは不要です。投稿系のpublish_note/save_draftは1行も変更していません。追加する3つのツール
1.
list_my_notes— 自分の記事一覧を取得公開済みの自分の記事を、タイトル・URL・公開日・スキ数・コメント数・ハッシュタグ・サムネイル付きで返します。
include_views: trueを付けると閲覧数 (PV) も付与されます。こんな使い方ができます:
all_pages: trueで一括取得してから LLM に分析させる入力例:
{ "name": "list_my_notes", "arguments": { "all_pages": true, "include_views": true } }返り値のイメージ (実アカウントで取得した本物の例):
{ "success": true, "urlname": "fresh_wolf5070", "count": 6, "notes": [ { "id": 154189701, "key": "n4cd1b857e601", "title": "LINEに話しかけるだけで、本格LPが自動で完成する仕組みを作った", "url": "https://note.com/fresh_wolf5070/n/n4cd1b857e601", "publish_at": "2026-04-04T18:46:56+09:00", "like_count": 5, "comment_count": 0, "view_count": 30, "hashtags": ["#AI", "#個人開発", "#LINE公式アカウント", "#イベント告知", "#LP制作"], "thumbnail": "https://assets.st-note.com/production/uploads/images/.../rectangle_large_type_2_....png" } ] }2.
get_note_stats— 特定の記事の詳細統計を取得1 記事に対してスキ数 (匿名含む)、コメント数、SNS シェア内訳、ハッシュタグ、著者情報などをまとめて返します。
include_views: trueで自分の記事に限り閲覧数も付与します。こんな使い方ができます:
入力例 (URL / key どちらでも OK):
{ "name": "get_note_stats", "arguments": { "note": "https://note.com/fresh_wolf5070/n/n4cd1b857e601", "include_views": true } }返り値のイメージ:
{ "success": true, "note": { "id": 154189701, "key": "n4cd1b857e601", "title": "LINEに話しかけるだけで、本格LPが自動で完成する仕組みを作った", "url": "https://note.com/fresh_wolf5070/n/n4cd1b857e601", "publish_at": "2026-04-04T18:46:56.000+09:00", "created_at": "2026-04-04T16:24:44.000+09:00", "like_count": 5, "anonymous_like_count": 0, "comment_count": 0, "share_total_count": 0, "share_details": { /* twitter / facebook / line / note / others の内訳 */ }, "view_count": 30, "hashtags": ["#AI", "#個人開発", "#LINE公式アカウント", "#イベント告知", "#LP制作"], "user": { "id": 1505130, "urlname": "fresh_wolf5070", "nickname": "Web屋のスミス", "follower_count": 12, "following_count": 9, "note_count": 6 } } }3.
list_note_likes— その記事にスキを付けた人の一覧を取得ある記事にスキ (♡) を付けたユーザーのリストを、プロフィール情報付きで返します。
こんな使い方ができます:
入力例:
{ "name": "list_note_likes", "arguments": { "note": "n4cd1b857e601", "all_pages": true } }返り値のイメージ:
{ "success": true, "note_key": "n4cd1b857e601", "count": 5, "likes": [ { "liked_at": "2026-04-06T17:02:55.000+09:00", "user": { "id": 32398, "urlname": "yumotrip", "nickname": "ゆも【Re:spects】", "profile_url": "https://note.com/yumotrip", "profile_image": "https://assets.st-note.com/...", "profile": "【美容×旅×歴史】...", "follower_count": 26, "following_count": 15, "note_count": 42 } } ] }使う側への影響 (Breaking changes)
なし。 既存ツールのシグネチャや挙動は変わりません。新ツール3つが追加されるだけです。
src/index.tsREADME.mdpackage.json/package-lock.json設計上のポイント (レビュワー向け)
既存コードへの影響を最小化
postToNoteやparseMarkdownなど既存の関数は一切触っていません。新ツール用のヘルパー (withNoteContext,fetchNoteJson,detectUrlname,fetchAllPvStats) をpostToNote定義の後・Zod スキーマ定義の前に追加しています。認証は既存の
note-state.jsonを再利用新しい認証フローは追加していません。
withNoteContextがstorageState付きで Playwright のBrowserContextを用意し、context.request(APIRequestContext) で note.com の内部 API を叩きます。cookie が自動的に引き継がれるため、追加の設定は不要です。UI スクレイピングは最小限
UI 操作が必要なのは
urlname自動検出 (note.com のトップページを1回開いてwindow.__NUXT__.stateから取得) の1回だけです。ユーザーがurlnameを明示的に指定すれば、このページロードすらスキップされます。記事一覧・統計・スキユーザー取得はすべて JSON API への直接リクエストです。使用しているエンドポイント (すべて非公式内部API)
GET /api/v2/creators/{urlname}/contents?kind=note&page={N}GET /api/v1/stats/pv?filter=all&page={N}&sort=pvGET /api/v3/notes/{key}GET /api/v3/notes/{key}/likes?page={N}include_viewsのコスト設計閲覧数は
/api/v1/stats/pvに全ページリクエストを投げて id → read_count のマップを作り、記事一覧とマージします。記事数が多い場合は複数ページ取得しますが、last_pageが boolean / number 両方で返る note 側の揺れにも対応済みです (SAFETY_MAX_PAGES = 200で無限ループ防止)。noteパラメータの柔軟性get_note_stats/list_note_likesのnoteパラメータは key (例:n04b99fa6a237) でも URL (https://note.com/.../n/nXXXX) でも受け付けます。extractNoteKeyで正規化しています。ページネーション
list_my_notesとlist_note_likesにはpage/all_pagesを用意しました。all_pages: trueで全ページ取得、それ以外は 1 ページだけ返します。どちらもSAFETY_MAX_PAGES = 200の安全装置付きです。注意事項
view_countは/api/v1/stats/pvが自分の記事しか返さないため、自分の記事でのみ取得可能です。他ユーザーの記事に対してinclude_views: trueを付けてもview_count: nullになります。動作確認
実アカウント (記事6件) で統合テスト実施済み。3ツールすべて正常動作を確認しています。
list_my_notes { all_pages: true, include_views: true }→ 6件取得 / 閲覧数付与 / urlname 自動検出成功get_note_stats { note, include_views: true }→ スキ数・コメント数・シェア数・ハッシュタグ・著者情報・閲覧数を取得list_note_likes { note, all_pages: true }→ 5名のスキユーザー (プロフィール付き) を取得publish_note/save_draftは未改変につき影響なしnpm run build(tsc) が通ることを確認Test plan
npm install && npm run buildが成功することpublish_note/save_draftが引き続き動作することlist_my_notesが urlname 自動検出 +all_pages: trueで全記事取得できることlist_my_notesにinclude_views: trueを渡すと閲覧数が含まれることget_note_statsが key でも URL でも同じ結果を返すことget_note_statsにinclude_views: trueを渡すと自分の記事のみ閲覧数が含まれることlist_note_likesが all_pages でページネーションを行うこと🤖 Generated with Claude Code