はじめに:AIエディタのパラダイムシフトとMCPの本質
こんにちは。開発現場で日夜、開発生産性の最大化に心血を注いでいるテックリードの皆さん。
VS Codeのフォークとして誕生した「Cursor」は、もはや単なる「補完が賢いエディタ」の枠を超えています。コードベース全体をコンテキストとして理解するComposer機能、リアルタイムの差分適用など、私たちのコーディングスタイルは劇的に変化しました。
しかし、実務でAIを活用する中で、こんな壁にぶつかったことはないでしょうか?
- 「社内の独自DBスキーマや、マイクロサービスのAPI仕様が変わるたびに、AIが古い前提でコードを生成してハルシネーションを起こす」
- 「最新の社内ドキュメントやチケット管理システムの情報を、毎回手動でプロンプトにコピペするのが苦痛だ」
この課題を根底から解決するのが、Anthropic社が提唱し、Cursorがいち早くネイティブサポートしたMCP(Model Context Protocol)です。
MCPは、AIモデルと外部データソース(データベース、S3、社内API、Git、GitHub Issuesなど)を安全かつ標準化されたプロトコルで接続するためのオープン規格です。これまではプラグインごとにバラバラだったAIと外部データの連携が、MCPによって「共通の言語」でシームレスに結ばれます。
今回は、このMCPを活用して「自社の独自データソースをCursorのAIに直接参照させ、回答精度を極限まで高めるカスタムMCPサーバーの実装と連携プロセス」を、実務で即座に使える設定ファイルやコードブロックを交えて徹底解説します。
—
1. 現場の生産性を劇的に高めるCursorの隠れたキーボードショートカット
MCPを活用してAIのコンテキストを拡張する前に、まずCursor本体の操縦桿を完全に握り、開発速度を物理的限界まで引き上げるためのショートカットを確認しておきます。これらを無意識レベルで使いこなすことが、AI駆動開発の前提条件です。
究極の高速化を実現するキーストローク
| ショートカット (Mac / Windows) | 役割・機能 | テックリード的解説 |
| :— | :— | :— |
| `Cmd + I` / `Ctrl + I` | インラインAI生成 (Chat/Edit) | コードを選択して即座に修正指示。別ウィンドウを開くコンテキストスイッチを完全に排除。 |
| `Cmd + L` / `Ctrl + L` | チャットパネルの呼び出し / フォーカス | 現在のファイルを自動的にチャットのコンテキストにロード。質問の起点を最速化。 |
| `Cmd + Shift + L` / `Ctrl + Shift + L` | 選択範囲をチャットに追加 | 長大なファイル全体ではなく、数行の重要なロジックだけをピンポイントでAIに渡す。 |
| `Cmd + K` (Composer内) / `Ctrl + K` | 複数ファイルにまたがるコード生成 (Composer) | 単なるファイル編集を超え、依存関係のある複数ファイルを同時に書き換える神機能。 |
| `Option + Enter` / `Alt + Enter` | AI提案の迅速な適用 (Apply) | 生成されたコードをエディタに一瞬でマージ。マウス操作は一切不要。 |
—
2. チーム開発で絶対に共有すべき設定と `.cursorrules` のベストプラクティス
MCPサーバーを導入しても、チームメンバー全員のCursorの設定がバラバラであれば、AIが生成するコードの品質やコーディング規約にブレが生じます。プロジェクトルートに `.cursorrules` を配置し、AIの振る舞いをコードベースレベルで統制します。
実務で効果を発揮する `.cursorrules` 構成例
以下の設定をプロジェクトのルートディレクトリに配置してください。CursorのAIは、コードを生成する際にこのファイルを無条件の「憲法」として解釈します。
.cursorrules – プロジェクト標準AI振る舞い定義書
1. 開発哲学とコード品質
- あなたは世界最高峰のシニアソフトウェアエンジニアです。
- 可読性、保守性、パフォーマンス、そして堅牢なエラーハンドリングを何よりも優先してください。
- マジックナンバーや冗長なコードを排除し、DRY原則を徹底してください。
2. 技術スタックとバージョン制約
- Frontend: Next.js 14 (App Router), TypeScript (Strict mode), Tailwind CSS
- Backend: Node.js (Express), Prisma ORM, PostgreSQL
- 测试: Vitest, Playwright
3. コーディング規約
- すべての公開関数、クラス、コンポーネントにはJSDocまたはTSDocを用いた詳細なドキュメントコメントを記述してください。
- 3項演算子の過度なネストは禁止です。早期リターン(Guard Clauses)を好みます。
- 型定義において `any` の使用は厳禁です。どうしても型が定まらない場合は `unknown` を使用し、型ガードを実装してください。
4. MCP(Model Context Protocol)の活用
- データベーススキーマやAPI仕様についての疑問が生じた場合は、自ら推測せず、接続されたMCPサーバー(`internal-docs-mcp` および `postgres-mcp`)のツールを使用して最新情報を取得してから回答・コード生成を行ってください。
—
3. 独自のデータソースを接続する:カスタムMCPサーバーの実装プロセス
ここからが本題です。今回は、「社内のローカルDB(PostgreSQL)と、最新のAPI仕様書(Markdown群)」をCursorのAIが直接読み込めるようにするカスタムMCPサーバーをTypeScriptで構築します。
MCPサーバーは、stdio(標準入出力)またはSSE(Server-Sent Events)を介してCursorと通信します。今回は開発・運用が最も堅牢なstdioベースのMCPサーバーを作成します。
ステップ 1: MCPサーバープロジェクトの初期化
適当なディレクトリにNode.jsプロジェクトを作成し、公式のMCP SDKをインストールします。
プロジェクトディレクトリの作成と初期化
mkdir cursor-custom-mcp
cd cursor-custom-mcp
npm init -y
依存関係のインストール(MCP SDKおよびPostgreSQLクライアント)
npm install @modelcontextprotocol/sdk pg dotenv
npm install -D typescript @types/node tsx
TypeScript設定ファイルの生成
npx tsc –init
ステップ 2: MCPサーバーの実装コード (`src/index.ts`)
以下のコードは、Cursorからのリクエストを受け取り、「ローカルDBのテーブル定義一覧を返すツール」と「社内ドキュメントを検索するツール」を提供するMCPサーバーの実装です。
import { Server } from “@modelcontextprotocol/sdk/server/index.js”;
import { StdioServerTransport } from “@modelcontextprotocol/sdk/server/stdio.js”;
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from “@modelcontextprotocol/sdk/types.js”;
import pg from “pg”;
import as fs from “fs”;
import as path from “path”;
// 1. PostgreSQL接続プールの設定(環境変数から取得)
const pool = new pg.Pool({
connectionString: process.env.DATABASE_URL || “postgresql://postgres:password@localhost:5432/app_db”,
});
// 2. MCPサーバーインスタンスの初期化
const server = new Server(
{
name: “internal-enterprise-mcp”,
version: “1.0.0”,
},
{
capabilities: {
tools: {}, // このサーバーが「ツール」を提供することを宣言
},
}
);
// 3. 利用可能なツールの定義リストをCursorに返却
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: “get_database_schema”,
description: “PostgreSQLデータベース内の全テーブル名とカラム定義を取得し、AIのスキーマ理解を助けます。”,
inputSchema: {
type: “object”,
properties: {},
required: [],
},
},
{
name: “search_internal_docs”,
description: “プロジェクト内のdocsディレクトリにあるマークダウン仕様書を検索し、設計思想やAPI仕様を取得します。”,
inputSchema: {
type: “object”,
properties: {
keyword: {
type: “string”,
description: “検索キーワード(例: 認証, 決済フロー)”,
},
},
required: [“keyword”],
},
},
],
};
});
// 4. ツールが呼び出されたときの実行ロジック
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
if (name === “get_database_schema”) {
// データベースからテーブル構造を取得するクエリ
const query = `
SELECT
table_name,
column_name,
data_type,
is_nullable
FROM information_schema.columns
WHERE table_schema = ‘public’
ORDER BY table_name, ordinal_position;
`;
const result = await pool.query(query);
return {
content: [
{
type: “text”,
text: JSON.stringify(result.rows, null, 2),
},
],
};
}
if (name === “search_internal_docs”) {
const keyword = (args as { keyword: string }).keyword;
// ローカルのdocsディレクトリを走査してキーワードが含まれるファイルを検索
const docsDir = path.resolve(process.cwd(), “docs”);
if (!fs.existsSync(docsDir)) {
return { content: [{ type: “text”, text: “docsディレクトリが見つかりませんでした。” }] };
}
const files = fs.readdirSync(docsDir);
let matchedContent = “”;
for (const file of files) {
if (file.endsWith(“.md”)) {
const filePath = path.join(docsDir, file);
const content = fs.readFileSync(filePath, “utf-8”);
if (content.toLowerCase().includes(keyword.toLowerCase())) {
matchedContent += `— File: ${file} —\n${content}\n\n`;
}
}
}
return {
content: [
{
type: “text”,
text: matchedContent || “該当するドキュメントが見つかりませんでした。”,
},
],
};
}
throw new Error(`未知のツール呼び出しです: ${name}`);
} catch (error: any) {
return {
content: [
{
type: “text”,
text: `エラーが発生しました: ${error.message}`,
},
],
isError: true,
};
}
});
// 5. 標準入出力(stdio)トランスポートでサーバーを起動
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error(“Internal Enterprise MCP Server running on stdio”);
}
main().catch((error) => {
console.error(“Server fatal error:”, error);
process.exit(1);
});
—
4. CursorへのMCPサーバー登録と設定ファイルのベストプラクティス
作成したカスタムMCPサーバーをCursorに認識させます。Cursorは、ホームディレクトリ直下またはプロジェクト設定にある `cursor.json` もしくは専用のMCP設定ファイルを読み込みます。
通常、Cursorの設定画面(Settings > Features > MCP)からGUIで追加することも可能ですが、チームメンバー間で設定を完全に同期し、CI環境や別PCへ即座に環境を移行するためには、プロジェクトルートの `.cursor/mcp.json`(またはグローバル設定)で管理するのがプロの開発者のアプローチです。
`mcp.json` のベストプラクティス構成例
プロジェクトのルートに `.cursor/mcp.json` を作成し、先ほど作成したTypeScript製MCPサーバーを登録します。
{
“mcpServers”: {
“internal-enterprise-mcp”: {
“command”: “npx”,
“args”: [
“tsx”,
“/absolute/path/to/cursor-custom-mcp/src/index.ts”
],
“env”: {
“DATABASE_URL”: “postgresql://postgres:password@localhost:5432/app_db”
}
},
“filesystem”: {
“command”: “npx”,
“args”: [
“-y”,
“@modelcontextprotocol/server-filesystem”,
“/absolute/path/to/your/workspace/docs”
]
}
}
}
> アーキテクトの知見(絶対的な注意点):
> `mcp.json` 内のパスを指定する際、相対パス(`./src/…`)は環境によって解決に失敗するリスクがあります。必ず絶対パスで記述するか、プロジェクトルートを動的に解決するラッパースクリプトを挟んでください。また、`env` ブロックにデータベースの接続文字列やAPIトークンを入れるため、絶対にこのファイルを Git にコミットせず、`.gitignore` に追加してください。 チーム共有が必要な場合は `.mcp.json.example` を用意し、各自でローカル設定を行わせるのが鉄則です。
—
5. 実動作の検証:CursorのAIが外部データを直接叩く瞬間
設定が完了し、Cursorを再起動すると、チャット入力欄の右下に小さなスパナ(ツール)のアイコン、もしくはMCPサーバーが接続されたことを示すインジケーターが表示されます。
ここで、Composer(`Cmd + K` または `Cmd + I`)を開き、以下のようにプロンプトを投げかけてみてください。
> プロンプト例:
> 「現在のデータベースのユーザーテーブルのスキーマを確認し、それに準拠した新規ユーザー登録用のPrismaモデルと、バリデーションを含んだExpressのコントローラー関数を実装してください。ついでに社内ドキュメントの決済フロー仕様も参照して、必要な例外処理を組み込んでください。」
内部で何が起きているのか?(データフローの完全解説)
1. AIの意図理解: CursorのLLM(Claude 3.5 Sonnetなど)がユーザーのプロンプトを解析し、「外部DBのスキーマ」と「社内ドキュメント」の情報が必要であると自律的に判断します。
2. ツール選択と実行: LLMはMCPサーバーが提供する `get_database_schema` と `search_internal_docs` を呼び出すためのJSONリクエストを、標準入出力(stdio)経由で私たちのTypeScript製MCPサーバーに送信します。
3. データ取得: MCPサーバーがローカルのPostgreSQLに安全にクエリを発行し、さらに `docs/` ディレクトリからマークダウンの内容を抽出します。
4. コンテキスト統合とコード生成: 取得された最新の生データ(DBスキーマや仕様書)がLLMのコンテキストウィンドウにリアルタイムに注入され、「過去の学習データ」ではなく「今目の前にある最新の社内仕様」に完全一致したコードがエディタ上に生成されます。
—
おわりに:次世代の開発体験を手に入れろ
今回は、CursorのMCP連携を通じて、ローカルデータベースや外部ドキュメントをAIに直接参照させ、回答精度を極限まで高めるカスタムMCPサーバーの実装と実践的な設定手法を解説しました。
- MCPの導入により、AIは単なる「コードを生成するおもちゃ」から「あなたの会社のシステムを完全に入り込んだシニアエンジニア」へと進化する。
- `.cursorrules` と `mcp.json` を駆使することで、チーム全体の開発コンテキストとコード品質を強固に同期できる。
この技術をマスターした開発チームと、そうでないチームの間には、今後数ヶ月で圧倒的な生産性の差が生まれます。ぜひあなたのプロジェクトにも今日の知見を取り入れ、開発スピードを次の次元へと引き上げてください。