0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【実戦】TypeScriptで独自の「MCPサーバー」を自作して、ローカルのSQLiteデータをAIに直接操作させてみる

0
Posted at

はじめに:AIに「自社データ」を触らせる最も簡単な方法

「CursorなどのAIツールに、ローカルにある特定のSQLiteデータベースの中身を直接クエリさせて、データ分析やデバッグをさせたい」
これを実現するための新しい世界標準がMCP(Model Context Protocol)です。
今回は、Node.js/TypeScriptを使って、「ローカルのSQLiteデータベースからデータを取得するツール」を持つMCPサーバーをスクラッチで自作してみます。
これさえできれば、自社の独自APIやローカルファイルをAIに自由自在に操作させることができるようになります。

ステップ1:プロジェクトのセットアップ

まずは適当なディレクトリを作成し、必要なライブラリをインストールします。MCP公式が提供しているSDK(@modelcontextprotocol/sdk)を使用します。

mkdir my-mcp-server
cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk sqlite3
npm install --save-dev typescript @types/node @types/sqlite3 ts-node
npx tsc --init

ステップ2:MCPサーバーの実装

index.ts を作成し、以下のコードを記述します。
このサーバーは、query_db という「SQLを実行してSQLiteからデータを取得するツール」をAIに提供します。

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 sqlite3 from "sqlite3";
import { open } from "sqlite";
// テスト用のSQLiteデータベースを開く
const db = await open({
  filename: "./database.db",
  driver: sqlite3.Database,
});
// 初期テーブルとデモデータの作成
await db.exec(`
  CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT);
  INSERT OR IGNORE INTO users (id, name, email) VALUES 
    (1, 'Alice', 'alice@example.com'),
    (2, 'Bob', 'bob@example.com');
`);
// MCPサーバーの初期化
const server = new Server(
  { name: "sqlite-mcp-server", version: "1.0.0" },
  { capabilities: { tools: {} } }
);
// 1. AIに対して「提供できるツールの一覧」を教える
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "query_db",
        description: "SQLiteデータベースに対してSQLクエリを実行します。",
        inputSchema: {
          type: "object",
          properties: {
            sql: { type: "string", description: "実行するSQLクエリ" },
          },
          required: ["sql"],
        },
      },
    ],
  };
});
// 2. AIが「ツールを実行した時」の実際の処理を定義する
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "query_db") {
    const sql = request.params.arguments?.sql as string;
    try {
      const results = await db.all(sql);
      return {
        content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
      };
    } catch (error: any) {
      return {
        content: [{ type: "text", text: `Error: ${error.message}` }],
        isError: true,
      };
    }
  }
  throw new Error("Unknown tool");
});
// 標準入出力(stdio)経由でクライアント(Cursorなど)と通信する設定で起動
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("SQLite MCP server running!");

ビルドの設定をしてコンパイルしておきます。
package.json に以下を追記して npm run build を実行します。

"scripts": {
  "build": "tsc"
}

ステップ3:Cursor(クライアント)への登録

ビルドしたMCPサーバーを、CursorなどのAIツールに登録します。

  1. Cursorの設定を開く (Settings -> Features -> MCP)
  2. + Add New MCP Server をクリック
  3. 以下の情報を入力します:
    • Name: sqlite-mcp
    • Type: command
    • Command: node /absolute/path/to/my-mcp-server/dist/index.js(ビルドされたJSファイルの絶対パス)

ステップ4:AIに直接クエリさせてみる

Cursorのチャット(またはComposer)を開き、AIに以下のように指示してみます。
query_db ツールを使って、usersテーブルからIDが1のユーザーのメールアドレスを調べて教えて」
すると、AIはあなたが書いたMCPサーバーの query_db ツールを自動で認識し、裏で SELECT email FROM users WHERE id = 1 というSQLを生成してサーバーに送信します。サーバーが返したJSON結果をAIが読み取り、「ID 1のAliceさんのメールアドレスは alice@example.com です」と自然な日本語で答えてくれます。

まとめ:MCPがもたらす「無限の拡張性」

今回はローカルのSQLiteデータベースを繋ぎましたが、同じ要領で:

  • 社内システムの社外秘APIを叩くツール
  • ローカルにある独自のログ解析スクリプトの実行ツール
    などをMCP経由でAIに提供できます。AIに「目と手(ツール)」を与えることで、開発効率は文字通り別次元になります。ぜひ独自のMCPサーバーを作って、自分だけのAIアシスタントを育ててみてください。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?