シンプルな自作MCPサーバーを VS Code に設定して GitHub Copilot の Agent mode で利用（Node.js で TypeScript を直接扱う）

## はじめに

過去に書いた記事で、「VS Code や　Claude for Desktop で MCPサーバーを軽く試してみる」ということをやってみていました。

●VS Code の設定から MCPサーバーを追加して GitHub Copilot agent mode で利用してみる（安定版でも利用可能に） - Qiita
　https://qiita.com/youtoy/items/adfeedeedf1309f194ce
●今になって Claude for Desktop で MCP に入門してみた（Claude は Free plan） - Qiita
　https://qiita.com/youtoy/items/3ef0af28b530f5c5709c

この時は、[Filesystem MCP Server](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem) を使っていたのですが、今回はすごく簡易な自作MCPサーバーを作ってみて、それを VS Code から使ってみます。

### 補足

#### 構成などの補足

構成については、VS Code の標準機能で 自作MCPサーバーを設定して、それを GitHub Copilot の Agent mode で利用する形とします。

また自作MCPサーバーは、[公式の TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) を使って「ツール」を実装します。その TypeScript のファイルは、nodeコマンドで直接処理する形にします（※ Node v23.6.0 以降の機能を利用）。

実装・手順は、MCPサーバーを使った処理が最低限動くのを確認できるくらいのものにします。


#### 動作している様子

それと、まずは今回の内容を動作させた時の様子を、以下に動画で示します。
テスト用に実装した内容は、「2つの数字を加算した値に、さらに 10を加算する」というものです。

<iframe width="560" height="315" src="https://www.youtube.com/embed/x9rGYXIJhkg?si=s4tWKpHud0bVsxYo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

上記の動画で 3回のやりとりをしていますが、2回目で、以下の「このセッションで許可する」を選択しています。

![2025-04-06_13-20-35.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/211174fb-409c-4917-b83d-d9f48c3c0e07.jpeg)

そのため、3回目の処理を実行した際は、処理を続行するかどうかのユーザーへの確認なしで、エージェントが処理を実行しています。


## 今回の内容を試そうと思ったきっかけ

今回の内容を試そうと思ったきかっけを書いてみます。

MCP・MCPサーバー関連の技術情報を追っている中で、MCPサーバーを自作するという話題をいくつも見かけます。
その中で、シンプルな MCPサーバーを実装して動かすという話も見かけていて、自分もそういう方向のものをやってみたくなりました。

- [なぜ MCP なのか](https://voluntas.ghost.io/why-mcp/)
- [30分で作ってみる自作MCPサーバー - KITUNE IS GOOD](https://sori883.dev/posts/claude_self_made_mcp_server/)
- [簡易な自作MCPサーバーをお試しで実装する方法](https://zenn.dev/smartround_dev/articles/02af1058e9f80f)
- [Azure FunctionsでMCPサーバーを作る！](https://zenn.dev/microsoft/articles/azure-function-mcp)
- [MCPに入門する/ Introduction to MCP - Speaker Deck](https://speakerdeck.com/shuntaka/introduction-to-mcp)

## 実際に試してみる

実際に試していきます。

実装には「[公式のページ（modelcontextprotocol/servers: Model Context Protocol Servers のページ）]()」に書かれている、「[公式の Typescript SDK](https://github.com/modelcontextprotocol/typescript-sdk)」を使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/6fcae92d-684a-4422-b50c-f14ce55f4af5.png)

SDK のページの「[Installation](https://github.com/modelcontextprotocol/typescript-sdk?tab=readme-ov-file#installation)」「[Quickstart](https://github.com/modelcontextprotocol/typescript-sdk?tab=readme-ov-file#quickstart)」の内容を見つつ、準備・実装を進めていきます。

この内容の一部を削ったものを使うような形になります。


### パッケージのインストール

まずは、[パッケージ（@modelcontextprotocol/sdk）](https://www.npmjs.com/package/@modelcontextprotocol/sdk)のインストールです。

```zsh
npm install @modelcontextprotocol/sdk
```

### コード

次に、TypeScript で実装するコードの話です。


#### サンプルコード

[公式の Quickstart](https://github.com/modelcontextprotocol/typescript-sdk?tab=readme-ov-file#quickstart) で示されているサンプルコードは、以下のとおりです。

```typescript
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// Create an MCP server
const server = new McpServer({
  name: "Demo",
  version: "1.0.0"
});

// Add an addition tool
server.tool("add",
  { a: z.number(), b: z.number() },
  async ({ a, b }) => ({
    content: [{ type: "text", text: String(a + b) }]
  })
);

// Add a dynamic greeting resource
server.resource(
  "greeting",
  new ResourceTemplate("greeting://{name}", { list: undefined }),
  async (uri, { name }) => ({
    contents: [{
      uri: uri.href,
      text: `Hello, ${name}!`
    }]
  })
);

// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport();
await server.connect(transport);
```

いろいろ試してみたところ、上記のコード内の処理をけっこう削ったものでも、「ツールを使って返答を返す」という最低限の動作をさせられそうでした。


#### 変更したコード

上記のサンプルの内容を削って、以下のシンプルな内容にしたものを使いました。


```typescript:app.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "Demo",
  version: "1.0.0",
});

server.tool(
  "add_test",
  "与えられた数値の足し算をする（さらに10を足す）",
  { a: z.number(), b: z.number() },
  async ({ a, b }) => ({
    content: [{ type: "text", text: String(a + b + 10) }],
  })
);

const transport = new StdioServerTransport();
await server.connect(transport);
```

とりあえず動かすだけなら、これだけの内容でも大丈夫でした。

計算をする処理の部分について、上記の MCPサーバーでの処理を使った出力が得られているかどうかを回答から判別しやすくするため、入力された値にさらに 10 を加算した結果を返すようにしてみました。

それと、MCPサーバーの説明の文章を「server.tool()」の「"add_test"」の後に加えてみています。


### VS Code での設定

VS Code で MCPサーバー関連の設定を進めていきます。

[冒頭で掲載していた過去の記事と同じ手順で、MCPサーバーの設定を行い](https://qiita.com/youtoy/items/adfeedeedf1309f194ce#mcp%E9%96%A2%E9%80%A3%E3%81%AE%E8%A8%AD%E5%AE%9A)、その設定の画面内で[サーバーを起動します](https://qiita.com/youtoy/items/adfeedeedf1309f194ce#mcp%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E8%B5%B7%E5%8B%95)。
（※ サーバーの起動について、他にコマンドパレットから行うこと方法もあります）


#### 設定内容

今回設定した内容は、以下のとおりです。

```json
{
  "mcp": {
    "servers": {
      "my-mcp-server": {
        "command": "node",
        "args": ["/【ファイルを置いたフォルダの絶対パス】/app.ts"]
      }
    }
  }
}
```

この設定では、nodeコマンドで TypeScript のファイルを直接実装する構成にしています。

以下の記事にも書いた、Node.js での TypeScript の直接実行ができるかもしれないと思い、上記のように「`"command": "node"`」の引数に「`app.ts`」を直接設定する形を試しました。

●Node v23.6.0 で TypeScript を直接実行（フラグなしのデフォルトでの処理） - Qiita
　https://qiita.com/youtoy/items/e7a1aeaea5918c48999b
 

なお今回、自分が利用した Node.js のバージョンは「v23.11.0」で、TypeScript の直接実行に対応したバージョンを使っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/1c3d5d78-2394-4675-a392-bbefdaee51a5.png)



### 実行結果

GitHub Copilot の Agent mode で、上記で実装したツールを使ってみます。VS Code の安定版の最新版で Agent mode が選択できない場合は、設定から Agent mode の機能を有効化してください。

今回の内容を実行した結果は以下のとおりです。
ツールの実行時にはデフォルトだと確認を求められて、それを許可すると処理が実行されました。

![2025-04-06_03-13-43.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/9478eed1-99df-4df8-b547-24b63ff8a8f8.jpeg)

以下は、数字の部分を変えたプロンプトで、処理を実行した結果です。

![2025-04-06_03-11-07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/6daa3712-8b8e-45d9-8a2f-035f39fd9510.jpeg)

その他、試した内容は冒頭に掲載した動画の内容の通りです。


#### ツール実行の確認を省略する

あと、冒頭の動画掲載部分に書いていた内容ですが、都度ツール実行の確認を求めないようにする設定を以下から選択できます。

![2025-04-06_13-20-35.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/211174fb-409c-4917-b83d-d9f48c3c0e07.jpeg)


## おわりに

今回、シンプルな自作MCPサーバーを公式の TypeScript SDK を使って実装しました。また、それを VS Code の標準機能で設定して、VS Code の GitHub Copilot agent mode で使ってみました。

ツールを使うだけのシンプルな内容にしてみたので、コードや設定・手順などがかなり少なくてすんだかと思います。

今回の内容は問題なく進められたので、さらに MCPサーバーで実装する処理を変えたものも試したり、より複雑な内容のものをやっていければと思います。


### 【追記】 Claude for Desktop で使ってみる

その後、自作MCPサーバーを Claude for Desktop でも使ってみて、設定した内容などを記事にしました！

#### 記事

●VS Code で使っていたシンプルな自作MCPサーバーを Claude for Desktop で使う（Node.js ＋ TypeScript SDK） - Qiita
 https://qiita.com/youtoy/items/01f8918b378c51989173

#### 試した時の様子

https://x.com/youtoy/status/1909271575133855770


### その他

今回のお試しをしている中で、VS Code の公式ページに MCPサーバーの話が書かれたページがあるのを見かけたので、メモの意味も兼ねて掲載してみます。

●Use MCP servers in VS Code (Preview)
　https://code.visualstudio.com/docs/copilot/chat/mcp-servers

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/95494970-f5c4-4df2-a249-0b0b7a6ff02a.png)