Service worker で (MCP) サーバを動かすメモ
ServiceWorker
web(ブラウザ上)でデーモンみたいなことができる.
URL アクセス(fetch)を横取りしてなんか処理とかできる.
(MCP) サーバたてたい.
制約
- セキュリティ上, https か localhost でないと動かせない.
- worker として動かすスクリプトは eval() など動的コード実行や,
import()での動的 import ができない制約がある
(webassembly は実行できる) - ブラウザ内だけなので, 外部(e.g. curl)からのアクセスはできない.
ちなみに Chrome だと, serviceWorker.register 使うと

というエラーがでるけど, serviceWorker.register での実行がエラーというわけではないのでややこしい.
serviceWorker の登録(起動)
にあるように window.isSecureContext のチェックを入れるとよい
if (window.isSecureContext) {
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register('/mcp-service-worker.js').then(function(reg){
if (reg.active) console.log('serviceworker installed')
})
.catch(function(err){
console.log('registration failed: ' + err)
})
} else {
console.log("no serviceworker")
}
こんなかんじでしょうか.
ちなみに著者は if ("serviceworker" in navigator) { と書いて, servieworker 検出されんのー, とうんうん悩んで半営業日消費しただよ...
worker 側
- install
- active
- fetch
あたりに eventListener をしかけることができます.
install は register の最初に呼ばれる?
active はページリロードのたびに呼ばれる?
(stop イベントで deactivate できる?)
fetch はページへのアクセスがあったときに呼ばれる.
self.addEventListener('install', (event) => {
console.log('[MCP server] Installing...');
});
self.addEventListener('activate', function (e) {
console.info('[MCP server] activate', e);
});
self.addEventListener('fetch', function (e) {
console.info('[MCP server] fetch', e);
});
こんなかんじでしょうか.
動作確認 tips
コード変更した場合, vite とかでのリロード or ブラウザリロードではうまく反映されないことが多いようです.

Chrome の場合 Application -> unregister してあげると良いようです.
MCP サーバ
あとは MCP のプロトコルに沿って JSON-RPC 通信をぺろぺろやればいけるはず!
service worker ではいろいろ制約あるので, proxy 的に使うのも手カモ.
ブラウザから別ホストの MCP サーバにつなぐときに, ブラウザ内で処理したい tool や resource は service worker ので処理させるとか.
(e.g. スクリーンショット取るとか. しかしスクリーンショット(DOM アクセス)は serviceworker 内では取得できないため, メッセージ通信でメインスレッドにリクエストを出すことで対応となろう)
さらなる高みへ
ChatGPT くんなり Claude くんへ相談しよう
(セキュリティ関連もありややこしいため, 以外といい返事もらえないけど)
Discussion