🦎

MCPサーバーでまだ出来ないこと

に公開

最近の生成AIのトピックはもっぱらMCP(サーバー)がトレンドで、Zennでもすごい量の記事がかかれていたりいいねが大量にあったりという状況です。
自分もローカルでテストしてみて、AIが会社のバックログのデータを参照して回答を生成してくれることに感動しています。
一方でMCPはまだまだ開発途中の技術であり、まだ出来ないことも分かってきたので、自分の企業でMCPサーバーを導入しようと考えた際に生じる2つのハードルについて書いていこうと思います。

MCPサーバーをローカル外に建てられない

イントロダクションの以下の図で示されている通り、現在MCPサーバーはローカルに立ち上げて利用するようになっています。
せいぜい外部との通信で出来ることは、自分のコンピューター(Your Computer)から外部のAPIを叩いて情報をfetchするくらいです。

公式で紹介されているサーバーや、以下のような記事で紹介されている自作のMCPサーバーも、他人が利用するにあたってはローカルでnodeやDocker、npxを使ってサーバーを起動しないといけません。
https://zenn.dev/ubie_dev/articles/f927aaff02d618
https://zenn.dev/notahotel/articles/93c091713bb199
https://zenn.dev/ryoppippi/articles/1eb7fbe9042a88

これは開発者なら苦にならないですが、非エンジニアの人々が使おうとなるとかなりの障壁になります。具体的には以下の点が難しいんじゃないかと思います。

  • Docker,nodeの環境のセットアップ
  • claude_desktop_config.jsonなどのjsonファイルを編集すること

一方でMCPサーバーから恩恵をもらう点で考えると、開発者よりそれ以外の人々の方がより多くの恩恵を得られると考えています。
開発者が必要な知識の多くはPublicな公式Docs、StackOverflow、Githubのissuesに載っているためAIが回答してくれる確率が高い上、個別のルールなんかも .cursor/rulesなどの機能で用意できます。
開発者以外の人々の方が、就業規則等の企業ごとの固有のルールに基づく事務手続き、Backlogなどのプロジェクト管理といったPrivateなリソースにアクセスする必要が多く、MCPサーバーをより必要としているという構図になっています。つよつよエンジニアの皆さんが、MCPサーバーを社内ネットワーク等に設置してみんなで使えるようになるように開発してくれるのを祈ります。

ツールによってresourceやpromptが使えない

↓がツールごとのMCPサーバーの機能対応表です。
https://modelcontextprotocol.io/llms-full.txt
MCPサーバーの代表的な機能として以下の3つの機能がありますが、AIツールごとに対応がまちまちで、例えば愛用のCursorはToolsしか今のところ対応していません[1]。(参照したページ)

  • Tools:計算やメッセージ送信などのアクションを起こす
  • Resources:生成AIに渡すコンテクストが書かれたデータ E.g.自社のオウンドメディア、手順書
  • Prompts:コードレビューなどで使うような特定のプロンプトで処理してもらうようにすることで、consistentな品質のレスポンスが帰ってくるようにする

対応の差によって次のような困ったことが起こると思います。

対応してない機能のデバッグがやりにくい

CursorでMCPサーバーを立てている記事のように、サーバーをビルドしてCursor Settingsで登録、Agent機能で実行という形ですぐテストしたいとなった際に、対応してない機能のテストはClaude Desktopなどの別アプリでチェックする形になり、コードをコンテクストとしたAIチェックが出来ない苦しみがあります。
自分がBacklogのAPIを使ってバックログの情報取得、操作を臨機応変にしてもらうサーバーを作った際に、toolはCursorで実行できたので、例としてfetchにPATCHメソッドなどを必要に応じて渡さないといけない問題を発見してくれたりしました。このようなバグの発見が対応してない機能だと出来ない上、APIレスポンスの手前のエラーだった場合のログ取得が結構難しい[2]のもあって対応してない機能の入ったMCPサーバーの開発は結構大変そうです。

製品の流行りが対応速度でガラッと変わる可能性

今自分はCursorを使っていますが、それの代替となる製品が色々とあります。
https://zenn.dev/robustonian/articles/cursor_vs_cline
https://zenn.dev/ks0318/articles/6023a5b729cb7a
https://openalternative.co/alternatives/cursor

先ほどのMCP対応表で見てみると、Continue、Cline、Copilot-MCPの方がCursorよりも対応している機能が現在多いです。
もし今後MCPサーバーがすごく発展して、活用の有無で生産性が大きく変わるような事態になった場合に、対応が遅れた製品は一瞬で廃れるような気がしています。
そうなった場合個人開発なら移行するだけで良いのですが、企業となると値段以外の移行コストが、アカウント発行だったり非エンジニアのためのインストール・設定作業だったり色々とかかってしまうので、素早く対応しないと大きく損することになってしまいそうです。

最後に

MCPという標準化のおかげで、自分のようなよわよわエンジニアでも簡単にコンテクストをLLMに渡せる時代になってきました。自分だけでなくチームや組織全体をMCPサーバーを使って業務効率化したい!となった際に現在はこんな障害があるなあと触ってて気づいたので、是非ともつよつよ開発者の吉報を聞きたいところです。

おまけ:プロンプトからBacklogの操作をするコード例

EXAMPLE_TICKET-1の状態を完了にしてとでも入力すると、公開されているAPIを勝手に探索して、何度かfetchを繰り返して操作してくれるコード
envで環境変数を渡して利用します

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const BACKLOG_API_KEY = process.env.BACKLOG_API_KEY;
const BACKLOG_BASE_URL = process.env.BACKLOG_BASE_URL;


const server = new McpServer({
  name: "backlog-api",
  version: "0.0.1",
});

server.tool(
  "fetch_backlog_api",
  "引数で指定したBacklogのAPIを呼び出します",
  {
    route: z.string().describe("APIのURL"),
    method: z.string().optional().describe("HTTPメソッド(GET, POST, PATCH, PUT)"),
    body: z.string().or(z.object({})).optional().describe("リクエストボディ")
  },
  async ({ route, method = "GET", body }) => {
    try {
      const separator = route.includes('?') ? '&' : '?';

      const options = {
        method,
        headers: {
            'Content-Type': 'application/json',
        },
        body: typeof body === 'string' ? body : JSON.stringify(body),
      };
      const response = await fetch(BACKLOG_BASE_URL + route + separator + "apiKey=" + BACKLOG_API_KEY, options);
      const data = await response.json();
      
      return {
        content: [{
          type: "text",
          text: JSON.stringify(data)
        }]
      };

    } catch (error: unknown) {

      
      // エラー時も適切な形式で返却
      return {
        content: [{
          type: "text",
          text: JSON.stringify({ error: "API呼び出しに失敗しました" })
        }]
      };
    }
  }
);

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Example MCP Server running on stdio");
}

main().catch((error) => {
  console.error("Fatal error in main():", error);
  process.exit(1);
});
脚注
  1. MCP servers offer two main capabilities: tools and resources. Tools are availabe in Cursor today, and allow Cursor to execute the tools offered by an MCP server, and use the output in it’s further steps. However, resources are not yet supported in Cursor. We are hoping to add resource support in future releases. とのことなので期待して待ってます ↩︎

  2. 表示->出力->Cursor MCPなど ↩︎

Discussion