HSP3.7RC1で標準入出力型mcpサーバーを作ってみた

# 概要

mcpサーバーにはローカルで動作するstdio型とネットワークごしにアクセスできるstreamable HTTP型がありますが
stdio型は標準入出力において改行で区切られたjsonメッセージのやり取りができれば実装可能です。
今回はHot Soup Processor 3.7 RC1で、Win11のローカルPCで動作するmcpサーバーを実装してみました。
たまねちゃんの挨拶を回答する機能を提供します。
引数に時刻の時を指定して時刻によって内容を変更できるようにします。

なお、ちゃんとしたデータチェックや親切なエラー情報、UTF-8入力対応などは今回は実装していません。

mcpホストとして Windows 11 Home の Visual Studio Code 1.100.3 を使用して動作したことがあります。

# 準備

## HSP3のコード2ファイルとstart.axファイル

今回は .exe ファイルは作成せずに`start.ax`ファイル作成からセッティングします。
`C:/path/to`フォルダに`json.hsp`と`mcpsrv.hsp`を作成し
HSP3エディタで下記のコードを入力し保存します。

https://github.com/hta393939/hsp-alacarte/blob/feature/qiita1/mcp/json.hsp

https://github.com/hta393939/hsp-alacarte/blob/feature/qiita1/mcp/mcpsrv.hsp

`mcpsrv.hsp`のタブでHSPエディタのGUIメニューから「HSP」→「START.AXファイル作成」を実行します。
これで`C:/path/to/start.ax`ファイルが作成されます。

## vscode への設定

vscodeで適当なプロジェクトフォルダに`.vscode`フォルダを作成し
その中に`mcp.json`ファイルを作成します。

```json
{
  "servers": {
    "tamane-server": {
      "type": "stdio",
      "command": "C:/hsp37/hsp3cl.exe",
      "args": ["C:/path/to/start.ax"]
    }
  }
}
```

args の第一引数には`C:/path/to/start.ax`を指定します。
vscode上では`"tamene-server"`上にボタンが追加されます。

|tamane-server開始前|
|:-:|
|![tama6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213145/0da073cf-f217-4787-a460-c85369ec027d.png)|
|※1回実行済みだとキャッシュの表示が追加されます|

開始 Start をクリックしてください。
mcpサーバーが正しく実装されていると以下のような状態になります。

|tamane-server開始後|
|:-:|
|![tama7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213145/c4d29440-05ca-4827-8d0b-87b5956a1d12.png)|
|Runningに状態が変化したら成功です|

# vscodeのchatでの問い合わせ

vscodeの「Open Chat」でチャットを開きます。
Ask または Edit を エージェント Agent モードへ変更します。
ここで「たまねちゃんの昼の挨拶を教えて」と入力します。
実行確認が出ますので 続行 または Continue をクリックします。
さらに「たまねちゃんの深夜の挨拶」と入力すると
別な挨拶が返ってきます。

|実行例1|
|:-:|
|![tama1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213145/889264d4-96c5-4cfb-b5f0-e1e3932c4461.png)|
|Copilotが昼を適切に12時と読み替えてmcpサーバーに問い合わせをしようとします|

|実行例2|
|:-:|
|![tama2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213145/c5a69ee1-8060-461b-9639-fb5cf2296076.png)|
|Ranの部分を展開するとmcpサーバーからの応答が Output または 出力 に表示されます|

|実行例3|
|:-:|
|![tama3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213145/4ac85aed-0559-459a-9e48-3ad2fd1ac232.png)|
|深夜は2時|

|実行例4|
|:-:|
|![tama4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213145/4d398601-cd0e-4df7-9af5-b75d668503c3.png)|
|12時とは異なる挨拶を返します|


Running であっても mcpサーバーに問い合わせにいかない場合は
\+ ボタンから New Chat として始めると
問い合わせにいくことがあります。

今回は挨拶だけ応答する tools を実装しましたが
目的に応じてローカルPCで実行する tools も実装できると思います。

`start.ax`ではなく .exe の実行形式を作成する場合は
`command`に作成後の .exe ファイルのパスを指定します。
その場合には .exe ファイルと同一フォルダに`hspinet.dll`を配置する必要があります。

# コードの解説

`json.hsp`はHSP3でのjsonアクセスのヘルパー関数実装です。
`hspinet`から提供されている関数のままでは下へオブジェクトを潜っていくのが面倒だったのでドット表記で書けるようにしてあります。

`mcpsrv.hsp`が実際の標準入出力とパース、応答作文などになります。

HSP3で標準入出力を扱うコンソールモードにするには`hsp3cl.as`を使用します。
`hsp3cl.as`をインクルードすると`input`が標準入力の取得として、`mes`が標準出力への書き出しとして動作するようになります。
stdio型mcpサーバーではメッセージが改行区切りなので
入力は改行ごとになるように`input`のオプションを指定し、
出力文はjsonを文字列に変換した後、改行を削除し、メッセージの最後にだけ改行を追加しています。
UTF-8出力したいのでWin32APIでのコードページの変更と
書き出し時に`mes`ではなくWin32APIの`WriteFile`で
UTF-8エンコードされたバイナリとして標準出力に書き出しています。
※`hsp3utf.as`を使用したら`input`も`mes`もそのままでUTF-8入出力対応になるかもしれませんが今回は試していないです。

挨拶の内容を応答する箇所は以下になります。

https://github.com/hta393939/hsp-alacarte/blob/feature/qiita1/mcp/mcpsrv.hsp#L94

`hours`パラメータの範囲によって返す文字列を変更しています。

# 参照

- [プログラミング言語 HSP3 公式](https://hsp.tv/)
- [Visual Studio Code](https://code.visualstudio.com/)
- [Model Context Protocol](https://modelcontextprotocol.io/)