Skip to main content
Glama
kaz29
by kaz29

NestJS MCP Server

NestJSを使用したModel Context Protocol (MCP)サーバーの実装サンプルです。 DDD/クリーンアーキテクチャを適用しやすい構造で、今後のMCP開発のベースとして利用できます。

🎯 特徴

  • NestJS: エンタープライズグレードのフレームワーク

  • デコレーターベース: @Toolデコレーターで簡潔にツールを定義

  • レイヤー分離: サービス層とツール層を分離(DDD適用可能)

  • 依存性注入: テスタブルで保守性の高い設計

  • Streamable HTTP: 最新のMCP仕様に対応

  • Zod: 型安全なパラメータバリデーション

🌿 ブランチ構成

このリポジトリは、学習段階に応じて2つのブランチを提供しています:

basic-example ブランチ(初心者向け)

基本的なMCP実装のサンプルです。以下のシンプルな機能を提供します:

  • get_current_time - 現在の日時を取得

  • calculate - 四則演算(加算、減算、乗算、除算)

  • save_note / get_note / list_notes - メモの保存・取得・一覧表示

推奨する利用シーン:

  • MCPの基本的な仕組みを学びたい

  • NestJSとMCPの連携方法を理解したい

  • シンプルな実装例から始めたい

git checkout basic-example

main ブランチ(実践向け)

実用的なFour Keys (DORA Metrics) 実装を含む、より本格的なサンプルです。

追加機能:

  • GitHub APIを使用したデプロイメント分析

  • Four Keys メトリクス計算(デプロイ頻度、リードタイム、変更失敗率、MTTR)

  • 包括的なテストカバレッジ(95%以上)

  • モック戦略を含むテスト実装例

推奨する利用シーン:

  • 実際のプロダクション環境での使用を検討している

  • GitHub統合などの外部API連携方法を学びたい

  • テスト戦略やカバレッジ改善の参考にしたい

📦 提供する機能

basic-exampleブランチ

  1. get_current_time - 現在の日時を取得

  2. calculate - 四則演算(加算、減算、乗算、除算)

  3. save_note - メモの保存

  4. get_note - メモの取得

  5. list_notes - 保存されたメモの一覧表示

mainブランチ(basic-exampleの機能 + 以下)

Four Keys (DORA Metrics) ツール

  1. get_deployment_frequency - デプロイ頻度の計算

    • GitHub Releases、Git タグ、GitHub Actions ワークフローから検出

    • DORA パフォーマンスレベル評価(Elite/High/Medium/Low)

  2. get_lead_time - リードタイム(変更のリードタイム)の計算

    • PR作成からマージまでの時間を集計

    • 平均、中央値、95パーセンタイルを算出

  3. get_change_failure_rate - 変更失敗率の計算

    • ホットフィックスPR、インシデントIssue、ワークフロー失敗から検出

    • デプロイ成功率の分析

  4. get_mttr - MTTR(平均復旧時間)の計算

    • インシデントの検出から解決までの時間を集計

    • Issue/PRベースのインシデント追跡

  5. get_four_keys_summary - Four Keys メトリクスの総合サマリー

    • 4つのメトリクスを一度に取得

    • 総合パフォーマンスレベルの評価

🚀 セットアップ

1. 依存関係のインストール

npm install

2. ビルド

npm run build

3. サーバーの起動

npm start

サーバーが起動すると、以下のように表示されます:

🚀 NestJS MCP Server running on http://localhost:3000
📡 MCP Endpoint: http://localhost:3000/mcp

4. テスト実行

node test-client.mjs

5. mainブランチ用の追加セットアップ

Four Keys機能を使用する場合、GitHub App認証の設定が必要です。

📖 詳細な設定手順は GitHub App 設定ガイド を参照してください。

クイックセットアップ

  1. .env.example.envにコピー

  2. GitHub Appを作成(詳細手順

  3. 以下の環境変数を設定:

GITHUB_APP_ID=your_app_id
GITHUB_INSTALLATION_ID=your_installation_id
GITHUB_PRIVATE_KEY_PATH=path/to/private-key.pem
# または
GITHUB_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n..."

必要なGitHub App権限:

  • Repository permissions:

    • Actions: Read

    • Contents: Read

    • Issues: Read

    • Pull requests: Read

    • Metadata: Read

🏗️ プロジェクト構造

basic-exampleブランチ

src/
├── main.ts                          # エントリーポイント
├── app.module.ts                    # ルートモジュール
├── mcp/                             # MCPモジュール
│   ├── mcp.module.ts               # MCP設定・プロバイダー登録
│   ├── tools/                       # ツール層(MCPインターフェース)
│   │   ├── time.tool.ts            # 時刻ツール
│   │   ├── calculator.tool.ts      # 計算ツール
│   │   └── notes.tool.ts           # メモツール
│   └── services/                    # サービス層(ビジネスロジック)
│       ├── time.service.ts
│       ├── calculator.service.ts
│       └── notes.service.ts
└── domain/                          # ドメイン層(将来の拡張用)
    └── notes/
        └── (エンティティ、リポジトリなど)

mainブランチ(追加構造)

src/
└── mcp/
    ├── tools/
    │   └── four-keys/               # Four Keysツール層
    │       ├── deployment-frequency.tool.ts
    │       ├── lead-time.tool.ts
    │       ├── change-failure-rate.tool.ts
    │       ├── mttr.tool.ts
    │       └── summary.tool.ts
    ├── services/
    │   ├── github/                  # GitHub統合サービス
    │   │   ├── github-auth.service.ts    # GitHub App認証
    │   │   └── github-api.service.ts     # GitHub API クライアント
    │   └── four-keys/               # Four Keys計算サービス
    │       ├── deployment-frequency.service.ts
    │       ├── lead-time.service.ts
    │       ├── change-failure-rate.service.ts
    │       └── mttr.service.ts
    └── types/
        ├── github.types.ts          # GitHub API型定義
        └── four-keys.types.ts       # Four Keys型定義

📝 実装例

ツール定義(デコレーターベース)

// src/mcp/tools/time.tool.ts
import { Injectable } from '@nestjs/common';
import { Tool } from '@rekog/mcp-nest';
import { z } from 'zod';
import { TimeService } from '../services/time.service';

@Injectable()
export class TimeTool {
  constructor(private readonly timeService: TimeService) {}

  @Tool({
    name: 'get_current_time',
    description: '現在の日時を取得します',
    parameters: z.object({}),
  })
  async getCurrentTime() {
    const time = this.timeService.getCurrentTime();
    return `現在の日時: ${time}`;
  }
}

サービス層(ビジネスロジック)

// src/mcp/services/time.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class TimeService {
  getCurrentTime(): string {
    const now = new Date();
    return now.toLocaleString('ja-JP', { timeZone: 'Asia/Tokyo' });
  }
}

モジュール設定

// src/mcp/mcp.module.ts
import { Module } from '@nestjs/common';
import { TimeService } from './services/time.service';
import { TimeTool } from './tools/time.tool';

@Module({
  providers: [
    // サービス層
    TimeService,
    // ツール層
    TimeTool,
  ],
})
export class McpToolsModule {}

🔧 開発

開発モード(ホットリロード)

npm run start:dev

ビルドのみ

npm run build

🎓 学習ポイント

basic-exampleブランチ

1. レイヤー分離

  • ツール層: MCPプロトコルとのインターフェース(@Toolデコレーター)

  • サービス層: ビジネスロジック(@Injectable()

  • ドメイン層: エンティティ、リポジトリ(将来の拡張)

2. 依存性注入

constructor(private readonly timeService: TimeService) {}

コンストラクタインジェクションで疎結合を実現し、テストが容易。

3. 型安全なパラメータ

parameters: z.object({
  operation: z.enum(['add', 'subtract', 'multiply', 'divide']),
  a: z.number(),
  b: z.number(),
})

Zodによる実行時バリデーションとTypeScript型推論。

4. MCPモジュール設定

McpModule.forRoot({
  name: 'nestjs-mcp-server',
  version: '1.0.0',
  transport: McpTransportType.STREAMABLE_HTTP,
  mcpEndpoint: '/mcp',
})

mainブランチ(追加の学習ポイント)

5. 外部API統合(GitHub API)

@Injectable()
export class GitHubApiService {
  private octokit: Octokit | null = null;

  constructor(private readonly authService: GitHubAuthService) {}

  async listReleases(owner: string, repo: string) {
    const client = await this.getClient();
    const { data } = await client.rest.repos.listReleases({ owner, repo });
    return data;
  }
}

6. 包括的なテスト戦略(カバレッジ95%以上)

// Vitestを使用したモックベースのテスト
describe('DeploymentFrequencyService', () => {
  let service: DeploymentFrequencyService;
  let mockGitHubApiService: any;

  beforeEach(() => {
    vi.clearAllMocks();
    mockGitHubApiService = {
      listReleases: vi.fn().mockResolvedValue(mockReleases),
    };
    service = new DeploymentFrequencyService(mockGitHubApiService as any);
  });

  it('リリースベースでデプロイを検出できる', async () => {
    const result = await service.calculate('owner', 'repo', 'week', {
      method: 'release',
    });
    expect(result.totalDeployments).toBe(2);
  });
});

7. GitHub App認証

@Injectable()
export class GitHubAuthService {
  async getInstallationToken(): Promise<string> {
    const auth = createAppAuth({
      appId: this.config.appId,
      privateKey: this.config.privateKey,
      installationId: this.config.installationId,
    });

    const { token } = await auth({ type: 'installation' });
    return token;
  }
}

8. CI/CD統合

  • GitHub Actionsでの自動テスト実行

  • カバレッジレポートのPRコメント投稿

  • ビルドとテストの自動化

🌟 今後の拡張例

データベース統合

// TypeORM
@Module({
  imports: [
    TypeOrmModule.forRoot({...}),
    TypeOrmModule.forFeature([Note]),
  ],
})

// Prisma
@Injectable()
export class NotesService {
  constructor(private prisma: PrismaService) {}
}

外部API統合

@Module({
  imports: [HttpModule],
})

@Injectable()
export class ExternalApiService {
  constructor(private http: HttpService) {}
}

認証・認可

@Tool({...})
@UseGuards(AuthGuard)
async protectedTool() {...}

📚 参考リンク

📄 ライセンス

MIT

-
security - not tested
F
license - not found
-
quality - not tested

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kaz29/mcp-server-example'

If you have feedback or need assistance with the MCP directory API, please join our Discord server