MCPでいろいろやってみた内容をまとめてみる
はじめに
最近話題のMCP(Model Context Protocol)についていろいろやっているよというのをまとめてみます。 ただMCPの話をする前に、先にn8nの話をします。
n8nとは
n8nはローコードのワークフローツールです。 IFTTTみたいなものを思い浮かべてもらったらいいと思うのですが、自由度が高く、多くのデータを並列処理できるので気に入っています。
ただライセンスはオープンソースではなく、Sustainable Use Licenseという独自ライセンスです。 とは言え最近よくある「競合サービス以外は使える」系のライセンスで、個人とか社内で使うには問題ないライセンスで、(自分的には)許容範囲だと判断して使っています。
n8nとカスタムノード
このn8nですが、GUIでワークフローを作成できます。その中にはCodeというものがあり、 JavaScriptやPythonでコードを書くことができます。
ただこのコードはテストができないのが不満でした。そこで自分が目をつけたのがカスタムノードという仕組みです。
特定の形式(n8n-
で始まるとかpackage.jsonにいろいろ書くとか)を満たしたnpmライブラリを用意することで、自分が作ったコードをノードとして提供できます。
具体的にはn8n-nodes-starterを参照してください。
これをセルフホスティングしているn8nに入れることができます。自分はGitHubのプライベートパッケージとしてリリースしたものを入れています。こんな感じで。
- name: install private community node in container
vars:
n8n_nodes_package: "@ikemo3/<パッケージ名>@<バージョン>"
command: docker compose exec -e GITHUB_TOKEN={{ lookup('env','GITHUB_TOKEN') }} n8n sh -c "cd ~/.n8n/nodes && npm config set @ikemo3:registry https://npm.pkg.github.com && npm config set //npm.pkg.github.com/:_authToken={{ lookup('env','GITHUB_TOKEN') }} && npm i {{ n8n_nodes_package }}"
args:
chdir: ~/n8n
そして出来たのがこれ。
最近自分はCloudflare Workersで軽いAPIsを作ってn8nのカスタムノードでプッシュ通知させる仕組み作ってた。Hono RPCのtypes.d.tsからLLMである程度作ってもらう形にしている(まだ完璧じゃないが)。 pic.twitter.com/HmPXnTeuvX
— Hideki Ikemoto (@ikemo) March 7, 2025
Cloudflare Workers + Honoを使ってこんな感じにしています。 CLI
としていますが、これは stdio
サーバのことです。

Claude DesktopとMCPに出会った
2月末、Claude 3.7 Sonnetがリリースされ、性能の高さに盛り上がりました。それからClaude Codeが話題になりました。 そこに「Limited time offer: 25% off Claude Pro with the new Claude 3.7 Sonnet」というメールが来ました。 自分は最近LibreChat + GPT-4o miniをケチケチ使ってたのですが、 Claudeの方針が好きなのと、性能のいいモデルを使っておかないとちょっとマズそうな思ったので、思い切って年間契約しました。
契約したものの、普通にWebで使っているだけだと微妙だよねということで他に何かできないかなと思って見つけたのがClaude Desktop。 そこでMCPというのが使えるぞというのを知り試してみました。
n8nのカスタムノードだけじゃなくて、MCPサーバにできるんじゃねと思って試してみたらうまくいった。 https://t.co/qJRZafA74L pic.twitter.com/HzwKt0c9Qf
— Hideki Ikemoto (@ikemo) March 11, 2025
コードの実体はこれです。
- 処理を共通化するためにAPIはPOST、パラメータはJSON bodyに限定
- HonoのRPC機能を使用
- zodスキーマをインポートして
.shape
で再利用 handleResponse
はLLMに書かせた
import { applePushMessageSchema } from "...";
import { ClientResponse, hc } from "hono/client";
// appはHonoインスタンス
const BASE_URL = "...";
const client = hc<typeof app>(BASE_URL, {
headers: {
// 認証のためのヘッダ追加
},
});
// Create an MCP server
const server = new McpServer({
name: "...",
version: "...",
});
server.tool(
"apple-push-message",
"Apple Push Notification用のメッセージを送信します",
applePushMessageSchema.shape,
async (args) => {
return handleResponse(
client["apple-push-message"].$post({
json: args,
}),
);
},
);
async function handleResponse(responsePromise: Promise<ClientResponse<any>>) {
try {
const res = await responsePromise;
const body = await res.json();
if (res.ok) {
return {
content: [
{
type: "text" as const,
text: JSON.stringify(body, null, 2),
},
],
};
} else {
return {
content: [
{
type: "text" as const,
text: `エラーが発生しました: ${res.status} ${res.statusText}\n${JSON.stringify(body, null, 2)}`,
},
],
isError: true,
};
}
} catch (error) {
return {
content: [
{
type: "text" as const,
text: `処理中にエラーが発生しました: ${error instanceof Error ? error.message : String(error)}`,
},
],
isError: true,
};
}
}

APIで何でも繋げていく
このAPIですが何でも出来ます(Cloudflare Workersの制限に引っ掛からなければ)。 たとえば自分はRaindropというブックマークサービスを使っていますが、これに流すためにURLをクリーンにするAPIを作っています。 100行未満のごく小さいコードですが、こんなのでも役立ちます。
そこで、自分が以前Fessで作っていた検索サーバと繋げてみました。 この検索サーバには自分の過去の発言とかを溜め込んでいる、自分だけの検索サーバです。 あとCloudflare Accessで自分しかアクセスできないようにしている、プライベートのコンテンツを取得するAPIも作りました。
これをClaude Desktopからアクセスすると、次のような結果が得られました。
プライベートで集めた情報をFessに入れてそれをCloudflareで検索できるようなエンドポイントを作ってMCPにしてClaude Desktopで使ったらオレオレディープリサーチっぽいのが出来た(?) pic.twitter.com/G7s4qeB7AY
— Hideki Ikemoto (@ikemo) March 19, 2025
ここには載せていませんが、結果の一部を掲載します。ディープリサーチっぽい感じになっています。

情報のソースも出すことができます。たとえば「ニコニコ市場で115本も売れている」の元はこの投稿です(「自分だけの検索サーバ」なので自分の投稿が出る)。
初音ミクがニコニコ市場で115本も売れてるw
— Hideki Ikemoto (@ikemo) September 21, 2007
やっていることはRAGと同様ですが、Claudeが「初音ミク」「初音ミク ボーカロイド」「初音ミク 誕生日」「初音ミク 歴史」とかキーワードを変えて何度も検索してくれます。 しかも検索した結果が0件ならより一般的な単語で検索してくれたりと、ある程度気を利かせてくれます。
こんな感じでいろいろ繋げています。

「@天気」で天気を検索
次に「@天気」で天気を出せるようにしました。
「@天気」で天気が出るようになった pic.twitter.com/uDQJx5XhV9
— Hideki Ikemoto (@ikemo) March 19, 2025
これはちょっとトリックがあって、「"@" から始まる会話については、custom_instruction を使ってカスタムインストラクションを取得し、取得したカスタムインストラクションに基づいて会話してください。」という命令を入れています。そしてカスタムインストラクション自体もMCPで、「天気を要求された時はここにアクセスしてね」という内容が書かれています。
これは何を意識しているのかというと、2006年頃に流行したPlaggerや、2024年まであったニコニコ動画の@ピザです。MCPってめっちゃPlaggerっぽいんです。
PlaywrightのMCPも出たことだし、きっとこれ使えばClaudeがピザ注文してくれるはず。
MCPを使うと「はらへった」とClaudeにつぶやいたらピザが届くようにできます。
— Hideki Ikemoto (@ikemo) March 25, 2025
VS Code + GitHub CopilotでもMCPが使えるしMacのローカルアプリも繋げられる
次にVS Codeのカスタム指示のネタが話題になりました。
自分はツンデレスキーということでVS Code + GitHub Copilotで試していたのですが、VS CodeのInsider版にMCP対応が公式で対応したということで試してみました(このときは公式ではなく別の拡張機能だったかもしれません)。それがこれ。セルフツッコミができるのがポイント高いです。
突然我に返るところとかおもろい https://t.co/ziW48IzaNj pic.twitter.com/D6uI2pLBfa
— Hideki Ikemoto (@ikemo) March 21, 2025
これはOmniFocusのInboxを検索していますが、確かapple-mcpだったと思います。 いくつかはAppleScriptを使っているようです。
モバイル対応していない → LibreChatがあるよ
このClaude DesktopでのMCPですが、デスクトップということで、モバイルに対応していないのが不満でした。 Transportにはstdioの他にSSE(Server-sent events)があったのですが、この実装ハードルが高いということで、Streamable HTTPによる対応が議論されていました。
ちなみにこの仕様は2025-03-26版としてリリースされています。
ただこれがクライアントに実装されるのはまだなので、他にいいのないかなとawesome-mcp-clientsを眺めていました。
ほとんどのアプリがデスクトップだったのですが、WebアプリにLibreChatが入っているのを確認しました。
サクッと動きました(ENDPOINTS
の指定漏れに注意)。
モバイル対応のMCPクライアントないかなーと思ったらLibreChatがMCP対応してたのを知ったので早速セット。これで色々できるようになった。https://t.co/NdYpzR8eTx
— Hideki Ikemoto (@ikemo) March 28, 2025
ただ stdio
だといろいろと面倒なのでやっぱりSSE対応クライアントが欲しくなりました。
stdioをSSEに変えてくれるものありそうだなと思って探したらmcp-proxyというのを見つけました。
これを入れたらサクッとSSE対応でき、iPhone + LibreChat + MCPでいろいろできるようになりました。

スケジュール実行したいよね → n8nがあるよ
これでモバイル対応できるようになりましたが、チャットUIだけでやるのは限界があるかなと感じて、自動できるプラットフォームがないかと探してみました。 まだどこにもないし、Mastraでclient作るしかないのかなと思ってたんですが、 ふとn8nにAgent機能があるのに気づきました。
LibreChatでMCPをツールとして使えるけど、どうせならスケジュール実行したいよねと思って色々考えてたけどn8nのAI Agentノードにツールがあるからそれ使えないかな・・・
— Hideki Ikemoto (@ikemo) April 6, 2025
Conversationと呼ばれるチャットUIの他にも色々なパターンがあります。
ただ、これは組み込みのノードには対応していますが、自作カスタムノードには対応していませんでした。 n8n-nodes-mcpというのも試したのですが、自分の今のコードとは合わないのでやめました。 Issue上がっていないかなと調べたら次のを見つけました。
読み進めてみるとすでに対応済み、ただし次の2つの設定が必要のこと。
- カスタムノードに
usableAsTool: true
を追加 - 環境変数に
N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true
を追加
Tools AI Agentを使って、データベースからデータを取得して、それをメールするタスクを試してみたんですが、無事動きました。動かないこともあったのですが、プロンプトが雑なのと、GPT-4o miniでケチったのがおそらく原因なので、ちゃんと組めばそこそこの精度は出るかなと。
n8nのAgent Toolは正確にはMCPではないんですが、MCPとAPIを共有しているので実質同じような感じに扱えます。

たろっとさん作ったよ
自分が昔作ったたろっとさんですが、とりあえずこれもMCPサーバ化。
MCPでたろっとさん作ってみた pic.twitter.com/9b2rig4PPB
— Hideki Ikemoto (@ikemo) April 6, 2025
ブラウザ拡張とも繋げられる?
自分はChrome/Firefox拡張の「ゴシップサイトブロッカー」を作っているのですが、この拡張機能をMCPサーバにできないかなと考えました。 拡張機能はWebSocketを使ってローカルのアプリとも通信できるようなので同じようなのを作ってないかなと思って調べたところ見つけました。
これ気になる。というか自分が考えたアイデア探したら見つけた。https://t.co/XcDu75CVGk
— Hideki Ikemoto (@ikemo) April 5, 2025
ただこれはPoC的リポジトリで、Chrome拡張機能も開発者モードでのインストールで、
デフォルトだとMCPクライアントからアラートダイアログを取得とUserAgentを取得する機能しかありませんでした。
そこで改造して document.body
を取得して返すというのを試してみました。
試してみた。デフォルトだとalert表示とuserAgent取得のみだったのでお試しでdocument.bodyを返すようにしてみた。ちゃんと内容が読み取れている。
— Hideki Ikemoto (@ikemo) April 5, 2025
ちなみにログインしているページでもできて内容が読み取れた。 pic.twitter.com/7rrVFB6cgV
ただこれは原理的にものすごく危なくて(MCP自体悪意があるコードに弱いのでいまさらですが)、普段使っているブラウザの情報を引っこ抜けます。 普通にブラウザ操作するならPlaywrightを使えばいいので、こんなこともできるという実験です。
数値の比較は出来なかった
LLMは9.9と9.11の比較が苦手なので、数値を比較するだけのMCPサーバを作れば解決できるんじゃね?と判断して試してみました。 ですがダメでした。
なんでや・・・ pic.twitter.com/H2uzAPIPZn
— Hideki Ikemoto (@ikemo) April 6, 2025
この比較を間違えるのはコンテキスト依存なので「ソフトウェア開発者かどうか」を渡せばうまくいくと思ったんですが。
本当にやりたかったこと pic.twitter.com/6ZEHUlH3M2
— Hideki Ikemoto (@ikemo) April 6, 2025
悪意があるプロンプトに弱い
MCPサーバが返す文字列として、LLMを操作する命令を入れるとどうかなと試してみました。 あっさりひっかかってしまいました。
悪意のある(?)MCPサーバは危険 pic.twitter.com/hADEdGjBXZ
— Hideki Ikemoto (@ikemo) April 6, 2025
おわりに
MCPに今後期待することとか今後試してみたいことも書こうと思ったんですが、これまでやってきたことを並べるだけで結構な量になったので一旦これまでにしておきます。
国産クラウドやVPS、SaaSに提供して欲しいもの→