fix_widget_handlers.py•5.28 kB
#!/usr/bin/env python3
"""
公式サンプルに合わせてリソースハンドラーを追加するスクリプト
"""
with open('/home/ubuntu/mcp-omotenashi/server.mjs', 'r', encoding='utf-8') as f:
lines = f.readlines()
# 修正1: import に ListResourcesRequestSchema と ReadResourceRequestSchema を追加
for i, line in enumerate(lines):
if 'isInitializeRequest, ListResourcesRequestSchema' in line:
# 既に ListResourcesRequestSchema がある場合、ReadResourceRequestSchema を追加
if 'ReadResourceRequestSchema' not in line:
lines[i] = line.replace(
'ListResourcesRequestSchema',
'ListResourcesRequestSchema, ReadResourceRequestSchema'
)
print(f"✓ 修正1完了: {i+1}行目に ReadResourceRequestSchema を追加")
break
elif 'isInitializeRequest' in line and '@modelcontextprotocol/sdk/types.js' in line:
# ListResourcesRequestSchema も ReadResourceRequestSchema も無い場合
if 'ListResourcesRequestSchema' not in line:
lines[i] = line.replace(
'isInitializeRequest',
'isInitializeRequest, ListResourcesRequestSchema, ReadResourceRequestSchema'
)
print(f"✓ 修正1完了: {i+1}行目に両スキーマを追加")
break
# 修正2: registerResource の直後(return server; の前)に2つのハンドラーを追加
handler_code = """
// ChatGPTがリソース一覧を取得できるようにする(公式サンプルに準拠)
server.setRequestHandler(
ListResourcesRequestSchema,
async () => ({
resources: [{
uri: "ui://widget/video-qr-display.html",
name: "Video QR Widget",
description: "動画プレイヤーとQRコードを表示するウィジェット",
mimeType: "text/html+skybridge",
_meta: {
"openai/outputTemplate": "ui://widget/video-qr-display.html",
"openai/widgetAccessible": true,
"openai/resultCanProduceWidget": true
}
}]
})
);
// ChatGPTがリソースの中身を読み込めるようにする(公式サンプルに準拠)
server.setRequestHandler(
ReadResourceRequestSchema,
async (request) => {
if (request.params.uri === "ui://widget/video-qr-display.html") {
return {
contents: [{
uri: "ui://widget/video-qr-display.html",
mimeType: "text/html+skybridge",
text: widgetHtml,
_meta: {
"openai/widgetDescription": "動画プレイヤーとQRコードを表示するウィジェット",
"openai/widgetDomain": "https://chatgpt.com"
}
}]
};
}
throw new Error(`Unknown resource: ${request.params.uri}`);
}
);
"""
for i, line in enumerate(lines):
if line.strip() == 'return server;' and 'createMcpServer' in ''.join(lines[max(0,i-100):i]):
# return server; の直前に挿入
lines.insert(i, handler_code)
print(f"✓ 修正2完了: {i}行目にリソースハンドラーを追加")
break
# 修正3: ツールの _meta に resultCanProduceWidget: true を追加
for i, line in enumerate(lines):
if '"openai/outputTemplate": "ui://widget/video-qr-display.html"' in line:
# 次の数行を確認して、resultCanProduceWidget がなければ追加
next_lines = ''.join(lines[i:i+5])
if 'resultCanProduceWidget' not in next_lines and '"openai/toolInvocation' in next_lines:
# toolInvocation の前に挿入
for j in range(i+1, min(i+5, len(lines))):
if '"openai/toolInvocation' in lines[j]:
indent = lines[j][:len(lines[j]) - len(lines[j].lstrip())]
lines.insert(j, f'{indent}"openai/resultCanProduceWidget": true,\n')
print(f"✓ 修正3a完了: {j}行目に resultCanProduceWidget を追加(ツール定義)")
break
break
# 修正4: ツールの返り値の _meta に resultCanProduceWidget: true を追加
for i, line in enumerate(lines):
if '"openai/widgetAccessible": true' in line and '_meta' in ''.join(lines[max(0,i-5):i]):
# この行の後に resultCanProduceWidget を追加
indent = line[:len(line) - len(line.lstrip())]
if 'resultCanProduceWidget' not in ''.join(lines[i:i+3]):
lines.insert(i+1, f'{indent}"openai/resultCanProduceWidget": true\n')
print(f"✓ 修正4完了: {i+1}行目に resultCanProduceWidget を追加(返り値)")
break
# ファイルに書き込む
with open('/home/ubuntu/mcp-omotenashi/server.mjs', 'w', encoding='utf-8') as f:
f.writelines(lines)
print("\n全ての修正が完了しました!")
print("\n=== 追加した機能 ===")
print("1. ListResourcesRequestSchema ハンドラー(リソース一覧)")
print("2. ReadResourceRequestSchema ハンドラー(リソース読み込み)")
print("3. resultCanProduceWidget: true フラグ")
print("\nこれで公式サンプルと同じ構造になりました。")