メインコンテンツへスキップ

Speedgrapherの紹介:Vibe WritingのためのMCPサーバー

· 13 分· loading · loading · ·
エージェント・コーディング
ダニエラ・ペトルザレク
著者
ダニエラ・ペトルザレク
Googleのシニアデベロッパーリレーションズエンジニア

はじめに
#

正直に告白すると、私はモノづくりが大好きなのですが、それに伴う定型作業(ボイラープレート)まで好きかというと、必ずしもそうではありません。新しい記事のアイデアは常にたくさんあるものの、構成を組み立て、自分の編集基準を満たしているか確認し、適切なトーンに仕上げるというプロセスは、時に骨の折れる作業に感じられることがあります。この記事は、ある技術仕様を深く読み解いたことをきっかけに、執筆プロセスに心地よい構造化をもたらすMCPサーバー、Speedgrapher を構築することになった物語です。

Speedgrapher への道のりは、前回の記事「GoDoctorの構築:Gemini CLIとGoでMCPサーバーを作成する」を公開した直後に始まりました。その記事では、Model Context Protocol (MCP) によってAIエージェントがいかにツールを利用できるようになるかという点に特化して解説しました。公開後、私はMCP仕様を改めてじっくり読み直してみました。そこで、以前は見落としていた小さな記述が目に留まりました。プロトコルは tools だけでなく、promptsresources も明示的に定義していたのです。ひらめきが走りました。メモやローカルファイル、GitHubリポジトリのあちこちに散らばっていたプロンプト集を、まったく同じプロトコルを使ってパッケージ化し、ポータブルに持ち運べるのではないかと気づいたのです。

実によい偶然でした。私がプロンプトサーバーの構想を練っていたその日、Gemini CLIチームが、MCPサーバーが公開するプロンプトをネイティブのスラッシュコマンドとして利用可能にする新機能を発表したのです。これにより、ポータブルなバックエンドツールキットという私のアイデアが、ターミナル上で直接動くファーストクラスで使いやすいUIを手に入れられることになりました。Speedgrapher のコンセプトは明確になりました。シンプルなスラッシュコマンドとして呼び出せる執筆ツールキットを束ねた、専用のMCPサーバーです。

Vibe Writing とは何か
#

Speedgrapher を構築した技術的な道のりに飛び込む前に、「バイブライティング(vibe writing)」という言葉で私が何を意味しているのかを少し説明させてください。「バイブコーディング(vibe coding)」という言葉を耳にしたことがある方も多いでしょう。これは、自然言語のプロンプトを使ってAIを導きながらコードを生成させる、最近ますます一般的になってきた開発手法を指します。開発者が大所高所の方向性を定め、AIが定型コードや細かな実装を担うという、流れるような対話的アプローチです。

「Vibe writing」は、この概念を言葉の世界へと自然に拡張したものです。私にとってそれは、孤独な執筆作業を、AIパートナーとのダイナミックで協力的な対話へと変えることを意味します。文構造や文法、完璧な言葉探しといった機械的な作業に足を取られることなく、伝えたい中心メッセージ — 生み出したい「バイブ(空気感・熱量)」 — に集中できるのです。私が最初の火種 — 大まかなアイデア、個人的な体験談、直面した厄介な課題 — を提示し、AIがそれを構造的で筋の通った物語へと形作る手助けをしてくれます。

この言葉を使ったのは私が最初ではありませんが、まだ生まれたばかりの新しい概念です。これはコンテンツ制作へのアプローチにおける根本的なシフトであり、完全な手作業から人間とAIの協調関係への移行を表しています。

まずはシンプルに:俳句ジェネレーター
#

どんな優れた技術探求も、まずは「Hello, World」から始まります。Speedgrapher における私の「Hello, World」は俳句(Haiku)でした。プロンプトをスラッシュコマンドとして公開できることを実証するための、手軽でリスクの少ない方法が必要だったのです。AIに詩を詠んでもらうこと以上にシンプルな検証があるでしょうか?

最初の試みは素朴なものでした。--theme 引数を取る /haiku プロンプトを作成し、プロンプト自体も "generate a haiku based on the theme %s" という単純なものでした。Gemini CLIを起動し、Speedgrapherプロジェクトをコンテキストとして読み込ませた状態で、こう入力しました。

/haiku --theme=flowers

その結果返ってきたのは……詩ではありませんでした。モデルはプロジェクト内のGoコードを見て、私のリクエストを「Speedgrapherに俳句機能を追加せよ」という指示だと解釈してしまったのです。そしてGoファイルの編集計画を立て始めました。私はすぐに ESC キーを押して処理を中断し、作戦を練り直すことにしました。

この経験は、プロンプトエンジニアリングにおける極めて重要な原則を思い出させてくれました。「曖昧さ(ambiguity)」と「コンテキスト(context)」のバランスを取る必要性です。私が作成するプロンプトの多くでは、モデルが柔軟に推論して情報を補完できるように、あえてある程度の曖昧さを残しています。たとえば /review プロンプトは、単に「私たちが作業してきた記事をレビューしてください」とだけ指示しています。DRAFT.md のような具体的なファイル名は指定していません。対話型ワークフローにおいて、この曖昧さは強力な道具になります。モデルは厳密で固定的なファイルパスがなくても、直近のやり取りから対象のテキストを自律的に特定できるからです。

しかし俳句の場合、その曖昧さに適切な制約がありませんでした。メインのコンテキストがGoプロジェクトだったため、モデルは論理的ではあるものの意図とは異なる結論 — 「コードを変更したいのだろう」 — を導き出してしまったわけです。モデルが間違っていたわけではなく、妥当な推論をしたに過ぎません。今回はコードと無関係な極めて具体的な結果を求めていたため、意図を明確にするコンテキストを与えて曖昧さを減らす必要がありました。

何度か試行錯誤を重ねた後、最終的に以下のプロンプトに落ち着きました。

// The final, working prompt for the haiku command.
prompt = fmt.Sprintf("The user wants to have some fun and has requested a haiku about the following topic: %s", topic)

これが意図を伝える最善の表現かどうかはわかりませんが、私の目的には見事に合致し、モデルはその後一貫して俳句を詠んでくれるようになりました。コアコンセプトの実証が完了したため、より実践的なプロンプトの構築へと進む準備が整いました。

執筆ツールキットの構築
#

俳句の実験によってコアコンセプトの正しさが確認できたので、より実践的な応用へと進みました。当時の私の GEMINI.md ファイルは、記事のレビュー、翻訳、アウトライン作成といった便利なプロンプトの集まりになっていたものの、ポータビリティがありませんでした。特定のプロジェクトに紐づいていたため、新しいプロジェクトを始めるたびにコピーし忘れることがよくあったのです。これらのツールをポータブルにするための次なる論理的一歩が、MCPサーバーでした。

まずは特によく使っていた3つのプロンプト — interviewreviewlocalize — を Speedgrapher に移行することから始めました。これらのプロンプトの核となるのは「編集ガイドライン」です。たとえばローカリゼーションのガイドラインには「技術用語は翻訳しない」というルールを含めており、当ブログがサポートする3つの言語間での一貫性を確保しています。このような「コードとしての編集ガイドライン(editorial guidelines as code)」を作成するアプローチは、コードに対するリンターのように、一定の文体やクオリティを維持する構造化されたシステムを構築する方法です。

Speedgrapher のプロンプトはすべて Gemini の支援を受けて生成したものですが、review プロンプトについては少し異なるアプローチを取りました。モデルに私の過去の記事を分析させ、私の執筆スタイルに基づいた編集ガイドラインの生成を依頼したのです。生成された初稿はしっかりしたものでしたが、今でも常に洗練を重ねているプロンプトです。

以下は、GitHub上の Speedgrapher ソースコードから直接埋め込んだプロンプトの最新版です。

	"context"
	"errors"
	"os"

	"github.com/modelcontextprotocol/go-sdk/mcp"
)

const reviewPrompt = `
You are a professional editor for a technical blog.
Your task is to review an article and ensure it meets our editorial guidelines.
Provide constructive feedback to the author on how to improve it.

主要なプロンプトが揃ったところで、私の仕事の他の重要な部分の自動化に取り掛かる時が来ました。

リーダビリティの重要性
#

テクニカルライターとしての最大の課題は、明快さ(clarity)と複雑さ(complexity)の間のスイートスポットを見つけることです。文章が単純すぎると幼稚に感じられ、複雑すぎると読めなくなってしまいます。リーダビリティとは単に平易にすることだけではなく、読者を引き込み、知的な刺激を与えることでもあるのです。

リーダビリティに関する朗報は、それが測定可能であるという点です。完璧な指標は存在しないものの、Gunning Fog Index(ガンニング・フォグ・インデックス) は基準値を把握するための優れたツールです。Gunning Fog Index は、文章を初見で理解するために何年間の正規教育が必要かを推定する可読性テストです。たとえばスコア12は、米国の高校3年生(シニア)相当の読解レベルであることを意味します。

このインデックスは、以下のアルゴリズムに基づいて計算されます。

  • 100語以上のテキストセクションを取り出す。
  • 平均文長(1文あたりの平均単語数)を算出する。
  • 「難解な単語(3音節以上の単語)」の数を数える。
  • 平均文長に、難解な単語の割合を加算する。
  • その結果に 0.4 を掛ける。

数学が好きな方向けに数式で表現すると、このアルゴリズムは以下のようになります。

\[ 0.4 \times \left[ \left( \frac{\text{words}}{\text{sentences}} \right) + 100 \left( \frac{\text{complex words}}{\text{words}} \right) \right] \]

Fog Indexの本来の意図はテキストの理解に必要な「教育年数」を推定することですが、教育年数という枠組みで考えるのはあまり実用的ではないと感じたため、自分のニーズに合わせてカスタマイズすることにしました。まず、特殊な例外ケースを無視して計算を単純化しました。このアルゴリズムで最も複雑(complex)な部分の一つは、何をもって単語が「複雑(complex)」であるかを定義する処理です(しゃれのようですが)。基本ルールでは3音節以上の単語を複雑とみなしますが、-ing-ed-es などの特定の語尾を無視するといった例外ケースが生じます。

この例外処理は、実装時に思いのほか多くの問題を引き起こしました。私にとって厳密な精度は必要なく、シンプルさを優先して複雑さを多少過大評価する程度で十分でした。そこで、すべての特殊ケースを無視し、音節のカウントに関して2つの基本ルールのみを採用しました。1) 単語内の音節数は母音グループの数で推定する、2) 複雑な単語とは3音節以上の単語である(例外なし)。

また、教育年数から実用的なアプローチへと焦点を移した分類体系も作成しました。

スコア分類説明
>= 22難解すぎる(Unreadable)ほとんどの読者にとって理解が困難。
18-21読みにくい(Hard to Read)専門家であってもかなりの労力を要する。
13-17専門家向け(Professional Audiences)専門知識を持つ読者に最適。
9-12一般向け(General Audiences)多くの読者にとって明快で親しみやすい。
< 9平易すぎる(Simplistic)幼稚、あるいは単純すぎると受け取られる可能性がある。

カスタマイズした Gunning Fog Index を fog ツールとして実装した後の最後のステップは、使いやすいインターフェースを用意することでした。fog ツールを呼び出して結果をわかりやすいフォーマットで提示する /readability プロンプトを作成しました。これは、「単一目的に絞ったツールを作り、それらを組み合わせてより強力で使いやすいワークフローを構築する」という Speedgrapher の設計指針に沿ったものです。

執筆ワークフローの自動化
#

個々のプロンプトは有用でしたが、理想のワークフローを実現するには、まだ自動化すべきプロセスが多く残されていました。その後の数回のイテレーションを通じてプロンプトを実践で試し、プロセスの隙間を洗い出しながら、新しいプロンプトの追加や既存プロンプトの微調整を行いました。現在使用しているプロンプトは以下のとおりです。

メインフロー

  • /interview: 記事の素材を集めるために著者にインタビューを行います。通常、執筆セッションの起点となります。
  • /outline: 現在のドラフト、コンセプト、またはインタビュー記録から構造化された構成案(アウトライン)を生成します。
  • /voice: ユーザーの文体やトーンを分析し、生成される文章にそれを反映させます。
  • /expand: 作業中の構成案やドラフトを、より詳細な記事へと拡張します。hint 引数を指定して、特定の段落やセクションを集中的に拡充することも可能です。
  • /review: 執筆中の記事を編集ガイドラインに照らしてレビューします。
  • /readability: Gunning Fog Index を用いて、直前に生成されたテキストの可読性を分析します。
  • /localize: 執筆中の記事を対象の言語に翻訳します。
  • /publish: 記事の最終版を公開します。

オプション

  • /context: 後続のコマンドのために、現在執筆中の記事をコンテキストに読み込みます。必要に応じてモデルに現在のドラフトを「思い出させる」ために使用し、全文を対象とする /readability/review などのコマンドの前に実行することがよくあります。
  • /reflect: 現在のセッションを分析し、執筆プロセスの改善点を提案します。プロンプトや編集ガイドラインを改善する際に役立ちます。

目指したのは、便利なコマンドの集まりから、シンプルなアイデアを洗練された多言語の公開記事へと導く、ひとつの合理化されたプロセスへと進化させることでした。

以下の図は、私のワークフローを簡略化して表したものです。

flowchart TD
    A[アイデア] -->|/interview| B[インタビュー記録]
    B -->|/outline & /voice| C[構造化された構成案]
    C -->|/expand| D[記事のドラフト]
    D -->|/review & /readability| E[推敲済みドラフト]
    E -->|/localize| F[ローカライズ版]
    F -->|/publish| G[公開された記事]

プロセスは、アイデアの核となるコンセプトを具体化する /interview から始まります。得られたインタビュー記録は /outline によって構造化された計画へと変換され、/voice によって私自身の執筆スタイルに合わせて調整されます。この土台ができあがったら、/expand でドラフトを肉付けし、/review/readability で推敲を重ねる反復ループに入ります。

記事が承認されたら、/localize で他言語版を作成し、/publish で公開プロセスを完了します。さらにオプションの /reflect プロンプトを使えば、セッションを分析して将来の改善のためのメモを生成し、継続的な改良のサイクルを回すことができます。

まとめ
#

リンターやテストを使ってコードに構造をもたらすのと同じように、クリエイティブなワークフローにも同様の原則を適用できます。執筆プロセスには、自動化できる反復作業が数多く存在します。自分専用のプロンプトツールキットを構築することで、定型作業をオフロードし、作品の核となるアイデアに集中できるようになります。

これこそが Speedgrapher のようなツールの真価です。「vibe writing」は書き手を置き換えるものではなく、執筆プロセスを拡張・強化するためのものです。そこにMCPサーバーを組み込むことで、混沌としがちなワークフローに役立つ構造化のレイヤーをもたらし、ベストプラクティスを確実に遵守させることができます。これはあらゆるAI支援プロセスに適用できます。自らのプロンプトを再利用可能でポータブルな資産として扱うことで、自らのプロセスとともに進化するシステムを構築し、プロンプトを1つずつ重ねながら、創作活動のクリエイティブな側面に集中できるようになるのです。

今後の展望
#

Speedgrapher の旅はまだまだ終わりません。現在のツールキットはテキストに特化していますが、次の論理的なステップはマルチモーダルへの対応です。ヒーロー画像を生成したり、テキストからより高度な図を作成したり、レイアウトの最適化を提案するツールの統合を検討しています。執筆以外のタスクをより多く処理できる個人用ツールキットを構築し続け、自分自身がコンテンツそのものに集中できるようにすることが目標です。

参考リソース
#

関連記事

AI時代のモダンな開発者ワークフロー

· 14 分· loading · loading
エージェント・コーディング
AIツールとシンプルな2軸の優先順位付けフレームワークを活用し、タスクの性質に応じて同期・非同期を使い分ける現代のモダンな開発者ワークフローを提案します。