Novita AI で最初の MCP サーバーを構築する方法

Novita AI で最初の MCP サーバーを構築する方法

Model Context Protocol (MCP) は、AI 分野で最も話題になっている概念の 1 つになりつつあります。比較的新しいにもかかわらず、すでに開発者や大手テクノロジー企業の注目を集めています。

Anthropic によって作成された MCP は、HTTP などの他のプロトコルと同様のオープン標準プロトコルです。ただし、HTTP がサーバーと Web ブラウザ (または HTTP クライアント) を介してユーザーをリソースに接続するように設計されているのに対し、MCP は大規模言語モデル (LLM) を外部ツールやデータに接続するように設計されています。

チャットボットがあり、GitHub にアクセスできるようにしたいとします。ユーザーがチャットボットを使用して、Issue の作成、クローズ、コメントの追加、既存のプルリクエストの表示などを行えるようにしたいとします。チャットボットがこれらのアクションをすべて実行できるようにするには、ツールへのアクセスが必要です。

ここで MCP サーバーの出番です。

MCP サーバーは、チャットボットが内部の LLM を使用して呼び出し、これらの機能にアクセスできるようにするいくつかのツールをホストします。GitHub の場合、公式の GitHub MCP サーバーを使用して、上記のすべてのタスクを実行できます。

この記事では、Novita API を使用して MCP サーバーを構築します。この MCP サーバーを使用すると、MCP プロトコルをサポートするあらゆるアプリケーションが、Novita で利用可能なすべての LLM にアクセスし、画像を生成し、動画を作成し、音声合成を実行できるようになります。

MCP アーキテクチャを理解する

MCP アーキテクチャ

MCP アーキテクチャ [出典]

MCP アーキテクチャは、典型的なクライアント-サーバー構成に似ています。4 つの重要なコンポーネントがあります。

  • MCP クライアント
  • MCP サーバー
  • MCP トランスポート
  • MCP ホスト

MCP クライアント

MCP クライアントは、AI アプリケーションと MCP サーバー間の通信ゲートウェイとして機能します。この通信が確立されると、アプリケーションはサーバーが持つすべてのツールとリソースにアクセスできるようになります。

MCP サーバー

MCP サーバーは、クライアントが AI アプリケーションに提供できるすべてのツールとデータをホストします。次のものをホストします。

  • ツール
  • リソース
  • プロンプト

ツール

ツールは、LLM に通常はない外部機能を提供します。たとえば、時刻を教える、データベースを更新および読み取る、天気を取得するなどです。これらのツールは、基本的にプログラマが定義した関数であり、呼び出すことができます。

MCP サーバーは複数のツールをホストできます。これらのツールにより、LLM は実行可能なアクションのためにエージェントとして機能できるようになります。

ツールはエージェントによって管理され、使用中に人間の監視がオプションで含まれる場合があります。副作用を引き起こすため、HTTP プロトコルの POST リクエストに似ています。

リソース

リソースは、AI アプリケーションにデータを提供する読み取り専用の情報です。副作用を引き起こさないことを意図しているため、HTTP GET リクエストに類似しています。リソースはアプリケーションによって管理されることを意図しており、アプリケーションはユーザーまたはエージェントがどのように操作するかを決定します。リソースの例としては、ファイルの内容、API 応答、データベースのレコードなどがあります。

プロンプト

MCP サーバーはプロンプトテンプレートをホストできます。これらのプロンプトにより、ユーザーは MCP サーバーからプロンプトを取得し、AI アプリケーションで使用できます。プロンプトはユーザーによって管理され、ユーザーはエージェントに提供するプロンプトを決定します。

これらすべてが MCP サーバーを構成します。この記事では、MCP サーバーで最も広く使用されている部分であるツールのみを実装します。

MCP トランスポート

MCP トランスポートとは、MCP クライアントが MCP サーバーと通信する方法を指します。この通信は、クライアントとサーバーの両方が同じマシンで実行されている場合にローカルで発生することも、別々のデバイス上にある場合にリモートで発生することもあります。MCP は現在、2 つの主要なトランスポートメカニズムをサポートしています。

  • STDIO: このモードでは、MCP サーバーとクライアントは同じマシン上で実行され、標準入力と標準出力を介して通信します。
  • SSE: このモードでは、MCP サーバーは HTTP 上で実行されます。サーバーへのメッセージの送信には HTTP POST が使用され、サーバーからクライアントへのメッセージの送信には Server-Sent Events が使用されます。
  • Streamable HTTP: このモードも HTTP を使用しますが、HTTP GET および POST リクエストに依存します。サーバーからクライアントに複数のメッセージをストリーミングする必要がある場合にのみ、SSE にフォールバックします。

標準入出力

STDIO を使用した MCP トランスポート

STDIO を使用した MCP トランスポート [出典]

MCP クライアントとサーバーは、標準入力と標準出力 (STDIO) を介して通信できます。STDIO を使用する場合、クライアントとサーバーの両方が同じマシン上で実行されています。クライアントはすべてのリクエストを stdin に書き込み、サーバーは応答を stdout に書き込みます。

ストリーム可能な HTTP

Streamable HTTP を使用した MCP トランスポート

Streamable HTTP を使用した MCP トランスポート [出典]

Streamable HTTP を使用すると、MCP クライアントとサーバーは HTTP 経由で通信できます。クライアントからリクエストを送信し、サーバーから応答を受信するために HTTP POST メソッドを使用します。必要に応じて、Server-Sent Events (SSE) に切り替えて、サーバーからクライアントにメッセージをストリーミングすることもできます。

Streamable HTTP は、クライアントとサーバー間のリモート通信に適しており、非推奨の MCP SSE トランスポートの置き換えとして機能します。

MCP ホスト

MCP が典型的なクライアント-サーバーアーキテクチャと異なる点は、ホストの役割です。MCP 仕様では、これをクライアント-ホスト-サーバーアーキテクチャとして定義しています。これは、クライアントとホストがアーキテクチャのフロントエンドを構成するためです。MCP ホストは、次の 2 つの重要なコンポーネントで構成されます。

  • MCP クライアント
  • 大規模言語モデル

MCP クライアントの役割は、LLM が必要とするツール、リソース、プロンプトをサーバーから取得することです。リソースが収集されると、それらはモデルのコンテキスト内に配置されます。単一の MCP ホストは複数のクライアントを持つことができ、それぞれが独自の MCP サーバーに接続されます。

MCP ホストは、ユーザーが作業しているアプリケーションと見なすこともでき、他の機能を実行する場合もあります。たとえば、Claude Desktop はチャットボットとして機能する MCP ホストであり、Cursor は IDE としても機能する MCP ホストであり、Claude Code は AI コーディングエージェントとして設計された MCP ホストです。

MCP サーバーを操作する

MCP サーバーの構築に入る前に、既存の MCP サーバーを操作する方法を見てみましょう。Python MCP SDK を使用して novita-mcp-server と対話します。

この記事の執筆時点では、novita-mcp-server は次のツールを提供しています。

  • すべての Novita クラスターを一覧表示するツール
  • Novita GPU インスタンス製品を一覧表示するツール
  • 実行中のすべての GPU インスタンスを一覧表示するツール
  • 新しい GPU インスタンスを作成するツール

STDIO を介して MCP サーバーに接続し、サーバーで利用可能なすべてのツールを一覧表示する簡単なスクリプトを作成して、これを確認してみましょう。

まず、MCP SDK をインストールします: pip install “mcp[cli]”

SDK をインストールしたら、client.py という名前のファイルを作成します。次に、必要なインポートをすべて行います。

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
import os

次に、StdioServerParameters を使用して、stdio 経由で MCP サーバーを起動するためのパラメーターを設定します。novita-mcp-server は Node.js で実装されているため、これを使用するには npx コマンドで実行する必要があります。また、Novita API キーを環境変数 NOVITA_API_KEY に保存する必要があります。

# stdio 接続のサーバーパラメーターを作成
server_params = StdioServerParameters(
   command="npx",
   args=["-y", "@novitalabs/novita-mcp-server"],
   env={"NOVITA_API_KEY":  os.environ["NOVITA_API_KEY"]},
)

次に、非同期関数を作成しましょう。関数内で、サーバーパラメーターを stdio_client 関数に渡します。これにより、読み取りストリームと書き込みストリームを返すコンテキストが作成されます。これらのストリームにより、それぞれ stdio からの読み取りと stdio への書き込みが可能になります。

async def run():
   async with stdio_client(server_params) as (read, write):
       async with ClientSession(read, write) as session:
           # 接続を初期化
           await session.initialize()

           # 利用可能なツールを一覧表示
           tools = await session.list_tools()
           print("利用可能なツール:", tools)

これらのストリームは、ClientSession クラスを使用してセッションを作成するために使用されます。セッションを作成したら、それを初期化し、サーバー上のすべてのツールを一覧表示できます。

このプログラムを実行するには、asyncio ライブラリを使用して run 関数を呼び出すだけです。以下が完全なコードです。

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
import os

# stdio 接続のサーバーパラメーターを作成
server_params = StdioServerParameters(
   command="npx",
   args=["-y", "@novitalabs/novita-mcp-server"],
   env={"NOVITA_API_KEY":  os.environ["NOVITA_API_KEY"]},
)

async def run():
   async with stdio_client(server_params) as (read, write):
       async with ClientSession(read, write) as session:
           # 接続を初期化
           await session.initialize()

           # 利用可能なツールを一覧表示
           tools = await session.list_tools()
           print("利用可能なツール:", tools)

if __name__ == "__main__":
   import asyncio

   asyncio.run(run())

スクリプトを実行すると、Novita MCP サーバー上のすべてのツールを確認できます。

この例は、MCP クライアントの使用方法を示しています。この例に LLM を追加して、効果的にホストに変換することもできますが、このチュートリアルの焦点は MCP サーバーを構築することです。

FastMCP を使用した MCP サーバーの構築

Python MCP SDK には、MCP サーバーを構築する 2 つの方法があります。1 つは低レベルサーバーを使用する方法で、もう 1 つは FastMCP を使用する方法です。FastMCP は MCP Python SDK 内のクラスであり、FastAPI から着想を得て、MCP サーバーをより簡単に作成できるようにしています。

FastMCP を使用して MCP サーバーを作成しましょう。始める前に、MCP サーバーの機能を考えてみましょう。現在の Novita MCP サーバーは、GPU 管理を処理するツールのみを実装しています。GPU 管理を超えた Novita API を中心としたサーバーを構築してみましょう。

代わりに、Novita プラットフォーム上のモデルへのアクセスを提供する MCP サーバーを構築しましょう。MCP サーバーにはツールのみがあり、リソースやプロンプトはありません。サーバーが持つツールのリストは次のとおりです。

  • list_models: このツールは、Novita プラットフォーム上のすべての大規模言語モデルを一覧表示します。
  • get_model: このツールは、特定の大規模言語モデルを取得して使用します。
  • text2image: このツールは、指定されたプロンプトから画像を生成します。
  • task_result: このツールは、その ID を介して実行中のタスクのステータスを取得するために使用されます。
  • text_to_speech: このツールは、指定されたテキストを音声に変換します。
  • generate_video: このツールは、指定されたプロンプトから動画を生成します。

構築するツールがわかったので、サーバーの作成を開始しましょう。まず、server.py という名前のファイルを作成し、次のコードを追加します。

import os
import sys
from mcp.server.fastmcp import FastMCP
import requests
import uvicorn
from starlette.applications import Starlette
from starlette.routing import Mount

base_url = "https://api.novita.ai/v3"

headers = {
   "Content-Type": "application/json",
   "Authorization": f"Bearer {os.environ['NOVITA_API_KEY']}"
}

mcp = FastMCP("Novita_API")

これで、必要なモジュールをインポートし、API のベース URL とヘッダーを定義し、FastMCP クラスのインスタンスを作成しました。ツールの作成に進みましょう。

モデルの一覧表示

FastMCP でツールを作成するには、FastMCP インスタンスの tool メソッドで関数をデコレートする必要があります。list_models 関数は、モデル一覧エンドポイント を呼び出してモデルのリストを取得します。応答は適切にフォーマットされ、呼び出した LLM に渡すことができます。

@mcp.tool()
def list_models() -> str:
   """
   Novita API から利用可能なすべてのモデルを一覧表示します。
   """

   url = base_url + "/openai/models"

   response = requests.request("GET", url, headers=headers)
   data = response.json()["data"]
  
   text = ""
   for i, model in enumerate(data, start=1):
       text += f"モデル ID: {model['id']}\
"
       text += f"モデルの説明: {model['description']}\
"
       text += f"モデルタイプ: {model['model_type']}\
\
"
  
   return text

ツールの docstring は、ツールの機能を説明する方法として機能し、LLM がツールの用途を理解できるようにします。

モデルの取得

このツールは、Novita 上のデプロイ済み LLM にアクセスするために使用されます。モデル ID とモデルへのプロンプトを受け取ります。Novita チャット完了 API エンドポイント を使用します。

@mcp.tool()
def get_model(model_id: str, message):
   """
   モデル ID とメッセージを指定して、Novita API から応答を取得します。
   """

   url = base_url + "/openai/chat/completions"

   payload = {
       "model": model_id,
       "messages": [
           {
               "content": message,
               "role": "user",
           }
       ],
       "max_tokens": 200,
       "response_format": {
           "type": "text",
       },
   }

   response = requests.request("POST", url, json=payload, headers=headers)
  
   content = response.json()["choices"][0]["message"]["content"]

   return content

Text2Image

このツールは、プロンプトから画像を生成します。内部では Novita の テキストから画像へのエンドポイント を使用します。このエンドポイントは非同期であるため、画像をすぐに返すのではなく、タスク ID を返します。

@mcp.tool()
def text2Image(prompt):
   """
   Novita API を使用してテキストプロンプトから画像を生成します。
   """

   url = base_url + "/async/txt2img"

   payload = {
       "request": {
           "model_name": "sd_xl_base_1.0.safetensors",
           "prompt": prompt,
           "width": 1024,
           "height": 1024,
           "image_num": 1,
           "steps": 20,
           "clip_skip": 1,
           "sampler_name": "Euler a",
           "guidance_scale": 7.5,
       },
       "extra": {
           "response_image_type": "jpeg"
       }
   }

   response = requests.request("POST", url, json=payload, headers=headers)

   return response.json()["task_id"]

タスク結果

このツールは、Novita API で進行中のタスクのステータスを取得するために使用されます。タスク ID のみを受け取ります。たとえば、画像ツールは非同期で画像を生成し、タスク ID をホストに返します。ユーザーはホストに、タスク結果ツールを使用してそのタスクの結果を取得するように依頼できます。

@mcp.tool()
def task_result(task_id: str):
   """
   タスク ID を使用して実行中のタスクの現在のステータスを取得します。
   """

   url = base_url + f'/async/task-result?task_id={task_id}'

   response = requests.request("GET", url, headers=headers)
   return response.json()

動画の生成

このツールは、Novita API の Kling AI V1.6 Text-to-Video エンドポイント を使用して動画を生成します。画像ツールと同様に、非同期で動画を生成し、タスク ID を返します。

@mcp.tool()
def generateVideo(prompt: str):
   """
   プロンプトを使用して画像を生成します
   """

   url = base_url + "/async/kling-v1.6-t2v"

   payload = {
       "mode": "Standard",
       "prompt": prompt,
       "negative_prompt": "low quality",
       "guidance_scale": 0.6
   }

   response = requests.post(url, json=payload, headers=headers)
  
   return response.json()

テキスト読み上げ

このツールは、Novita API の Text-to-Speech エンドポイント を使用して音声を生成します。これも非同期エンドポイントであるため、タスク ID を返します。

@mcp.tool()
def textToSpeech(text, voice_id) -> str:
   """
   テキストと音声 ID を使用して音声を生成します。
   生成された音声のタスク ID を返します。
  
   利用可能な音声 ID は次のとおりです。
   - Emily
   - James
   - Olivia
   - Michael
   - Sarah
   - John
   """

   url = base_url + "/async/txt2speech"

   payload = {
       "request": {
           "voice_id": voice_id,
           "language": "en-US",
           "texts": [text]
       }
   }

   response = requests.post(url, json=payload, headers=headers)
  
   return response.json()["task_id"]

すべてのツールを定義したら、トランスポートメカニズムを設定します。stdio を使用します。

if __name__ == "__main__":
   # stdio トランスポートを使用して実行
   mcp.run(transport="stdio")

これで、すべてのコードをまとめることができます。

import os
import sys

from mcp.server.fastmcp import FastMCP

import requests

import uvicorn

from starlette.applications import Starlette
from starlette.routing import Mount

base_url = "https://api.novita.ai/v3"

headers = {
   "Content-Type": "application/json",
   "Authorization": f"Bearer {os.environ['NOVITA_API_KEY']}"
}

mcp = FastMCP("Novita_API")

@mcp.tool()
def list_models() -> str:
   """
   Novita API から利用可能なすべてのモデルを一覧表示します。
   """

   url = base_url + "/openai/models"

   response = requests.request("GET", url, headers=headers)
   data = response.json()["data"]
  
   text = ""
   for i, model in enumerate(data, start=1):
       text += f"モデル ID: {model['id']}\
"
       text += f"モデルの説明: {model['description']}\
"
       text += f"モデルタイプ: {model['model_type']}\
\
"
  
   return text

@mcp.tool()
def get_model(model_id: str, message) -> str:
   """
   モデル ID とメッセージを指定して、Novita API から応答を取得します。
   """

   url = base_url + "/openai/chat/completions"

   payload = {
       "model": model_id,
       "messages": [
           {
               "content": message,
               "role": "user",
           }
       ],
       "max_tokens": 200,
       "response_format": {
           "type": "text",
       },
   }

   response = requests.request("POST", url, json=payload, headers=headers)
  
   content = response.json()["choices"][0]["message"]["content"]

   return content

@mcp.tool()
def text2Image(prompt: str) -> str:
   """
   Novita API を使用してテキストプロンプトから画像を生成します。
   """

   url = base_url + "/async/txt2img"

   payload = {
       "request": {
           "model_name": "sd_xl_base_1.0.safetensors",
           "prompt": prompt,
           "width": 1024,
           "height": 1024,
           "image_num": 1,
           "steps": 20,
           "clip_skip": 1,
           "sampler_name": "Euler a",
           "guidance_scale": 7.5,
       },
       "extra": {
           "response_image_type": "jpeg"
       }
   }

   response = requests.request("POST", url, json=payload, headers=headers)

   return response.json()["task_id"]

@mcp.tool()
def task_result(task_id: str) -> str:
   """
   タスク ID を使用して実行中のタスクの現在のステータスを取得します。
   """

   url = base_url + f'/async/task-result?task_id={task_id}'

   response = requests.request("GET", url, headers=headers)
   return response.json()

@mcp.tool()
def generateVideo(prompt: str) -> str:
   """
   プロンプトを使用して画像を生成します
   """

   url = base_url + "/async/kling-v1.6-t2v"

   payload = {
       "mode": "Standard",
       "prompt": prompt,
       "negative_prompt": "low quality",
       "guidance_scale": 0.6
   }

   response = requests.post(url, json=payload, headers=headers)
  
   return response.json()["task_id"]

@mcp.tool()
def textToSpeech(text, voice_id) -> str:
   """
   テキストと音声 ID を使用して音声を生成します。
   生成された音声のタスク ID を返します。
  
   利用可能な音声 ID は次のとおりです。
   - Emily
   - James
   - Olivia
   - Michael
   - Sarah
   - John
   """

   url = base_url + "/async/txt2speech"

   payload = {
       "request": {
           "voice_id": voice_id,
           "language": "en-US",
           "texts": [text]
       }
   }

   response = requests.post(url, json=payload, headers=headers)
  
   return response.json()["task_id"]

if __name__ == "__main__":
   # stdio トランスポートを使用して実行
   mcp.run(transport="stdio")

次の設定を使用して、Claude Desktop、Cursor、VS Code などの MCP ホストで MCP サーバーをテストできます。

{
     "command": "python",
     "args": [
       "path/to/server.py" 
     ],
     "env": {
       "NOVITA_API_KEY": "sk_...."
     }
   }

以前に開発したクライアントスクリプトを使用してサーバーをテストすることもできます。

MCP 低レベルサーバーの使用

前のセクションで構築したサーバーは、MCP サーバーを構築するための高レベルインターフェースを提供する FastMCP クラスを利用しています。低レベルサーバーを使用して MCP サーバーを構築することもでき、MCP プロトコルを細かく制御できます。前のセクションのサーバーを低レベルサーバーを使用するように変更する方法を見てみましょう。

ツール管理

FastMCP が行うことの 1 つは、定義したツールを管理することです。FastMCP クラスの tool デコレータで関数をデコレートすると、FastMCP はそのツールをリストに追加します。エージェントがそのツールを要求すると、FastMCP はそれをフェッチし、呼び出し、結果をエージェントに送り返します。

低レベルサーバーを使用すると、call_tool デコレータを使用してこのプロセスを自分で管理できます。

@app.call_tool()
async def manage_tool(name: str, arguments: dict ) -> list[types.TextContent]:
   if name == "list_models":
       return await list_models_tool()
  
   if name == "get_model":
       return await get_model_tool(arguments)
  
   else:
       raise ValueError(f"不明なツール: {name}")

上記のコードは、call_tool メソッドでデコレートされた関数を示しています。エージェントがツールを呼び出すと、ツールの名前とツールが期待する引数が渡されます。関数の名前を使用して、エージェントが呼び出したいツールを判別し、実行できます。

また、FastMCP では tool メソッドで関数がデコレートされると自動的にこれが行われるのとは異なり、低レベルサーバーを使用してツールの一覧表示を管理することもできます。

@app.list_tools()
async def list_tools() -> list[types.Tool]:
   return [
       types.Tool(
           name="list_models",
           description="Novita API から利用可能なすべてのモデルを一覧表示します。",
           inputSchema={"type": "object", "properties": {}},
       ),
       types.Tool(
           name="get_model",
           description="モデル ID とメッセージを指定して、Novita API から応答を取得します。",
           inputSchema={
               "type": "object",
               "required": ["model_id", "message"],
               "properties": {
                   "model_id": {
                       "type": "string",
                       "description": "使用するモデルの ID。",
                   },
                   "message": {
                       "type": "string",
                       "description": "送信する入力メッセージ。",
                   },
               },
           },
       ),
   ]

以下が完全な低レベルサーバーコードです。2 つのツールが含まれており、標準入出力を介してクライアントと通信できます。

import os
import asyncio
import requests
from mcp.server.lowlevel import Server
from mcp.server.stdio import stdio_server
import mcp.types as types

base_url = "https://api.novita.ai/v3"

headers = {
   "Content-Type": "application/json",
   "Authorization": f"Bearer {os.environ['NOVITA_API_KEY']}"
}

app = Server("Novita_API")

async def list_models_tool():
   """
   Novita API から利用可能なすべてのモデルを一覧表示します。
   """
   url = base_url + "/openai/models"
   response = requests.get(url, headers=headers)
   data = response.json()["data"]

   text = ""
   for i, model in enumerate(data, start=1):
       text += f"モデル ID: {model['id']}\
"
       text += f"モデルの説明: {model['description']}\
"
       text += f"モデルタイプ: {model['model_type']}\
\
"

   return [types.TextContent(type="text", text=text)]

async def get_model_tool(arguments: dict):
   """
   モデル ID とユーザーメッセージを指定して、Novita API から応答を取得します。
   """
   model_id = arguments.get("model_id")
   message = arguments.get("message")

   if not model_id or not message:
       raise ValueError("「model_id」と「message」の両方が必要です。")

   url = base_url + "/openai/chat/completions"

   payload = {
       "model": model_id,
       "messages": [
           {
               "content": message,
               "role": "user",
           }
       ],
       "max_tokens": 200,
       "response_format": {
           "type": "text",
       },
   }

   response = requests.post(url, json=payload, headers=headers)
   content = response.json()["choices"][0]["message"]["content"]
   return [types.TextContent(type="text", text=content)]

@app.call_tool()
async def manage_tool(name: str, arguments: dict ) -> list[types.TextContent]:
   if name == "list_models":
       return await list_models_tool()
  
   if name == "get_model":
       return await get_model_tool(arguments)
  
   else:
       raise ValueError(f"不明なツール: {name}")

@app.list_tools()
async def list_tools() -> list[types.Tool]:
   return [
       types.Tool(
           name="list_models",
           description="Novita API から利用可能なすべてのモデルを一覧表示します。",
           inputSchema={"type": "object", "properties": {}},
       ),
       types.Tool(
           name="get_model",
           description="モデル ID とメッセージを指定して、Novita API から応答を取得します。",
           inputSchema={
               "type": "object",
               "required": ["model_id", "message"],
               "properties": {
                   "model_id": {
                       "type": "string",
                       "description": "使用するモデルの ID。",
                   },
                   "message": {
                       "type": "string",
                       "description": "送信する入力メッセージ。",
                   },
               },
           },
       ),
   ]

async def main():
   async with stdio_server() as streams:
       await app.run(streams[0], streams[1], app.create_initialization_options())

if __name__ == "__main__":
   asyncio.run(main())

低レベルサーバーは、ツール管理をきめ細かく制御できるだけでなく、リソース、プロンプト、およびライフサイクル管理などの MCP プロトコルの他の部分も低レベルで制御できます。

結論

このチュートリアルでは、Novita API を使用して MCP ホストの機能を強化する MCP サーバーを構築しました。ツールの定義と公開方法を含む、MCP サーバーの作成に必要な基本を学びました。

この基礎を基に、認証、リモート MCP サーバーのデプロイ、低レベル Python 実装の直接操作など、より高度なトピックを探求し始めることができます。

また、Novita API 自体を調査し、多様な言語モデルセットから動画、音声、画像の生成ツールに至るまで、その機能を確認しました。Novita LLM プレイグラウンド にアクセスして、画像エディターや顔エディターのエンドポイントなど、カバーできなかった他の API も試してみてください。

Novita AI は、開発者がシンプルな API を使用して AI モデルを簡単にデプロイできると同時に、構築とスケーリングのための手頃で信頼性の高い GPU クラウドを提供する AI クラウドプラットフォームです。