├── .env.example ├── .gitignore ├── tsconfig.json ├── start-mcp.sh ├── run-mcp.sh ├── src ├── config │ ├── config.ts │ └── tools.ts ├── utils │ └── logger.ts ├── middleware │ └── errorHandler.ts ├── services │ └── difyService.ts ├── routes │ └── toolsRoutes.ts └── index.ts ├── package.json └── README.md /.env.example: -------------------------------------------------------------------------------- 1 | # Dify API設定 2 | DIFY_BASE_URL=https://api.dify.ai/v1 3 | DIFY_SECRET_KEY=your_dify_secret_key_here 4 | 5 | # サーバー設定 6 | NODE_ENV=production 7 | LOG_LEVEL=info 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 依存関係 2 | node_modules/ 3 | 4 | # ビルド出力 5 | dist/ 6 | 7 | # 環境変数 8 | .env 9 | 10 | # ログ 11 | *.log 12 | 13 | # OS固有のファイル 14 | .DS_Store 15 | Thumbs.db 16 | 17 | # エディタ固有のファイル 18 | .vscode/ 19 | .idea/ 20 | *.swp 21 | *.swo 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "NodeNext", 5 | "moduleResolution": "NodeNext", 6 | "esModuleInterop": true, 7 | "outDir": "./dist", 8 | "rootDir": "./src", 9 | "strict": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "resolveJsonModule": true 13 | }, 14 | "include": ["src/**/*"], 15 | "exclude": ["node_modules", "dist", "src/routes/**/*"] 16 | } 17 | -------------------------------------------------------------------------------- /start-mcp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 現在のディレクトリに移動 4 | cd "$(dirname "$0")" 5 | 6 | # .envファイルから環境変数を読み込む 7 | if [ -f .env ]; then 8 | echo ".envファイルから環境変数を読み込んでいます..." 9 | export $(grep -v '^#' .env | xargs) 10 | else 11 | echo "警告: .envファイルが見つかりません。デフォルト設定を使用します。" 12 | export DIFY_BASE_URL="https://api.dify.ai/v1" 13 | export DIFY_SECRET_KEY="YOUR_DIFY_SECRET_KEY" # ここに実際のDify APIキーを設定してください 14 | export NODE_ENV=production 15 | export LOG_LEVEL=info 16 | fi 17 | 18 | # サーバーの起動 19 | echo "Dify MCP サーバーを起動しています..." 20 | node dist/index.js 21 | -------------------------------------------------------------------------------- /run-mcp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # スクリプトのディレクトリを取得 4 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 5 | 6 | # .envファイルのパス 7 | ENV_FILE="${SCRIPT_DIR}/.env" 8 | 9 | # .envファイルから環境変数を読み込む 10 | if [ -f "${ENV_FILE}" ]; then 11 | # .envファイルから環境変数を読み込む 12 | source "${ENV_FILE}" 13 | else 14 | # デフォルト値を設定 15 | DIFY_BASE_URL="https://api.dify.ai/v1" 16 | DIFY_SECRET_KEY="YOUR_DIFY_SECRET_KEY" 17 | NODE_ENV="production" 18 | LOG_LEVEL="info" 19 | fi 20 | 21 | # 環境変数を設定してサーバーを実行 22 | exec env DIFY_BASE_URL="${DIFY_BASE_URL}" DIFY_SECRET_KEY="${DIFY_SECRET_KEY}" NODE_ENV="${NODE_ENV}" LOG_LEVEL="${LOG_LEVEL}" node "${SCRIPT_DIR}/dist/index.js" 23 | -------------------------------------------------------------------------------- /src/config/config.ts: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv'; 2 | import logger from '../utils/logger.js'; 3 | 4 | // .envファイルの読み込み 5 | dotenv.config(); 6 | 7 | // 環境変数の設定 8 | export const config = { 9 | dify: { 10 | baseUrl: process.env.DIFY_BASE_URL || 'https://api.dify.ai/v1', 11 | secretKey: process.env.DIFY_SECRET_KEY || '', 12 | }, 13 | server: { 14 | port: parseInt(process.env.SERVER_PORT || '3034', 10), 15 | env: process.env.NODE_ENV || 'development', 16 | }, 17 | }; 18 | 19 | // 設定の検証 20 | export function validateConfig() { 21 | if (!config.dify.secretKey) { 22 | throw new Error('DIFY_SECRET_KEY環境変数が設定されていません'); 23 | } 24 | 25 | logger.debug('設定を読み込みました', { config }); 26 | } 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dify-mcp4", 3 | "version": "1.0.0", 4 | "main": "dist/index.js", 5 | "type": "module", 6 | "scripts": { 7 | "build": "tsc", 8 | "start": "node dist/index.js", 9 | "dev": "ts-node src/index.ts", 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "description": "", 16 | "dependencies": { 17 | "@modelcontextprotocol/sdk": "^1.6.0", 18 | "axios": "^1.7.9", 19 | "dotenv": "^16.4.7", 20 | "express": "^5.0.1", 21 | "winston": "^3.17.0" 22 | }, 23 | "devDependencies": { 24 | "@types/express": "^5.0.0", 25 | "@types/node": "^22.13.5", 26 | "ts-node": "^10.9.2", 27 | "typescript": "^5.7.3" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/utils/logger.ts: -------------------------------------------------------------------------------- 1 | import winston from 'winston'; 2 | 3 | // ログレベルの設定 4 | const logLevel = process.env.LOG_LEVEL || 'info'; 5 | 6 | // ロガーの設定 7 | const logger = winston.createLogger({ 8 | level: logLevel, 9 | format: winston.format.combine( 10 | winston.format.timestamp(), 11 | winston.format.json() 12 | ), 13 | transports: [ 14 | new winston.transports.Console({ 15 | format: winston.format.combine( 16 | winston.format.colorize(), 17 | winston.format.printf(({ level, message, timestamp, ...meta }) => { 18 | return `${timestamp} ${level}: ${message} ${ 19 | Object.keys(meta).length ? JSON.stringify(meta, null, 2) : '' 20 | }`; 21 | }) 22 | ), 23 | }), 24 | ], 25 | }); 26 | 27 | export default logger; 28 | -------------------------------------------------------------------------------- /src/middleware/errorHandler.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response, NextFunction } from 'express'; 2 | import logger from '../utils/logger.js'; 3 | 4 | // 404エラーハンドラー 5 | export const notFoundHandler = (req: Request, res: Response) => { 6 | logger.warn(`リクエストされたパスが見つかりません: ${req.originalUrl}`); 7 | res.status(404).json({ 8 | error: 'Not Found', 9 | message: 'リクエストされたリソースが見つかりません', 10 | }); 11 | }; 12 | 13 | // グローバルエラーハンドラー 14 | export const errorHandler = ( 15 | err: Error, 16 | req: Request, 17 | res: Response, 18 | next: NextFunction 19 | ) => { 20 | logger.error('サーバーエラー', { error: err.message, stack: err.stack }); 21 | 22 | res.status(500).json({ 23 | error: 'Internal Server Error', 24 | message: process.env.NODE_ENV === 'production' 25 | ? 'サーバー内部でエラーが発生しました' 26 | : err.message, 27 | }); 28 | }; 29 | -------------------------------------------------------------------------------- /src/config/tools.ts: -------------------------------------------------------------------------------- 1 | // MCP ツールの定義 2 | const tools = [ 3 | { 4 | name: 'dify-chat', 5 | description: 'Difyチャットアプリにクエリを送信し、応答を取得します', 6 | parameters: { 7 | type: 'object', 8 | properties: { 9 | query: { 10 | type: 'string', 11 | description: 'Difyに送信するクエリ', 12 | }, 13 | conversation_id: { 14 | type: 'string', 15 | description: '会話ID(オプション)。会話を継続する場合に指定します。', 16 | }, 17 | }, 18 | required: ['query'], 19 | }, 20 | }, 21 | { 22 | name: 'knowledge-base-query', 23 | description: 'Difyの知識ベースにクエリを送信し、応答を取得します', 24 | parameters: { 25 | type: 'object', 26 | properties: { 27 | query: { 28 | type: 'string', 29 | description: '知識ベースに送信するクエリ', 30 | }, 31 | knowledge_base_id: { 32 | type: 'string', 33 | description: '知識ベースID', 34 | }, 35 | conversation_id: { 36 | type: 'string', 37 | description: '会話ID(オプション)', 38 | }, 39 | }, 40 | required: ['query', 'knowledge_base_id'], 41 | }, 42 | }, 43 | ]; 44 | 45 | export default tools; 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dify Connect MCP 2 | 3 | Dify APIと連携するModel Context Protocol (MCP) サーバー。 4 | 5 | ## 概要 6 | 7 | このMCPサーバーは、Dify APIと連携して、チャットアプリケーションにクエリを送信し、結果を取得する機能を提供します。 8 | 9 | ## 機能 10 | 11 | - **dify-chat**: Difyチャットアプリにクエリを送信し、応答を取得します 12 | - **knowledge-base-query**: Difyの知識ベースにクエリを送信し、応答を取得します 13 | 14 | ## セットアップ 15 | 16 | ### 前提条件 17 | 18 | - Node.js (v16以上) 19 | - npm 20 | - Dify APIキー 21 | 22 | ### インストール 23 | 24 | 1. 依存関係をインストールします: 25 | 26 | ```bash 27 | npm install 28 | ``` 29 | 30 | 2. TypeScriptコードをコンパイルします: 31 | 32 | ```bash 33 | ./build.sh 34 | ``` 35 | 36 | ### 設定 37 | 38 | 以下の環境変数を設定する必要があります: 39 | 40 | - `DIFY_BASE_URL`: Dify APIのベースURL(デフォルト: https://api.dify.ai/v1) 41 | - `DIFY_SECRET_KEY`: Dify APIキー(必須) 42 | - `NODE_ENV`: 実行環境(development/production) 43 | - `LOG_LEVEL`: ログレベル(debug/info/warn/error) 44 | 45 | これらの環境変数は、`.env`ファイルで設定できます: 46 | 47 | 1. `.env.example`ファイルを`.env`にコピーします: 48 | 49 | ```bash 50 | cp .env.example .env 51 | ``` 52 | 53 | 2. `.env`ファイルを編集して、実際のDify APIキーを設定します: 54 | 55 | ``` 56 | # Dify API設定 57 | DIFY_BASE_URL=https://api.dify.ai/v1 58 | DIFY_SECRET_KEY=your_actual_dify_secret_key_here 59 | 60 | # サーバー設定 61 | NODE_ENV=production 62 | LOG_LEVEL=info 63 | ``` 64 | 65 | スクリプト(`start-mcp.sh`と`run-mcp.sh`)は自動的に`.env`ファイルから環境変数を読み込みます。 66 | 67 | ### 実行 68 | 69 | サーバーを起動するには: 70 | 71 | ```bash 72 | ./start-mcp.sh 73 | ``` 74 | 75 | ## MCPサーバーの設定 76 | 77 | Clineで使用するには、MCPサーバー設定ファイルに以下を追加します: 78 | 79 | ```json 80 | { 81 | "mcpServers": { 82 | "dify-connect-mcp": { 83 | "command": "/bin/bash", 84 | "args": ["<リポジトリのパス>/run-mcp.sh"], 85 | "disabled": false, 86 | "autoApprove": [] 87 | } 88 | } 89 | } 90 | ``` 91 | 92 | `<リポジトリのパス>`は、実際のリポジトリのパスに置き換えてください。 93 | 94 | この設定では、`run-mcp.sh`スクリプトが`.env`ファイルから環境変数を読み込むため、MCPサーバー設定ファイルに直接APIキーを記述する必要はありません。 95 | 96 | ## 使用例 97 | 98 | MCPサーバーが設定されると、以下のようなコマンドでDifyにクエリを送信できます: 99 | 100 | ``` 101 | dify-chat "こんにちは、今日の天気は?" 102 | ``` 103 | 104 | または知識ベースにクエリを送信: 105 | 106 | ``` 107 | knowledge-base-query "製品の特徴について教えてください" "knowledge_base_id_here" 108 | -------------------------------------------------------------------------------- /src/services/difyService.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { config } from '../config/config.js'; 3 | import logger from '../utils/logger.js'; 4 | 5 | // Dify API クライアントの設定 6 | const difyClient = axios.create({ 7 | baseURL: config.dify.baseUrl, 8 | headers: { 9 | 'Content-Type': 'application/json', 10 | 'Authorization': `Bearer ${config.dify.secretKey}`, 11 | }, 12 | }); 13 | 14 | // エラーハンドリング 15 | difyClient.interceptors.response.use( 16 | (response) => response, 17 | (error) => { 18 | if (error.response) { 19 | logger.error('Dify API エラー', { 20 | status: error.response.status, 21 | data: error.response.data, 22 | }); 23 | } else if (error.request) { 24 | logger.error('Dify API リクエストエラー', { request: error.request }); 25 | } else { 26 | logger.error('Dify API 未知のエラー', { message: error.message }); 27 | } 28 | return Promise.reject(error); 29 | } 30 | ); 31 | 32 | // Dify サービス 33 | const difyService = { 34 | /** 35 | * チャットメッセージを送信する 36 | */ 37 | async sendChatMessage(params: { 38 | inputs?: Record; 39 | query: string; 40 | response_mode: 'streaming' | 'blocking'; 41 | conversation_id?: string; 42 | user: string; 43 | }) { 44 | try { 45 | logger.debug('Dify チャットメッセージを送信します', { params }); 46 | 47 | const response = await difyClient.post('/chat-messages', params); 48 | 49 | logger.debug('Dify チャットレスポンスを受信しました', { 50 | status: response.status, 51 | data: response.data, 52 | }); 53 | 54 | return response.data; 55 | } catch (error) { 56 | logger.error('Dify チャットメッセージの送信に失敗しました', { error }); 57 | throw error; 58 | } 59 | }, 60 | 61 | /** 62 | * 知識ベースにクエリを送信する 63 | */ 64 | async queryKnowledgeBase( 65 | query: string, 66 | knowledgeBaseId: string, 67 | conversationId?: string 68 | ) { 69 | try { 70 | logger.debug('Dify 知識ベースにクエリを送信します', { 71 | query, 72 | knowledgeBaseId, 73 | conversationId, 74 | }); 75 | 76 | // 知識ベースへのクエリは通常のチャットメッセージと同じエンドポイントを使用 77 | // ただし、知識ベースIDを指定する必要がある 78 | const response = await difyClient.post('/chat-messages', { 79 | inputs: { knowledge_base_id: knowledgeBaseId }, 80 | query, 81 | response_mode: 'blocking', 82 | conversation_id: conversationId, 83 | user: 'default', 84 | }); 85 | 86 | logger.debug('Dify 知識ベースレスポンスを受信しました', { 87 | status: response.status, 88 | data: response.data, 89 | }); 90 | 91 | return response.data; 92 | } catch (error) { 93 | logger.error('Dify 知識ベースクエリの送信に失敗しました', { error }); 94 | throw error; 95 | } 96 | }, 97 | }; 98 | 99 | export default difyService; 100 | -------------------------------------------------------------------------------- /src/routes/toolsRoutes.ts: -------------------------------------------------------------------------------- 1 | import { Router, Request, Response } from 'express'; 2 | import difyService from '../services/difyService.js'; 3 | import logger from '../utils/logger.js'; 4 | 5 | const router = Router(); 6 | 7 | // ツール一覧を取得 8 | router.get('/', (req: Request, res: Response) => { 9 | res.json({ 10 | tools: [ 11 | { 12 | name: 'dify-chat', 13 | description: 'Difyチャットアプリにクエリを送信し、応答を取得します', 14 | }, 15 | { 16 | name: 'knowledge-base-query', 17 | description: 'Difyの知識ベースにクエリを送信し、応答を取得します', 18 | }, 19 | ], 20 | }); 21 | }); 22 | 23 | interface DifyChatRequest { 24 | query: string; 25 | conversation_id?: string; 26 | } 27 | 28 | interface KnowledgeBaseRequest { 29 | query: string; 30 | knowledge_base_id: string; 31 | conversation_id?: string; 32 | } 33 | 34 | // Difyチャットツール 35 | router.post('/dify-chat', async (req: Request<{}, any, DifyChatRequest>, res: Response) => { 36 | try { 37 | const { query, conversation_id } = req.body; 38 | 39 | if (!query) { 40 | return res.status(400).json({ 41 | error: 'Bad Request', 42 | message: 'クエリパラメータが必要です', 43 | }); 44 | } 45 | 46 | logger.info(`Difyチャットツールを実行: "${query}"`); 47 | 48 | const response = await difyService.sendChatMessage({ 49 | inputs: {}, 50 | query, 51 | response_mode: 'blocking', 52 | conversation_id, 53 | user: 'default', 54 | }); 55 | 56 | res.json(response); 57 | } catch (error: any) { 58 | logger.error('Difyチャットツールの実行に失敗しました', { error }); 59 | 60 | res.status(500).json({ 61 | error: 'Internal Server Error', 62 | message: error.message || 'Difyチャットツールの実行中にエラーが発生しました', 63 | }); 64 | } 65 | }); 66 | 67 | // 知識ベースクエリツール 68 | router.post('/knowledge-base-query', async (req: Request<{}, any, KnowledgeBaseRequest>, res: Response) => { 69 | try { 70 | const { query, knowledge_base_id, conversation_id } = req.body; 71 | 72 | if (!query) { 73 | return res.status(400).json({ 74 | error: 'Bad Request', 75 | message: 'クエリパラメータが必要です', 76 | }); 77 | } 78 | 79 | if (!knowledge_base_id) { 80 | return res.status(400).json({ 81 | error: 'Bad Request', 82 | message: '知識ベースIDが必要です', 83 | }); 84 | } 85 | 86 | logger.info(`知識ベースクエリツールを実行: "${query}"`); 87 | 88 | const response = await difyService.queryKnowledgeBase( 89 | query, 90 | knowledge_base_id, 91 | conversation_id 92 | ); 93 | 94 | res.json(response); 95 | } catch (error: any) { 96 | logger.error('知識ベースクエリツールの実行に失敗しました', { error }); 97 | 98 | res.status(500).json({ 99 | error: 'Internal Server Error', 100 | message: error.message || '知識ベースクエリツールの実行中にエラーが発生しました', 101 | }); 102 | } 103 | }); 104 | 105 | export default router; 106 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { Server } from '@modelcontextprotocol/sdk/server/index.js'; 3 | import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; 4 | import { 5 | CallToolRequestSchema, 6 | ErrorCode, 7 | ListToolsRequestSchema, 8 | McpError, 9 | } from '@modelcontextprotocol/sdk/types.js'; 10 | import logger from './utils/logger.js'; 11 | import tools from './config/tools.js'; 12 | import difyService from './services/difyService.js'; 13 | import { config, validateConfig } from './config/config.js'; 14 | 15 | // 設定の検証 16 | try { 17 | validateConfig(); 18 | } catch (error: any) { 19 | logger.error(`設定エラー: ${error.message}`); 20 | process.exit(1); 21 | } 22 | 23 | class DifyMcpServer { 24 | private server: Server; 25 | 26 | constructor() { 27 | this.server = new Server( 28 | { 29 | name: 'dify-mcp-server', 30 | version: '1.0.0', 31 | }, 32 | { 33 | capabilities: { 34 | tools: { 35 | 'dify-chat': { 36 | description: 'Difyチャットアプリにクエリを送信し、応答を取得します', 37 | parameters: { 38 | type: 'object', 39 | properties: { 40 | query: { 41 | type: 'string', 42 | description: 'Difyに送信するクエリ', 43 | }, 44 | conversation_id: { 45 | type: 'string', 46 | description: '会話ID(オプション)。会話を継続する場合に指定します。', 47 | }, 48 | }, 49 | required: ['query'], 50 | }, 51 | }, 52 | 'knowledge-base-query': { 53 | description: 'Difyの知識ベースにクエリを送信し、応答を取得します', 54 | parameters: { 55 | type: 'object', 56 | properties: { 57 | query: { 58 | type: 'string', 59 | description: '知識ベースに送信するクエリ', 60 | }, 61 | knowledge_base_id: { 62 | type: 'string', 63 | description: '知識ベースID', 64 | }, 65 | conversation_id: { 66 | type: 'string', 67 | description: '会話ID(オプション)', 68 | }, 69 | }, 70 | required: ['query', 'knowledge_base_id'], 71 | }, 72 | }, 73 | }, 74 | }, 75 | } 76 | ); 77 | 78 | this.setupToolHandlers(); 79 | 80 | // エラーハンドリング 81 | this.server.onerror = (error) => logger.error('[MCP Error]', error); 82 | process.on('SIGINT', async () => { 83 | await this.server.close(); 84 | process.exit(0); 85 | }); 86 | } 87 | 88 | private setupToolHandlers() { 89 | // ListToolsRequestSchema ハンドラーは不要です。 90 | // MCPサーバーは capabilities に設定されたツールを自動的に公開します。 91 | 92 | this.server.setRequestHandler(CallToolRequestSchema, async (request) => { 93 | try { 94 | let response; 95 | 96 | switch (request.params.name) { 97 | case 'dify-chat': 98 | if (!request.params.arguments || typeof request.params.arguments.query !== 'string') { 99 | throw new McpError( 100 | ErrorCode.InvalidParams, 101 | 'クエリパラメータが必要です' 102 | ); 103 | } 104 | 105 | logger.info(`Difyチャットツールを実行: "${request.params.arguments.query}"`); 106 | 107 | const chatResponse = await difyService.sendChatMessage({ 108 | inputs: {}, 109 | query: request.params.arguments.query, 110 | response_mode: 'blocking', 111 | conversation_id: typeof request.params.arguments.conversation_id === 'string' 112 | ? request.params.arguments.conversation_id 113 | : undefined, 114 | user: 'default' 115 | }); 116 | 117 | return { 118 | content: [ 119 | { 120 | type: 'text', 121 | text: JSON.stringify(chatResponse, null, 2), 122 | }, 123 | ], 124 | }; 125 | 126 | case 'knowledge-base-query': 127 | if (!request.params.arguments || typeof request.params.arguments.query !== 'string') { 128 | throw new McpError( 129 | ErrorCode.InvalidParams, 130 | 'クエリパラメータが必要です' 131 | ); 132 | } 133 | 134 | if (!request.params.arguments || typeof request.params.arguments.knowledge_base_id !== 'string') { 135 | throw new McpError( 136 | ErrorCode.InvalidParams, 137 | '知識ベースIDが必要です' 138 | ); 139 | } 140 | 141 | logger.info(`知識ベースクエリツールを実行: "${request.params.arguments.query}"`); 142 | 143 | const kbResponse = await difyService.queryKnowledgeBase( 144 | request.params.arguments.query, 145 | request.params.arguments.knowledge_base_id, 146 | typeof request.params.arguments.conversation_id === 'string' 147 | ? request.params.arguments.conversation_id 148 | : undefined 149 | ); 150 | 151 | return { 152 | content: [ 153 | { 154 | type: 'text', 155 | text: JSON.stringify(kbResponse, null, 2), 156 | }, 157 | ], 158 | }; 159 | 160 | default: 161 | throw new McpError( 162 | ErrorCode.MethodNotFound, 163 | `未知のツール: ${request.params.name}` 164 | ); 165 | } 166 | } catch (error: any) { 167 | if (error instanceof McpError) { 168 | throw error; 169 | } 170 | 171 | logger.error(`ツール実行エラー: ${error.message}`, { error }); 172 | 173 | return { 174 | content: [ 175 | { 176 | type: 'text', 177 | text: `エラー: ${error.message || 'ツール実行中にエラーが発生しました'}`, 178 | }, 179 | ], 180 | isError: true, 181 | }; 182 | } 183 | }); 184 | } 185 | 186 | async run() { 187 | const transport = new StdioServerTransport(); 188 | await this.server.connect(transport); 189 | logger.info('Dify MCP サーバーが起動しました'); 190 | logger.info(`環境: ${config.server.env}`); 191 | logger.info('利用可能なツール:'); 192 | tools.forEach(tool => { 193 | logger.info(`- ${tool.name}: ${tool.description}`); 194 | }); 195 | } 196 | } 197 | 198 | const server = new DifyMcpServer(); 199 | server.run().catch(console.error); 200 | --------------------------------------------------------------------------------