📝

ChatGPTのメッセージをPHPで受け取るだけのMCPサーバできた!Plusプランでも使える!(開発者モード)

に公開

Plusプランで自作MCPサーバが使えるようになった!けどスケジュール(タスク)は無理かも?


ちょっと前まで自作のMCPサーバを使うには、ProプランかBusiness(旧teamプラン)でしか使えなったはずですが、開発者モードがONだったら使えるよ!という神アプデがあったようです。

今の環境がPHPなので、とりあえず「ChatGPTから届いたメッセージをPHPで受け取る」だけのMCPサーバをChatGPTさんに作ってもらいました(ついでにプロンプトも作ってもらいました)

少しややこしいですが「MCPサーバ」と「実際に受け取るPHP」の2つファイル必要となります。

  1. https://example.com/mcp.php → ChatGPTの設定から、MCPサーバのURLとして追加する
  2. https://example.com/sample.php → 実際に受け取るPHPファイル($_POST['text']で取得)

1. 簡易MCPサーバ(mcp.php)※コピペ可

<?php
/**
 * 簡易MCPサーバ(URLとメッセージを受け取ってPOSTで渡すだけ)
 * 例えばここに置く:https://example.com/mcp.php
 */
if ($_SERVER['REQUEST_METHOD'] === 'GET') { header('Allow: POST', true, 405); exit; }
if ($_SERVER['REQUEST_METHOD'] !== 'POST') { http_response_code(405); exit; }

$in = json_decode(file_get_contents('php://input'), true);
if (!is_array($in)) { http_response_code(400); echo '{"error":"invalid json"}'; exit; }
if (!isset($in['id']) && (isset($in['method']) || isset($in['result']) || isset($in['error']))) { http_response_code(202); exit; }

$id = isset($in['id']) ? $in['id'] : null;
$method = isset($in['method']) ? $in['method'] : null;
$params = isset($in['params']) && is_array($in['params']) ? $in['params'] : [];

header('Content-Type: application/json; charset=utf-8');

function rpc_result($id, $result) {
  echo json_encode(['jsonrpc' => '2.0', 'id' => $id, 'result' => $result], JSON_UNESCAPED_UNICODE); exit;
}
function rpc_error($id, $code, $msg) {
  echo json_encode(['jsonrpc' => '2.0', 'id' => $id, 'error' => ['code'=>$code,'message'=>$msg]], JSON_UNESCAPED_UNICODE); exit;
}

if ($method === 'initialize') {
  rpc_result($id, [
    'protocolVersion' => '2025-03-26',
    'serverInfo' => ['name' => 'Vanilla PHP MCP', 'version' => '1.1.0'],
    'capabilities' => ['tools' => ['listChanged' => false]],
    'instructions' => 'Use tools.call("post_message") with {text, url}.'
  ]);
}

if ($method === 'tools/list') {
  rpc_result($id, [
    'tools' => [[
      'name' => 'post_message',
      'title' => 'POST model reply to URL',
      'description' => 'Posts the final reply to the specified URL as form field "text".',
      'inputSchema' => [
        'type' => 'object',
        'properties' => [
          'text' => ['type' => 'string', 'description' => 'Model final reply text'],
          'url'  => ['type' => 'string', 'description' => 'Destination webhook URL']
        ],
        'required' => ['text', 'url']
      ]
    ]],
    'nextCursor' => null
  ]);
}

if ($method === 'tools/call') {
  $name = isset($params['name']) ? $params['name'] : '';
  $args = isset($params['arguments']) && is_array($params['arguments']) ? $params['arguments'] : [];
  if ($name !== 'post_message') { rpc_error($id, -32602, 'Unknown tool'); }
  if (!isset($args['text']) || $args['text'] === '') { rpc_error($id, -32602, 'text is required'); }
  if (!isset($args['url']) || $args['url'] === '') { rpc_error($id, -32602, 'url is required'); }
  if (!filter_var($args['url'], FILTER_VALIDATE_URL)) { rpc_error($id, -32602, 'invalid url'); }

  $ch = curl_init($args['url']);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(['text' => (string)$args['text']], '', '&'));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_TIMEOUT, 10);
  curl_exec($ch);
  curl_close($ch);

  rpc_result($id, ['content' => [['type' => 'text', 'text' => 'ok']], 'isError' => false]);
}

rpc_error($id, -32601, 'Method not found');

2. 取得する(sample.phpの$_POST['text'])

<?php if($_SERVER['REQUEST_METHOD']==='POST'){ file_put_contents(dirname(__FILE__) . '/log.txt',($_POST['text']??'').PHP_EOL,FILE_APPEND); echo 'ok'; }

ひとまず、ChatGPTから受け取ったメッセージをlog.txtにfile_put_contentsするだけのやつです。

3. あとはChatGPTに投げるだけ!

最後にChatGPT側「設定→コネクタ→高度な設定→開発者モード」にすると「コネクタを参照する」の右あたりに「作成」が表示されるので、https://example.com/mcp.php を入れてください。

このチャットの方針:
- あなたは通常どおり回答を作成し、まずユーザーに表示します。
- その直後に MCP ツール post_message を 1 回だけ実行します。
- arguments は次のとおり:
  {
    "text": あなたが直前に画面へ表示した最終回答“全文”。スケジュールにより自動出力されたものも同様。Markdown/改行/コードブロックなどの整形はそのまま。先頭末尾の空白も削除しない。ツール出力やメタ情報は含めない。
    "url": "https://example.com/sample.php"
  }
- 失敗した場合はエラーメッセージをユーザーに短く知らせ、同一メッセージ内での再試行は 1 回まで。
- 1 ユーザーメッセージにつき 1 回だけ post_message を呼び、無限ループを避けるためツール実行結果の内容はユーザー回答に再度含めない。

これでChatGPTは

  1. 最初に https://example.com/mcp.php にアクセス
  2. 次に https://example.com/sample.php に$_POST['text']でメッセージを送る。

という手順を踏んでくれるようになります。

あとはDBに入れたり、メール送ったり、LINEで通知するなどしてください!

今のとこスケジュール(タスク)では使えなかった

2025年9月16日時点では、定期実行するためにスケジュールに入れても、{"error":"The bio tool is disabled..."} が帰ってきてしまい、これもChatGPTに聞いたところ以下の返答をいただきました。

結論:プログラム不具合ではなく、ChatGPT 側の制限です。
スクショの {"error":"The bio tool is disabled..."} は ChatGPT のメモリ用内部ツール(bio/memory) がタスク実行時に無効であることを示すエラーで、同じ実行環境では Developer Mode のリモート MCP ツールも使えません。通常チャットでは使えても、タスク(スケジュール実行)からは外部MCPを呼べないため、post_message が呼ばれず、あなたのサーバにもアクセスが来ません。

まだ開発段階で GPTs やプロジェクトなどでは利用できないですし、今後のアプデに期待したい!

Discussion