章 23 · 部 III · 実践
WebMCP:Sandboxで作業するエージェント
ブラウザーで動くAIエージェントが、36のWebMCPツールでSandboxを相手にできること(ページを見る、任意の設定を変える、本文を編集する、画像、表、フォントを加える、検査を実行する、書き出す)と、各ツールの呼び出し方を、実際の引数と答えで示します
かんたんな説明
このページは、Sandboxでの本の作業をAIの助手に任せたい人のためのものです。Sandboxを開いている間、助手には、ページを見る、デザインを変える、本文を直す、画像や表を加える、問題を見つける、ファイルを保存するための道具が渡されます。たとえば「本文を少し大きくして、本が40ページに収まるか確かめて」と普段の言葉で頼むと、助手が道具を使い、そのページを見せてくれます。作業はすべてお使いのブラウザーの中で行われます。このページでは、助手のつなぎ方、助手にできること、各ツールの呼び出し方を説明します。
ブラウザーの中のエージェントが、Sandboxで開いている本を扱います。ページを見て、変えて、もう一度見ます。
Sandboxは、WebMCPを通じてエージェントに専用のツールを渡します。WebMCPはWeb標準の草案で、ページがブラウザーとやり取りしているAIモデルにツールを渡せるようにするものです。エージェントはこのツールを使うので、画面をクリックしてたどる必要がありません。本を読み、12ページの画像を求め、bodyText.fontSizeを10.5 ptにし、章が18ページから19ページに増えたのを見て、元に戻します。人が目で確かめながらすることを、あなたの本に対して、あなたのブラウザーの中で行います。
ツールは、名前がsandbox_で始まるものが36個あり、Sandboxが画面にある間だけ登録されます。ほかに、postext.devのどのページにもあるサイトのツールsite_*が8個あります。このページでは、エージェントに頼みたい内容ごとにツールを分け、それぞれの呼び出し方を示します。
#エージェントをつなぐ
#WebMCPのあるブラウザー
ツールはSandboxがマウントされたときにdocument.modelContextに登録され、Sandboxを離れると取り下げられます。ブラウザーからページのツールを受け取るエージェントは、そこでツールを見つけます。Postext側でインストールや設定をするものはありません。
WebMCPはまだ草案の段階です。Chromeではオリジントライアルとして、またchrome://flags/#enable-webmcp-testingのフラグで使えます。ツールはページに従います。ホームページやドキュメントでは、エージェントが使えるのはsite_*のツールで、Sandboxが画面に出ると36個のsandbox_*のツールが加わります。
#そのほかのブラウザー:window.postextWebMcp
ページは、WebMCPの有無にかかわらず、同じツールをwindow.postextWebMcpにも置きます。ページ内でスクリプトを実行できるエージェントなら、これを使えます。PuppeteerやPlaywrightのような自動化ツール、ブラウザーを操作してスクリプトを評価するMCPサーバー(Chrome DevTools MCP)、ブラウザー拡張機能、あるいは開発者コンソールに向かうあなた自身です。
// このページにあるツール
postextWebMcp.listTools().map((t) => t.name);
// ツールを1つ実行する:名前と、引数を収めたオブジェクト
await postextWebMcp.executeTool('sandbox_get_state', {});
await postextWebMcp.executeTool('sandbox_set_config', {
changes: [{ path: 'bodyText.fontSize', value: '10.5pt' }],
});同じことをPuppeteerのスクリプトで行い、ページを画像として保存する例です。
import fs from 'node:fs';
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://postext.dev/ja/sandbox');
await page.waitForFunction(() => window.postextWebMcp?.listTools().some((t) => t.name === 'sandbox_get_state'));
await page.waitForFunction(async () => (await window.postextWebMcp.executeTool('sandbox_get_state', {})).ready);
const result = await page.evaluate(() =>
window.postextWebMcp.executeTool('sandbox_render_page', { chapter: 1, position: 1, width: 1200, format: 'png' }),
);
const picture = result.content.find((part) => part.type === 'image');
fs.writeFileSync('page-1.png', Buffer.from(picture.data, 'base64'));
await browser.close();新しいブラウザープロファイルは保存領域も別なので、あなたのプロジェクトではなく見本の本から始まります。自分の本で作業するときは、その本を作ったブラウザーを使ってください。
#ツールの答えの形
ツールはJSONのオブジェクトで答えます。成功すればok: trueと求められた内容、失敗すればok: falseと、何が誤りで代わりに何を求めればよいかを述べるerrorです。
{
"ok": false,
"error": "bodyText.fontSize is a length: give { \"value\": 11, \"unit\": \"pt\" }, a number (in pt) or a text such as \"11pt\". The units: cm, mm, in, pt, px, em, rem."
}引数は、何かを実行する前にツールのスキーマと照合されます。パラメーター名を書き誤ると、正しい名前の一覧を添えて拒否されます。画像を返すツール(sandbox_render_page)は、MCPの形{ content: [...] }で答えます。最初にページを説明するJSONを収めたテキストの部分があり、続いてページごとに1つ、base64でエンコードした画像の部分が並びます。
#作業の繰り返し
本を変えるツールは、どれもレイアウトが追いつくのを待ってから答え、各章が何ページになったかを伝えます。そのため次に見るのはいつも新しいページで、エージェントはデザイナーと同じように作業を進められます。
- 現状を知る:
sandbox_get_stateは、本、その章と各章のページ、画面に出ている章とページ、開いているパネルを返します。 - 見る:
sandbox_render_pageはページを描き、sandbox_inspect_pagesはページをデータとして説明し、sandbox_get_warningsは検査で見つかったものを一覧にします。 - 変える:
sandbox_set_config、sandbox_edit_text、sandbox_save_resourceなど。 - もう一度見る:そして変更を残すか、元に戻します。
ページは、画面にどのビューアーが出ていても、ツールのために組まれて描かれます。あなたが第2章を読んでいる間に、エージェントは第7章を見ることができます。
#頼めることと、そのやり方
#開いているものを知る
// sandbox_get_state
{}{
"ok": true,
"ready": true,
"book": { "kind": "sample", "id": "postext-guide", "name": "ガイド" },
"pages": 3,
"chapters": [
{ "chapter": 1, "id": "a", "title": "はじめに", "onScreen": true, "words": 1007, "pages": 2 },
{ "chapter": 2, "id": "b", "title": "第二章", "words": 101, "pages": 1 }
],
"view": { "viewer": "canvas", "panel": "none", "scope": "chapter", "chapter": 1 },
"resources": 0,
"warnings": 0
}ready: falseのときは、理由を示すwaitingForが付きます(本がまだ読み込み中、など)。Sandboxがあなたの返事を待っているときはquestionとnoticeが現れます。確認と通知を参照してください。
chapterを受け取るツールは、本の中での位置(1から)、章のタイトル、章のidのどれでも受け付けます。省略すると、画面に出ている章になります。
#ページを見る
画像:「第3章の冒頭を見せて」「24ページと25ページの見開きはどう見える?」といった頼みには、次のように呼びます。
// sandbox_render_page:見開き、1ページあたり幅1200 px
{ "chapter": 3, "page": 24, "count": 2, "width": 1200 }pageはページに印刷されている番号、positionはその章のページの中での順番(1から)で、番号のないページに使います。どちらもなければ、画面に出ているページになります。cropはページの一部を拡大します。位置と大きさは左上の角からの、ページの幅と高さに対する割合で指定し、文字やアキを間近で確かめるのに使います。
// sandbox_render_page:右下の4分の1を拡大
{ "chapter": 3, "page": 24, "crop": { "x": 0.5, "y": 0.5, "width": 0.5, "height": 0.5 }, "width": 1600 }printPreview: trueは、印刷プロファイルによるソフトプルーフを、仕上がり、裁ち落とし、セーフエリアのガイドとともに描きます。trimmed: trueは、トンボのある余白を省きます。
データとしての同じページ:「このページで間延びしている行は?」「2段目は埋まっている?」といった問いには、次のように呼びます。
// sandbox_inspect_pages:ページを指定しなければ、章のページごとに1行
{ "chapter": 1 }{
"chapter": 1, "title": "はじめに", "chapterPages": 2, "converged": true,
"pages": [
{ "position": 1, "label": "1", "role": "opener", "blank": false, "lines": 45, "figures": 0, "starts": "はじめに" },
{ "position": 2, "label": "2", "role": "body", "blank": false, "lines": 37, "figures": 0, "starts": "数十年が過ぎた。活版印刷は五百年をかけて…" }
]
}pageかpositionを指定すると、そのページのブロックをすべて一覧にします。ブロックごとに、種類、段、テキスト、行数、ハイフンで終わる行、間延びした両端そろえの行とその語間の幅、ページ上の枠が示され、さらに各段がどこまで埋まっているか(fill: 0.99)も示されます。
ある点にあるもの:エージェントは画像の中に何かを見つけると、切り抜きと同じ割合を使って、それが何かを尋ねます。
// sandbox_inspect_point
{ "chapter": 3, "page": 24, "x": 0.71, "y": 0.42 }答えには、そこにあるブロック、Markdownのソースの行と桁(と語)、リンクとその行き先のページ、リソースの表のセルやキャプションが入ります。select: trueを付けると、クリックと同じことも行います。本文パネルが開き、その位置にキャレットが置かれます(word: trueでその語を選択し、toで2つ目の点までを選択します)。
#デザインを変える
設定のどの項目も、パスで指定して変えられます。エージェントは最初からパスを知っていることはまずないので、まず探します。
// sandbox_find_setting
{ "query": "orphans" }{
"ok": true,
"paths": [
{ "path": "bodyText.avoidOrphans", "effective": true },
{ "path": "bodyText.avoidOrphansInLists", "effective": true }
],
"sections": [{ "section": "Body text", "group": "Typography", "settingsGroup": "text", "configKeys": ["bodyText"] }]
}sandbox_get_configは、1つの設定またはセクション全体を読みます。setは本が保存している値、effectiveは既定値を補った結果の値で、後者からはそのセクションにあるすべての設定もわかります。
// sandbox_get_config
{ "path": "headings.levels[level=2]" }パスでは、リストの項目をほかと区別する値で指定します。headings.levels[level=2].fontSize、header.elements[id=titleOdd].italic、calloutStyles[id=note].titleのようにです。そのうえでsandbox_set_configを使えば、1回の呼び出しでいくつでも設定を変えられます。
// sandbox_set_config
{
"changes": [
{ "path": "bodyText.fontSize", "value": "10.5pt" },
{ "path": "page.margins.top", "value": { "value": 2.5, "unit": "cm" } },
{ "path": "headings.levels[level=2].color", "value": "#1f3a5f" },
{ "path": "bodyText.avoidOrphans", "value": true }
]
}長さは"2.5cm"、{ "value": 2.5, "unit": "cm" }、またはその設定の単位での数値で、色は"#1f3a5f"です。値にnullを渡すと設定が取り除かれ、デザインの値に戻ります。答えには、変更の良し悪しを判断する材料と、元に戻す方法が入っています。
{
"ok": true,
"changed": [
{
"path": "bodyText.fontSize",
"from": null,
"to": { "value": 10.5, "unit": "pt" },
"effective": { "from": { "value": 10, "unit": "pt" }, "to": { "value": 10.5, "unit": "pt" } }
}
],
"followed": [
{ "path": "captionStyle.fontSize.value", "from": 10, "to": 10.5 },
{ "path": "tableStyle.bodyFontSize.value", "from": 10, "to": 10.5 }
],
"pagesBefore": 212,
"pagesAfter": 219,
"chapters": [{ "chapter": 1, "title": "はじめに", "pages": 19, "pagesBefore": 18 }]
}fromは変更前に保存されていた値です(ここではnullで、本はこの設定を持っていませんでした)。fromを値にして同じ呼び出しをすれば、変更が元に戻ります。followedには、この設定に連動して変わった設定が並びます。エンジンが求められたものと違う値に解決したとき(上限に当たった、ほかの設定に依存している、など)はnoteが付きます。形の合わない値や、エンジンが解決できない設定は拒否され、何も変わりません。
大きな変更には、設定にオブジェクトをマージするpatch(オブジェクトはマージされ、nullは取り除き、リストは丸ごと置き換わります)と、本の設定を丸ごと別の設定に置き換えるreplaceがあります。後者には、たとえば書き出したpostext-config.jsonを渡せます。sandbox_reset_to_originalにpart: "config"を渡すと、本の最初のデザインに戻ります。
フォントも設定です。sandbox_list_fontsにsearch: "Garamond"を渡すと公開カタログからファミリーを探し、その名前をfontFamilyの設定に書き込むとフォントが読み込まれます。
#本文を編集する
各章の本文は、Postextの拡張を加えたMarkdownです(文書形式を参照)。エージェントは行番号付きで本文を読み、該当する一節を探し、一節を厳密に指定して置き換えます。
// sandbox_read_text:第2章の40行目から80行目
{ "chapter": 2, "fromLine": 40, "toLine": 80 }// sandbox_search_text:一節が現れる場所と、そのページ
{ "query": "ベースライングリッド", "pages": true }// sandbox_edit_text
{
"chapter": 2,
"edits": [
{ "find": "冒頭の最後の言葉。", "replace": "冒頭を締めくくる言葉。" },
{ "find": "コンピュータ", "replace": "コンピューター", "all": true }
]
}それぞれのfindはソースと完全に一致し、allを指定しない限り1回だけ現れる必要があります。編集はすべて適用されるか、1つも適用されないかのどちらかです。見つからない一節があると、章を読み直すよう勧める答えとともに拒否されます。1回の呼び出し全体がsandbox_undo_textの1ステップになり、このツールで取り消せます(redo: trueでやり直せます)。sandbox_write_textは章全体を、markdownまたは.mdファイルの内容で置き換えます。
本文のある場所をあなたに示すときは、sandbox_select_textが本文パネルを開き、その一節を選択します(text、line、offsetで指定)。検査パネルで見つかった項目をクリックしたときと同じ動きです。
#章を整理する
sandbox_manage_chaptersは、章の追加、名前の変更、移動、分割、結合、表示を行います。
// 3番目に章を加える
{ "action": "add", "title": "エピローグ", "markdown": "# エピローグ\n\nおわり。\n", "position": 3 }
// ある一節が始まる位置で章を分ける
{ "action": "split", "chapter": "はじめに", "before": "## 第二部" }
// レベル1の見出しごとに1つの章にする
{ "action": "split_at_headings", "chapter": 1 }sandbox_remove_chapterは章を1つ削除します。この操作は取り消せません。
#画像、表、動画、フォントを加える
sandbox_save_resourceは、リソースパネルと同じように、リソースを加えたり変えたりします。ファイルはurl(ページが取得できるhttps:のアドレス、またはdata: URL)か、base64で渡します。
// キャプションと代替テキストの付いた画像
{
"id": "harbour",
"image": { "url": "https://example.org/harbour.jpg" },
"caption": "夜明けの港",
"altText": "石の岸壁に係留された漁船。水面に霧がかかっている",
"placement": { "position": "top", "span": "page" }
}// テキストの行から作る表。最初の行が見出し行になる
{
"id": "prices",
"caption": "1850年の価格",
"table": { "rows": [["品目", "価格"], ["パン", "2ペンス"], ["インク", "6ペンス"]], "columnWidths": [2, 1] }
}// YouTubeの動画:ポスター画像、フレームの大きさ、タイトルは取得される
{ "id": "interview", "video": { "url": "https://www.youtube.com/watch?v=…" }, "caption": "仕事中の著者" }答えには、保存されたレコードと、それを配置する行::resource{id="prices"}が入ります。エージェントはこの行をsandbox_edit_textで本文に書き込みます。既存のidに対して呼ぶと、渡したものだけが変わります。キャプション、表のセル、配置、画像のセーフエリアなどです。newIdはリソースの名前を変え、既定では本の中のそのリソースへの参照もすべて書き換えます。sandbox_list_resourcesはリソースを一覧にし、idを渡すとその1つを詳しく返します(表なら書式付きのセル、SVGならそのソース)。
本にアップロードするフォントはsandbox_save_fontで扱います。
{ "action": "add", "family": "My Serif", "weight": 700, "style": "italic", "file": { "url": "https://example.org/MySerif-BoldItalic.woff2" } }#本を検査する
// sandbox_get_warnings:すべての章
{ "scope": "book" }答えは検査パネルが示す内容と同じで、画面に何が出ていても、任意の章または本全体について返ります。見つからないフォントや画像、エンジンが読めなかったマークアップ、収まらないデザイン要素、地に対して薄すぎる文字、間延びした行、ウィドウ、はみ出した囲み、印刷のプリフライトです。各警告には、分類、章、行とオフセット、ページ、そして警告が名指しする設定やリソースが付きます。
{
"ok": true,
"scope": "book",
"total": 3,
"byCategory": { "typesetting": 2, "design": 1 },
"warnings": [
{
"kind": "headerFooterMetadataMissing",
"category": "design",
"title": "Placeholder metadata missing",
"detail": "header · {title} — The metadata referenced by this placeholder is not set — it will render empty."
}
]
}エージェントは警告からその場所に移り(sandbox_select_textにoffsetとtoOffsetを渡すか、sandbox_go_to_pageを使います)、ページを見て、本文か設定を直せます。categoryで一覧を絞り込めます。長い本では、scope: "book"はすべての章を組むので時間がかかります。
#画面で見せる
エージェントが変えたものは、あなたにも見えます。何かを指し示したいときは次のようにします。
// sandbox_set_view:Canvasで見開き表示にし、間延びした行を強調する
{ "viewer": "canvas", "pages": "spread", "fit": "height", "guides": { "looseLines": true, "baselineGrid": true } }// sandbox_go_to_page:図が置かれている場所
{ "anchor": "harbour" }sandbox_set_viewでは、ほかに、ビューアー(canvas、pdf、folio、html、epub)、サイドパネル、章か本全体か、拡大率、読者側の文字サイズ、印刷プレビュー、デザインパネルのグループも選べます。sandbox_go_to_pageは、step、page、position、本文の一節text、anchor、EPUBの目次の項目contentsでページを移します。sandbox_run_viewerはツールバーのボタンを押します。regenerateはPDFやEPUBを作り直してそれを待ち、printは印刷ダイアログを開いてあなたの確認を待ち、play_videoはページ上の動画を再生します。
#漫画のページの編集
sandbox_inspect_comicは、漫画のページのコマ、割り線、吹き出しを位置とともに返します。sandbox_edit_comicは、人がポインターで行う編集を行い、ソースに書き込みます。
// 吹き出しの中心を、そのコマの絵の中の一点に動かす(パーセントで指定)
{ "comic": 1, "action": "move_balloon", "balloon": 2, "at": { "x": 30, "y": 18 } }
// 1本目の割り線を、そのセルの45 %の位置に動かす
{ "comic": 1, "action": "move_splitter", "splitter": 1, "start": 45 }吹き出しが顔に重なったり、コマからはみ出したりすると、答えで警告します。形式については漫画を参照してください。
#本、ファイル、Word
-
本を開いて保存する:
sandbox_list_booksは見本の本とあなたのプロジェクトを一覧にし、sandbox_open_bookはそのうちの1冊を開きます({ "kind": "sample", "id": "postext-guide", "language": "es" })。sandbox_save_bookにaction: "copy_current"を渡すと画面の本を自分のプロジェクトとして保存し、new_blankを渡すと空の本を始めます。 -
書き出す:
sandbox_exportはpdf、epub、postext、docx、markdown、configを書き出します。既定ではブラウザーがファイルをダウンロードします。deliver: "data"を渡すと、PDFやEPUBがbase64でエンコードされてエージェントに返ります。{ "format": "pdf", "scope": "book", "deliver": "data" } -
.postextファイルを読み込む:sandbox_import_bookを使います(inspect: trueを渡すと、読み込まずに、どの言語が入っているかを答えます)。 -
Wordの原稿を取り込む:
sandbox_import_wordを使います。最初にdryRun: trueで実行してください。何も変えずに、品質レポート、Wordのスタイルごとに何になるか、作られる章とリソースを答えます。そのあとで対応づけを直し、本番の読み込みを実行します。{ "file": { "url": "https://example.org/manuscript.docx" }, "destination": "book", "mapping": { "paragraphs": { "Epigraph": { "kind": "quote" }, "Chapter Title": { "kind": "chapter" } } }, "saveTemplateAs": "わたしの出版社" }sandbox_word_templatesは、保存した対応づけの一覧表示、読み取り、保存、削除を行います。この対応づけはWordへの書き出しでも使われます。
#確認と通知
リンクから開いた本について、あなたがすでに自分の版を持っている場合、Sandboxは手元の複製を置き換えるかどうかを尋ねます。sandbox_get_stateはこれをquestionとして、ready: falseとともに伝えます。sandbox_answerがこれに答えます。replaceCopy: falseは手元の複製を残し、trueは公開版で置き換えて手元の複製を削除します。dismissNotice: trueは本パネルのメッセージを消します。
#最初から最後まで、3つの作業例
「本文を少し大きくして。ただし本は220ページ未満に収めて」:sandbox_get_state(212ページ)→ bodyText.fontSizeを"10.5pt"にするsandbox_set_config(219ページ)→ 文字の詰まったページをsandbox_render_pageで描いて確かめる → category: "typesetting"を渡したsandbox_get_warningsで新しいウィドウを探す → うまくいかなければ、最初の答えのfromの値でもう一度sandbox_set_config。
「第4章で検査が見つけたものを直して」:chapter: 4を渡したsandbox_get_warnings → 警告ごとに、そのlineの周りをsandbox_read_textで読み、そのpageをsandbox_render_pageで描く → sandbox_edit_textまたはsandbox_set_config → 空の答えが返るまで、もう一度sandbox_get_warnings。
「このWordファイルから本を作って、PDFをちょうだい」:action: "new_blank"を渡したsandbox_save_book → dryRun: trueを渡したsandbox_import_word → mappingを直し、destination: "book"で本番の読み込み → scope: "book"を渡したsandbox_get_warnings → format: "pdf"とscope: "book"を渡したsandbox_export。
#あなたの同意を求めるツール
元に戻せない操作をする6つのツールには、重大な操作の印(consequentialHint)が付いており、実行の前にブラウザーがあなたに確認を求められます。sandbox_remove_chapter、sandbox_delete_resource、sandbox_delete_book、sandbox_reset_to_original、sandbox_import_word(本全体を置き換えることがあります)、sandbox_answer(手元の本の複製を削除することがあります)です。迷うときは、先に.postextの複製を書き出すようエージェントに頼んでください。
読み取るだけのツールにはreadOnlyHintが付いています。ページ自身が書いたのではないテキスト(本の本文、取得したファイル)を答えに含むツールにはuntrustedContentHintが付いており、ブラウザーはそのテキストが指示として扱われないようにできます。
#制限
- すべてはブラウザーの中にとどまります:ツールが届くのは、Sandbox自身が届く範囲だけです。本はこのブラウザーの保存領域にあり、
urlで渡したファイルはページが取得するので、そのサーバーが許可している必要があります(CORS)。data:URLやbase64なら必ず使えます。 - 長い作業には時間がかかります:ツールはレイアウトを待ってから答えます。
wait: falseを渡すとすぐに答えます。長い本のPDFやEPUBには数分かかります。 sandbox_undo_textが取り消せるもの:ツールによる本文の編集(1回の呼び出しずつ)と、プレビュー上で行った編集です。本文エディターで入力した内容(エディター自身の取り消しで戻します)、章の追加や移動、デザインやリソースの変更は取り消せません。これらには、各答えのfromを使います。取り消しの履歴は、ページを再読み込みすると失われます。- 画面の本が対象です:ツールは開いている本に対して働きます。開かずに別の本に届くのは、
.postextファイルを書き出すsandbox_export、duplicateを渡したsandbox_save_book、sampleを渡したsandbox_reset_to_originalだけです。
#サイトのツール
Sandboxを含む、postext.devのすべてのページにあります。
site_get_context:画面に出ているページ、その言語とテーマ、ドキュメントのセクションとすべてのページ。site_search:ドキュメントとレシピ集を、語、設定名(bodyText.avoidOrphans)、ディレクティブ(::resource)で検索します。site_read_page:サイトのページを、画面のページを離れずにMarkdownとして読みます。site_open_page:ページを表示します。#headingを付けると、そのセクションに移ります。site_list_recipesとsite_open_recipe_in_sandbox:レシピ集のレシピを探し、編集できる本としてSandboxで開きます。site_lookup_term:用語集の用語(ウィドウ、カーニング、禁則など)。site_set_preferences:サイトの言語とテーマ。
ホームページから始めたエージェントは、レシピ集を検索し、レシピをSandboxで開き、そのままsandbox_*のツールで作業を続けられます。
#ツールの一覧
Sandboxが登録するときのまとまりで並べています。各ツールの詳しい説明とスキーマは、postextWebMcp.listTools()で得られます。
- 開いているもの:
sandbox_get_state。 - ページ:
sandbox_render_page、sandbox_inspect_pages、sandbox_inspect_point。 - 本文:
sandbox_read_text、sandbox_write_text、sandbox_edit_text、sandbox_undo_text、sandbox_select_text、sandbox_search_text、sandbox_manage_chapters、sandbox_remove_chapter。 - デザイン:
sandbox_get_config、sandbox_set_config、sandbox_find_setting、sandbox_reset_to_original。 - 表示:
sandbox_set_view、sandbox_go_to_page、sandbox_run_viewer。 - リソースとフォント:
sandbox_list_resources、sandbox_save_resource、sandbox_delete_resource、sandbox_list_fonts、sandbox_save_font。 - 漫画:
sandbox_inspect_comic、sandbox_edit_comic。 - 本とファイル:
sandbox_list_books、sandbox_open_book、sandbox_save_book、sandbox_delete_book、sandbox_import_book、sandbox_export。 - Word:
sandbox_import_word、sandbox_word_templates。 - 確認:
sandbox_answer。 - 検査:
sandbox_get_warnings。
#Sandboxを埋め込むとき
<PostextSandbox>はマウントされている間ツールを登録し、webmcp={false}でツールを登録しないようにできます(Propsを参照)。ホストのページは、同じモジュールを通じて独自のツールを加えられます。
import { registerWebMcpTools } from 'postext-sandbox/webmcp';
const controller = new AbortController();
registerWebMcpTools([
{
name: 'shop_list_titles',
description: 'The titles of this shop, with the id of the Postext project of each one.',
inputSchema: { type: 'object', properties: {}, additionalProperties: false },
annotations: { readOnlyHint: true },
execute: async () => ({ titles: await fetchTitles() }),
},
], controller.signal);
// controller.abort()でツールを取り下げるこれらのツールは、ブラウザーがWebMCPを提供していればWebMCPに登録され、window.postextWebMcpには常に登録されます。引数はinputSchemaと照合されます。