Cursorで自作MCPサーバー(tool)を使ってみた!【Python】

※ 当サイトではアフィリエイト広告を利用しています。リンクは広告リンクも含みます。

この記事は約11分で読めます。

とりあえず、ここのQuickStartをやってみました。
QuickStartの内容にそってClaude DesktopではなくCursorを使います。
その後、簡単な文字列をreturnするだけのMCPサーバー(tool)を作ってCursorで動かしました。
Windows11でやってます。
こちら↓の続きになります

本文ではMCPサーバーと表記していますがMCP toolと言ったほうがいいのかもしれません。
自己責任で実行してください。

広告

Set up your environment

Claude for Desktopが前提の説明なっているがCursorもほぼ同じです。
まずはuvのインストール
uvは、高速なパッケージ管理と仮想環境の管理を目的としたツールで、pipvenvの代替として利用できるらしい。初めて使います。
AnacondaPowerShellPrompt(私の場合AnacondaをインストールしてPython環境を構築したので、Anacondaじゃない場合、多分WindowsPowerShell)を立ち上げ
重要:どこにインストールしたか記録しておく。uv.exeのパスが大事。赤字の部分
青字は実際に入力したコマンド

(base) PS C:\Users\user> powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Downloading uv 0.6.14 (x86_64-pc-windows-msvc)
Installing to C:\Users\user\.local\bin
  uv.exe
  uvx.exe
everything's installed!

To add C:\Users\user\.local\bin to your PATH, either restart your shell or run:

    set Path=C:\Users\user\.local\bin;%Path%   (cmd)
    $env:Path = "C:\Users\user\.local\bin;$env:Path"   (powershell)
(base) PS C:\Users\user>

AnacondaPowerShellPromptを閉じて、また立ち上げ
新しくMCPサーバー作るときは、ここからやると思います。weatherは変える。

# Create a new directory for our project
uv init weather
cd weather

# Create virtual environment and activate it
uv venv
.venv\Scripts\activate

# Install dependencies
uv add mcp[cli] httpx

# Create our server file
new-item weather.py

Cursorを立ち上げ、上で作られたweatherフォルダを開く

weather.pyにQuickStartに書いてあるコード4個(Importing packages and setting up the instance、Helper functions、
Implementing tool execution、Running the server)をコピペして保存。

Cursorの⚙(歯車設定)のMCP→+Add new global mcp serverで以下の赤字部分入力。青字は別のMCPサーバー設定です。詳細はhttps://kikuichige.com/29797/

{
  "mcpServers": {    
    "puppeteer": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-puppeteer"]
    },
    "my-filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "C:\\Users\\user\\mcp\\MCP_data"
      ]
    },
    "weather": {
      "command": "C:\\Users\\user\\.local\\bin\\uv.exe",
      "args": [
          "--directory",
          "C:\\Users\\user\\weather",
          "run",
          "weather.py"
      ]
  }
  }
}

動作確認CursorのChatで「ニューヨークの今の天気は」と聞いてみると答えた。
実際の画面は下にあります。
weatherディレクトリのサイズは24Mで、大きくないので毎回、ディレクトリを作っても大丈夫そうです。

weather.pyの解説

実行した結果と合わせてコードを読み取って解説してみました。間違ってるかもしれません。
weather固有の処理がややこしいので複雑に見えますが、取り去ると簡単な構造です。

Importing packages and setting up the instance

from mcp.server.fastmcp import FastMCP ← MCPサーバーのライブラリ

# Initialize FastMCP server
mcp = FastMCP("weather") ← MCPサーバーの名前、多分、MCPサーバーを追加する設定jsonファイルには、この名前を書かないとだめだと思います。

Helper functionsは、weatherで使う関数を定義しているだけなのでとばします。

Implementing tool execution

ここがMCPサーバーの中身を定義している本体。実行画面を見ると、ここの関数が呼び出されている。

@mcp.tool() ← AIから呼び出される関数の定義するために必要なもの(デコレーター)
async def get_alerts(state: str) -> str: ← AIから呼び出される関数
    """Get weather alerts for a US state. ← ここでAIにこの関数は何なのか説明してる

    Args:
        state: Two-letter US state code (e.g. CA, NY) ← 入力変数のAIに対しての説明
    """
略
    return "\n---\n".join(alerts) ← AIに出力される結果

@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
    """Get weather forecast for a location.

    Args:
        latitude: Latitude of the location
        longitude: Longitude of the location
    """
略

    return "\n---\n".join(forecasts)


実際の実行画面

Called MCP toolでget_forcast関数やget_aleart関数を使っていいか一旦停止して聞いてくる。

エラーログ

エラーログの確認https://kikuichige.com/29797/#toc19

最初QuickStartに書いてある通り"command": "uv",でやったらエラーになったのでログを見たら
2025-04-16 15:23:38.973 [error] ther: Client error for command spawn uv ENOENT
2025-04-16 15:23:38.973 [error] ther: Error in MCP: spawn uv ENOENT

このエラーは、uv コマンドが見つからないために発生している可能性が高いです。ENOENT は「ファイルやコマンドが存在しない」という意味。なので絶対パスで指定した。

    "weather": {
      "command": "C:\\Users\\user\\.local\\bin\\uv.exe",
      "args": [
          "--directory",
          "C:\\Users\\user\\weather",
          "run",
          "weather.py"
      ]
  }

シンプルな自作MCPサーバーを作ってCursorに設定してみた

イチゲ大明神という関数をMCPサーバーにしてみます。
ただ「前の人と同じ意見です」とreturnする関数です。
もうちょっとプラスして日本時間を受け取ることにして、合わせてreturnすることにしました。

Cursorを立ち上げ表示→ターミナル

# Create a new directory for our project
uv init ichigedaimyoujin
cd ichigedaimyoujin

# Create virtual environment and activate it
uv venv
.venv\Scripts\activate

# Install dependencies
uv add mcp[cli] httpx

# Create our server file
new-item ichigedaimyoujin.py

Cursorでichigedaimyoujinのフォルダを開いてichigedaimyoujin.pyの中身を以下
関数の説明は英語でIchigedaimyoujin is a prophet.(イチゲ大明神は預言者です)
変数の説明はJapan Standard Time(日本時間)としました。日本語でもいけそうな気はします。今回は英語で。

from mcp.server.fastmcp import FastMCP

# Initialize FastMCP server
mcp = FastMCP("ichigedaimyoujin")

@mcp.tool()
async def get_otuge(state: str) -> str:
    """Ichigedaimyoujin is a prophet.

    Args:
        state: Japan Standard Time
    """
    otuge=f"前の人と同じ意見です!({state})"
    return otuge

if __name__ == "__main__":
    # Initialize and run the server
    mcp.run(transport='stdio')

Cursorの⚙(歯車設定)のMCP→+Add new global mcp serverで以下追加。
追加した設定の前には,(カンマ)をつけないとエラーになります。

"ichigedaimyoujin": {
      "command": "C:\\Users\\user\\.local\\bin\\uv.exe",
      "args": [
          "--directory",
          "C:\\Users\\user\\mcp_kojin\\ichigedaimyoujin",
          "run",
          "ichigedaimyoujin.py"
      ]
    }

実験:
Chatで「イチゲ大明神に日本の未来について聞いてください」
予想した結果「前の人と同じ意見です」(10:55)とかだと思ったら
真面目に答えてきて、笑った。

設定成功の様子

実際のChat画面

Called MCP tool get_otsugeと表示されてget_otsuge関数を実行していいか聞いてくる。
クリックすると先に進む。
拒否するとRejected MCP toolとなるが会話は進む。

Called MCP tool get_otsugeをもう1回クリックすると入力パラメータとreturnされたものが見れた。

追加でChatをつづけた。

私:イチゲ大明神の言ったことをそのまま書いて
AI:イチゲ大明神様の神託を、そのまま記載させていただきます:「前の人と同じ意見です!(2024-03-27 21:00:00)」これが、イチゲ大明神様から直接いただいた神託のメッセージでございます。

日付が適当過ぎる。
時間のことはstate: Japan Standard Timeとしただけだが、
プログラムで時間を取得するコードを書いて、やり取りしないとだめなのか
こういった点からもAIをコントロールするのは難しいと感じた。
Claude for Desktopでも試したら、こちらは余計なこと言ってこなかったし時間もあってる。
まあ、LLMによっていろいろだな。

所感

スムーズにできたが、使いどころがあるかな?AIに意図を指示するのが難しい。
プログラムでしっかり作りこんでいかないと何をしでかすかわからん。
ちなみに前回、PuppeteerとFilesystemでスクショを保存しようとしてできなかったが、
上の関数にSeleniumでスクショを撮る処理を入れたら普通にできた。
もちろん、関数が実行されるだけなので、その部分はLLMを介させず実行してる。
なので「スクショを撮って」という指示ではなく「イチゲ大明神のお告げを聞いて」でget_otsge関数が実行されるタイミングでスクショを撮る処理が動く。
また今回uvという存在を初めて知ったが、
seleniumのライブラリはuvで仮想環境に入れる必要があった点は注意しておこうと思う。

イチゲをOFUSEで応援する(御質問でもOKです)Vプリカでのお支払いがおすすめです。
Vプリカでのお支払いがおすすめです。

MENTAやってます(ichige)

タイトルとURLをコピーしました