AI・AIエージェント活用 基礎知識集基礎知識集 / MCP の中身

MCPサーバーとは|実装の中身と事例で見る振る舞い


MCPサーバーは「魔法のクラウドサービス」ではなく、JSON-RPC でメッセージをやり取りするローカル / リモートのアプリケーションです。本記事では、プロトコル構造、3 つのプリミティブ(Tools / Resources / Prompts)、ライフサイクル、最小実装コード、公式 OSS サーバーの実例まで踏み込み、MCP サーバーの「振る舞い」を可視化します。

公開2026.05.11
最終更新2026.05.11
読了 20 分 / 約8,200
この記事をシェアポスト
AI × 業務活用MCP サーバーの中身

MCPサーバーとは

MCP(Model Context Protocol)の話になると「サーバーを立てる」「サーバーが提供する」とよく出てきますが、MCP サーバーが実際に何を動かしているのかは意外と整理されていません。OSS の modelcontextprotocol/servers には公式・コミュニティ製のサーバーが揃っており、いずれも JSON-RPC をベースにした素朴なアプリケーションとして実装されています。

C
結論
MCP サーバーは JSON-RPC で Tools / Resources / Prompts を公開するアプリ

MCP サーバーは特別な機械学習基盤ではなく、stdio・SSE・HTTP のいずれかで JSON-RPC メッセージを受け取り、(1) ツール、(2) リソース、(3) プロンプトテンプレートの 3 種を公開する普通のアプリケーションです。実装は TypeScript / Python / Java などの公式 SDK で数十行から書けます。

01.まず結論:JSON-RPC で 3 種を公開するアプリ

MCP サーバーの構造を一文でいうと「JSON-RPC でメッセージを受け取り、Tools・Resources・Prompts の 3 種類のプリミティブを公開するプロセス」です。AI クライアント(Claude Desktop / Claude Code / Cursor など)が、そのプロセスとメッセージをやり取りすることで「外部システムをつなぐ」が実現します。

関連記事

MCP実務入門|AIエージェントと社内ツールをつなぐ接続標準

本記事は実装の中身に踏み込みます。導入判断・権限境界・運用ステップは別記事で整理しています。

続きを読む

02.MCPサーバーの内部構造

MCP サーバーは 3 層構成で考えると整理しやすくなります。

役割実装の中身
トランスポート層クライアントとのバイト列のやり取りstdio(標準入出力) / SSE / Streamable HTTP
プロトコル層JSON-RPC 2.0 メッセージの解釈公式 SDK(TypeScript / Python / Java など)が担当
業務ロジック層実際の処理(API 呼び出し、DB 検索、ファイル読み書き)サーバー作者が自前で書く部分

トランスポート層(stdio / SSE / HTTP)

ローカルで動かす MCP サーバーは、ほとんどが stdio です。クライアントが子プロセスとして起動し、標準入出力でメッセージを送受信します。リモートサーバー(社内 SaaS、認証付きシステム)には SSE / Streamable HTTP が使われます。

プロトコル層(JSON-RPC 2.0)

メッセージは JSON-RPC 2.0 形式です。標準的なリクエスト 1 つは以下のような構造になります。

{
  "jsonrpc": "2.0",
  "id": 42,
  "method": "tools/call",
  "params": {
    "name": "search_customer",
    "arguments": { "query": "山田" }
  }
}

サーバーは同じ id で結果を返します。

{
  "jsonrpc": "2.0",
  "id": 42,
  "result": {
    "content": [
      { "type": "text", "text": "顧客ID:1023, 名前:山田太郎" }
    ]
  }
}

業務ロジック層

実装者が書く部分です。たとえば「顧客検索ツール」なら、社内 CRM の検索 API を呼び、結果を整形して返します。MCP プロトコル自体は中身を関知しません。

03.3つのプリミティブ:Tools / Resources / Prompts

MCP サーバーが公開できる項目は 3 種類に整理されています。

プリミティブ意味主な用途クライアント API
ToolsAI が呼び出す関数・操作検索、計算、CRM 更新、ファイル操作tools/list, tools/call
ResourcesAI が読み込む対象(ファイル・ドキュメント・レコード)社内ドキュメント、データベースレコードresources/list, resources/read
Prompts事前定義のプロンプトテンプレート「議事録要約テンプレ」「障害対応テンプレ」prompts/list, prompts/get
i
設計の使い分け
Tools と Resources を混同しない

「読む」が Resources、「実行する」が Tools です。ファイル取得を Resources 経由にすると、AI クライアントが取得可否を明示的に判断できます。逆にメール送信や CRM 更新は必ず Tools 側に置きます。書き込み系を Resources にしてはいけません。

04.ライフサイクル:initialize → list → call の実物

図解:MCP セッションの基本フロー
1initialize

クライアントが capabilities と protocolVersion を交換

2list

tools/list, resources/list, prompts/list で公開項目を取得

3call

tools/call などで個別呼び出し。引数を JSON で渡す

4result

戻り値(成功 or エラー)を JSON で受け取る

各ステップは JSON-RPC メッセージ 1 往復です。tools/list は通常初回のみ、tools/call はタスクごとに繰り返されます。

実際のメッセージ例を流れに沿って見ていきます。

① initialize(接続確立)

クライアントが最初に投げる初期化リクエストです。

-> client to server
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-11-25",
    "capabilities": {},
    "clientInfo": { "name": "claude-desktop", "version": "0.7.0" }
  }
}

<- server to client
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-11-25",
    "capabilities": {
      "tools": {},
      "resources": {},
      "prompts": {}
    },
    "serverInfo": { "name": "crm-mcp", "version": "1.0.0" }
  }
}

※ `protocolVersion` は MCP 仕様のリリース日(YYYY-MM-DD 形式)で、2024-11-05 / 2025-03-26 / 2025-06-18 / 2025-11-25 と段階的に更新されてきました。本記事は 2026 年 5 月時点で最新の 2025-11-25 を使っています。クライアントとサーバーが対応バージョンを互いに通知し合い、最も新しい共通バージョンを選ぶネゴシエーション仕様です。

② tools/list(公開ツールの取得)

-> client to server
{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }

<- server to client
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {
        "name": "search_customer",
        "description": "顧客名やメールから顧客レコードを検索する(読み取り専用)",
        "inputSchema": {
          "type": "object",
          "properties": {
            "query": { "type": "string" }
          },
          "required": ["query"]
        }
      }
    ]
  }
}

③ tools/call(実行)

-> client to server
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "search_customer",
    "arguments": { "query": "山田 太郎" }
  }
}

<- server to client
{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      { "type": "text", "text": "顧客ID:1023 / 山田太郎 / yamada@example.com" }
    ],
    "isError": false
  }
}

AI はこの結果を見て、次の判断(さらに別ツールを呼ぶ、ユーザーに回答する、など)を行います。

05.最小実装コード(TypeScript SDK)

公式 TypeScript SDK( modelcontextprotocol/typescript-sdk)を使うと、トランスポートと JSON-RPC は SDK が引き受けるので、業務ロジックだけ書けば済みます。

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";

const server = new Server(
  { name: "crm-mcp", version: "1.0.0" },
  { capabilities: { tools: {} } },
);

// ツール一覧を返す
server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: "search_customer",
      description: "顧客名やメールから顧客レコードを検索する(読み取り専用)",
      inputSchema: {
        type: "object",
        properties: { query: { type: "string" } },
        required: ["query"],
      },
    },
  ],
}));

// ツール実行
server.setRequestHandler(CallToolRequestSchema, async (req) => {
  const { name, arguments: args } = req.params;
  if (name !== "search_customer") {
    return { content: [{ type: "text", text: "unknown tool" }], isError: true };
  }
  const query = args?.query ?? "";
  // ここで実際の CRM API を叩く(疑似コード)
  const hit = await crm.findByQuery(query);
  return {
    content: [{ type: "text", text: `顧客ID:${hit.id} / ${hit.name}` }],
    isError: false,
  };
});

// stdio で起動
const transport = new StdioServerTransport();
await server.connect(transport);

Python SDK でもほぼ同じ構造で実装できます( modelcontextprotocol/python-sdk)。

06.公式・OSS の代表的なサーバー事例

公式リポジトリの modelcontextprotocol/servers に並んでいる代表的なサーバーと、その振る舞いを並べます。これらは MCP サーバーが実務で「何をしているか」の素直なサンプルです。

サーバー公開する Tools / Resources の例振る舞いの中身
filesystemread_file / write_file / list_directory / search_filesAI クライアントが起動時に許可したディレクトリ配下のファイルを操作。書き込み許可は明示する
githubsearch_repositories / create_issue / get_pull_request / merge_pull_requestGitHub REST API のラッパー。トークンは環境変数で渡し、API スコープでさらに制限
slacklist_channels / post_message / search_messagesSlack Bot API のラッパー。bot token とチャンネル ID で範囲を制御
postgresquery(読み取り専用 SQL)/ schemaPostgreSQL に直接接続し、SELECT のみ許可するなどの安全策を実装に組み込み
brave-searchbrave_web_search / brave_local_searchBrave Search API を呼び、結果を整形して返す
puppeteernavigate / screenshot / click / fill / evaluateヘッドレス Chrome を内部で起動し、AI からの指示でブラウザ操作
memory(公式)create_entities / read_graph / search_nodesローカルのナレッジグラフに対する追記・検索。AI 自身の「メモリ」用途
i
読むと振る舞いが分かる
ソースは公式リポジトリで全部公開

上記サーバーはすべて OSS でソースが公開されています。たとえば filesystem サーバーは「許可ディレクトリ内のファイル操作だけ受け付ける」というシンプルな約束で実装されており、コードを読むと「AI クライアントから来た JSON-RPC を fs API に橋渡ししているだけ」だと分かります。MCP サーバーは魔法ではなく、API ラッパー + 権限ガードの薄い層です。

07.トランスポート方式の違いと選び方

方式向く用途認証・運用代表例
stdioローカル実行、個人 PC で動く AI クライアントプロセス起動時の環境変数で認証情報を渡すClaude Desktop からの filesystem / github サーバー起動
SSE / Streamable HTTP社内 SaaS・リモートサーバーHTTP 認証ヘッダ、OAuth、API キー社内認証付き MCP サーバー、共有チームでの利用

stdio は「ローカルプロセス同士のやり取り」なので、認証情報をネットワークに流さずに済むのが利点です。一方、複数ユーザーで共有する場合や、社内 SaaS から接続する場合は SSE / HTTP の方が運用しやすくなります。

08.認証・セキュリティ・運用注意

観点実装側で必ずやること外すと起きること
認証情報環境変数 / Secrets Manager から読み込み、ログに出さない鍵が AI 出力や監査ログに混入し漏洩
スコープ制限GitHub なら repo 単位、Slack なら channel 単位で絞る別プロジェクトのデータも読まれてしまう
副作用ツール削除・送信系は別ツールとして分離、説明にも明示AI が誤呼び出しで本番反映
入力検証JSON Schema + サーバー側で再検証AI が捏造した引数で API を不正に叩く
監査ログtools/call の name / args / 結果サマリを記録事故時の追跡ができない
失敗時の戻りisError: true と原因テキストを返す無限リトライ・暴走の原因
関連記事

AIセキュリティ・権限設計|エージェントに何を触らせ、何を触らせないか

MCP サーバー側の権限設計と、AI クライアント側の境界設計はセットで考えます。

続きを読む
関連記事

AIとデータ連携|業務システムと繋ぐ3つの役割と全体像

MCP サーバーが公開する Tools が呼ばれる Tool Use の境界は §02-1 で詳しく整理しています。

続きを読む
関連記事

AIエージェントの外部接続入門|ツール利用・MCP・RAGの違いと設計図

MCP / Tool Use / RAG の役割分担を全体像で把握できるピラー記事です。

続きを読む

09.よくある質問(FAQ)

MCP サーバーはクラウドに置く必要がありますか?

用途次第です。個人 PC で完結するなら stdio で動くローカルサーバー、複数ユーザー / 社内 SaaS / 認証付きシステムに統合するならリモートの SSE / Streamable HTTP サーバーが向きます。両方とも公式仕様で対応されており、選択は運用要件次第です。

TypeScript / Python 以外でも MCP サーバーを書けますか?

書けます。公式 SDK は TypeScript / Python / Java / Kotlin / C# / Swift などに広がっています。プロトコルは JSON-RPC 2.0 なので、SDK が無い言語でも仕様に従って実装可能です。社内システムの実装言語に合わせて選びます。

Resources と Tools の違いは何ですか?

Resources は「読む対象(ファイル・ドキュメント・レコード)」、Tools は「実行する操作(関数呼び出し)」です。ファイル取得は Resources、ファイル削除や API 呼び出しは Tools。書き込み・送信などの副作用は必ず Tools 側で扱い、Resources で実行しないのが約束です。

MCP サーバーは AI を内部で持っていますか?

持っていません。AI / LLM 本体は AI クライアント(Claude Desktop / Claude Code / Cursor 等)側にあり、MCP サーバーは「外部 API や DB への橋渡し」を担うだけの普通のプロセスです。MCP サーバー単独で AI が動作することはありません。

公式 OSS の MCP サーバーをそのまま本番で使えますか?

汎用サーバー(filesystem / github / slack / postgres など)は社内ガイドライン・コンプライアンスに合うか確認してから採用します。社内独自業務(自社 CRM、独自 API、社内 DB)は、汎用サーバーが存在しないので自社で実装するのが現実的です。

MCP サーバーをデバッグする方法は?

JSON-RPC リクエスト / レスポンスのログを別ファイルに記録するのが基本です。公式の MCP Inspector(@modelcontextprotocol/inspector)を使うと、ブラウザ UI 上で接続テスト・ツール呼び出し・戻り値の可視化ができ、実装中の動作確認が大きく楽になります。

10.まとめ

MCP サーバーは「JSON-RPC でメッセージを受け取り、Tools・Resources・Prompts を公開する普通のアプリケーション」です。トランスポート層・プロトコル層は公式 SDK が引き受け、実装者が書くのは業務ロジック層だけ。最小実装は数十行で、modelcontextprotocol/servers に並ぶ公式 OSS(filesystem / github / slack / postgres / puppeteer / memory など)が「MCP サーバーが実際に何をしているか」のサンプルとして読める状態です。

運用では、認証情報・スコープ・副作用ツール・入力検証・監査ログ・失敗時の戻りの 6 点を実装側でしっかり設計するのが基本です。MCP は接続標準であって安全装置ではない、という前提で組み立てます。

お問い合わせ

社内向け MCP サーバーの設計・実装を支援します

AI 活用や AI エージェント導入のご相談、PoC、伴走支援をご検討の方は、お気軽にお問い合わせください。

お問い合わせはこちら

AI・AIエージェント活用 基礎知識集

一覧に戻る →
この記事をシェア
澤田 翔太(Shota Sawada)
この記事を書いた人

澤田 翔太

株式会社クリプタル 代表取締役

1988年生まれ、慶應義塾大学卒。創業メンバーとして関わった株式会社セールスサポートを株式会社ネオマーケティング(東証STD 4196)に売却。株式会社クリプタルでも複数の事業立ち上げと売却を経験し、2022年9月には婚活・恋愛メディア「シッテク」「婚活会議」を株式会社ベビーカレンダー(東証GRT 7363)へ売却。現在はAI業務支援事業、TANTOU事業、グロースハック支援事業、メディア事業、SEOコンサルティング事業を手がける。