統合ガイド - 高度な使用パターン
開発ワークフロー、CI/CDパイプライン、カスタムアプリケーションとのFluorite MCP統合に関する包括的なガイドです。
🎯 クイックリンク: 詳細な実世界のシナリオと例については、使用例・ケーススタディガイドを参照してください
📖 目次
- Claude Code CLI統合
- 開発ワークフロー統合
- CI/CDパイプライン統合
- IDEとエディタ統合
- カスタムアプリケーション統合
- チームコラボレーションパターン
- エンタープライズデプロイ
- 監視とオブザーバビリティ
Claude Code CLI統合
基本セットアップと設定
標準インストール
bash
# Fluorite MCPをグローバルインストール
npm install -g fluorite-mcp
# 正しいサーバーバイナリでClaude Code CLIに追加
claude mcp add fluorite-mcp -- fluorite-mcp
# インストール確認
claude mcp list
claude mcp status fluorite
高度な設定
bash
# カスタムカタログディレクトリ
export FLUORITE_CATALOG_DIR="/path/to/custom/specs"
# パフォーマンス最適化
export NODE_OPTIONS="--max-old-space-size=4096"
export FLUORITE_CACHE_TTL="3600"
# 詳細ログ付き開発モード
export FLUORITE_LOG_LEVEL="debug"
export FLUORITE_LOG_FILE="/path/to/fluorite.log"
自然言語統合パターン
ライブラリ特有のリクエスト
# 自動仕様アクセス
"Zod検証付きreact-hook-formを使用したフォームコンポーネントを作成"
→ アクセス: spec://react-hook-form, spec://zod
"PrismaとJWT認証付きNext.js APIルートを構築"
→ アクセス: spec://nextjs, spec://prisma, spec://nextauth
"アクセシビリティチェック付きPlaywrightテストをセットアップ"
→ アクセス: spec://playwright, spec://playwright-axe-accessibility
フレームワーク対応開発
# Next.js開発
"このNext.jsコンポーネントをハイドレーション問題について解析"
→ 使用: nextjsフレームワークルール付き静的解析
"認証用Next.jsミドルウェアを作成"
→ 使用: spikeテンプレート + 静的解析検証
# React開発
"このReactコンポーネントをパフォーマンス向上のため最適化"
→ 使用: React特有の解析ルール + パフォーマンス推奨
ワークフロー最適化
開発前セットアップ
bash
# 検証付きプロジェクト初期化
claude-code "プロジェクト構造を解析し改善点を提案"
# フレームワーク特有のセットアップ
claude-code "strictモード付きNext.js用TypeScript設定をセットアップ"
アクティブ開発
bash
# 開発中のリアルタイム検証
claude-code "このコンポーネントのリアルタイム検証を有効化"
# クイックコード検証
claude-code "このhook実装をReactベストプラクティスでチェック"
プリコミット統合
bash
# コミット前の静的解析
claude-code "変更されたファイルに包括的な静的解析を実行"
# Spike検証
claude-code "このspike実装がベストプラクティスに従っているか検証"
開発ワークフロー統合
Gitワークフロー統合
プリコミットフック
bash
#!/bin/bash
# .git/hooks/pre-commit
echo "Fluorite MCP解析を実行中..."
# ステージングされたファイルのリストを取得
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(ts|tsx|js|jsx|vue)$')
if [ ! -z "$STAGED_FILES" ]; then
# ステージングされたファイルの静的解析を実行
claude-code "これらのステージングファイルの問題を解析: $STAGED_FILES"
# 終了コードをチェック
if [ $? -ne 0 ]; then
echo "❌ 静的解析で問題が見つかりました。コミット前に修正してください。"
exit 1
fi
fi
echo "✅ 静的解析が通過しました"
プルリクエスト検証
yaml
# .github/workflows/pr-validation.yml
name: Fluorite MCPによるPR検証
on:
pull_request:
branches: [main, develop]
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Node.jsセットアップ
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Fluorite MCPインストール
run: npm install -g fluorite-mcp
- name: 静的解析実行
run: |
fluorite-mcp --static-analysis \
--project-path . \
--framework nextjs \
--predict-errors \
--max-issues 50
- name: Spikeテンプレート検証
run: |
fluorite-mcp --validate-spikes \
--check-integrity \
--verify-dependencies
コードレビュー強化
自動コードレビュー
typescript
// scripts/code-review.ts
import { MCPClient } from '@modelcontextprotocol/sdk';
class FluoriteCodeReview {
private client: MCPClient;
constructor() {
this.client = new MCPClient({
command: 'fluorite-mcp',
args: []
});
}
async reviewPullRequest(files: string[]) {
const results = [];
for (const file of files) {
// 各ファイルの静的解析
const analysis = await this.client.callTool('static-analysis', {
targetFiles: [file],
framework: this.detectFramework(file),
predictErrors: true
});
// Spikeパターンマッチング
const patterns = await this.client.callTool('spike-patterns-match', {
file: file,
context: 'code-review'
});
results.push({
file,
analysis: analysis.content,
patterns: patterns.content,
recommendations: await this.generateRecommendations(file, analysis)
});
}
return this.generateReviewReport(results);
}
private async generateRecommendations(file: string, analysis: any) {
// ファイル固有の改善推奨を生成
return await this.client.callTool('code-improvement-suggestions', {
file,
analysisResults: analysis,
focus: ['performance', 'security', 'maintainability']
});
}
}
自動品質ゲート
品質メトリクス追跡
typescript
// scripts/quality-gates.ts
interface QualityMetrics {
codeComplexity: number;
testCoverage: number;
securityScore: number;
performanceScore: number;
maintainabilityIndex: number;
}
class QualityGateValidator {
private thresholds = {
codeComplexity: 10, // 最大循環複雑度
testCoverage: 80, // 最小テストカバレッジ(%)
securityScore: 7, // 最小セキュリティスコア(1-10)
performanceScore: 8, // 最小パフォーマンススコア(1-10)
maintainabilityIndex: 70 // 最小保守性インデックス
};
async validateQualityGates(projectPath: string): Promise<boolean> {
const metrics = await this.calculateMetrics(projectPath);
const violations = this.checkThresholds(metrics);
if (violations.length > 0) {
console.log('❌ 品質ゲート失敗:');
violations.forEach(v => console.log(` - ${v}`));
return false;
}
console.log('✅ すべての品質ゲートが通過しました');
return true;
}
private async calculateMetrics(projectPath: string): Promise<QualityMetrics> {
// Fluorite MCPツールを使用してメトリクスを計算
const analysis = await this.client.callTool('static-analysis', {
projectPath,
includeMetrics: true,
calculateComplexity: true
});
return {
codeComplexity: analysis.metrics.averageComplexity,
testCoverage: analysis.metrics.testCoverage,
securityScore: analysis.security.overallScore,
performanceScore: analysis.performance.overallScore,
maintainabilityIndex: analysis.maintainability.index
};
}
}
CI/CDパイプライン統合
GitHub Actions統合
完全なCI/CDワークフロー
yaml
# .github/workflows/ci-cd.yml
name: CI/CD with Fluorite MCP
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
NODE_VERSION: '20'
FLUORITE_LOG_LEVEL: 'info'
jobs:
quality-analysis:
name: コード品質解析
runs-on: ubuntu-latest
outputs:
analysis-results: ${{ steps.analysis.outputs.results }}
steps:
- name: コードチェックアウト
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Node.jsセットアップ
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: 依存関係インストール
run: |
npm ci
npm install -g fluorite-mcp
- name: フレームワーク検出
id: framework
run: |
FRAMEWORK=$(fluorite-mcp --detect-framework .)
echo "framework=$FRAMEWORK" >> $GITHUB_OUTPUT
- name: 静的解析実行
id: analysis
run: |
fluorite-mcp --static-analysis \
--project-path . \
--framework ${{ steps.framework.outputs.framework }} \
--output-format json \
--predict-errors \
--max-issues 100 > analysis-results.json
echo "results=$(cat analysis-results.json)" >> $GITHUB_OUTPUT
- name: セキュリティスキャン
run: |
fluorite-mcp --security-scan \
--check-dependencies \
--scan-secrets \
--validate-configs
- name: パフォーマンス解析
run: |
fluorite-mcp --performance-analysis \
--check-bundle-size \
--analyze-runtime \
--suggest-optimizations
- name: 解析結果をアーティファクトとして保存
uses: actions/upload-artifact@v3
with:
name: analysis-results
path: analysis-results.json
spike-validation:
name: Spikeテンプレート検証
runs-on: ubuntu-latest
needs: quality-analysis
steps:
- uses: actions/checkout@v4
- name: Fluorite MCPセットアップ
run: npm install -g fluorite-mcp
- name: Spikeパターン検証
run: |
fluorite-mcp --validate-spikes \
--check-integrity \
--verify-dependencies \
--validate-patterns
- name: テンプレート使用法解析
run: |
fluorite-mcp --analyze-spike-usage \
--project-path . \
--suggest-improvements
build-and-test:
name: ビルドとテスト
runs-on: ubuntu-latest
needs: [quality-analysis, spike-validation]
strategy:
matrix:
node-version: [18, 20]
steps:
- uses: actions/checkout@v4
- name: Node.js ${{ matrix.node-version }}セットアップ
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: 依存関係インストール
run: npm ci
- name: Fluorite MCP強化ビルド
run: |
npm install -g fluorite-mcp
fluorite-mcp --enhanced-build \
--optimize-bundle \
--validate-types \
--check-compatibility
- name: テスト実行(Fluorite推奨付き)
run: |
fluorite-mcp --enhance-tests \
--generate-missing-tests \
--validate-coverage
npm test
deployment:
name: デプロイ
runs-on: ubuntu-latest
needs: build-and-test
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: デプロイ前検証
run: |
npm install -g fluorite-mcp
fluorite-mcp --pre-deployment-check \
--validate-environment \
--check-dependencies \
--verify-configs
- name: 本番デプロイ
run: |
# あなたのデプロイスクリプト
echo "Fluorite MCP検証済みデプロイを実行"
Jenkins統合
Jenkinsパイプライン
groovy
// Jenkinsfile
pipeline {
agent any
environment {
NODE_VERSION = '20'
FLUORITE_LOG_LEVEL = 'info'
}
stages {
stage('セットアップ') {
steps {
sh 'nvm use ${NODE_VERSION}'
sh 'npm install -g fluorite-mcp'
sh 'npm ci'
}
}
stage('品質解析') {
parallel {
stage('静的解析') {
steps {
script {
def framework = sh(
script: 'fluorite-mcp --detect-framework .',
returnStdout: true
).trim()
sh """
fluorite-mcp --static-analysis \\
--project-path . \\
--framework ${framework} \\
--output-format junit \\
--output-file static-analysis.xml
"""
}
publishTestResults testResultsPattern: 'static-analysis.xml'
}
}
stage('セキュリティスキャン') {
steps {
sh """
fluorite-mcp --security-scan \\
--output-format sarif \\
--output-file security-results.sarif
"""
publishSecurityResults(
tool: 'sarif',
pattern: 'security-results.sarif'
)
}
}
stage('Spike検証') {
steps {
sh 'fluorite-mcp --validate-spikes --check-integrity'
}
}
}
}
stage('ビルドとテスト') {
steps {
sh """
fluorite-mcp --enhanced-build \\
--optimize-bundle \\
--validate-types
"""
sh 'npm test'
}
post {
always {
publishTestResults testResultsPattern: 'test-results.xml'
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'coverage',
reportFiles: 'index.html',
reportName: 'カバレッジレポート'
])
}
}
}
stage('デプロイ') {
when {
branch 'main'
}
steps {
sh 'fluorite-mcp --pre-deployment-check'
// デプロイスクリプト
sh './deploy.sh'
}
}
}
post {
always {
sh 'fluorite-mcp --generate-report --output-file fluorite-report.html'
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: '.',
reportFiles: 'fluorite-report.html',
reportName: 'Fluorite MCP レポート'
])
}
failure {
sh 'fluorite-mcp --failure-analysis --output-file failure-analysis.json'
}
}
}
GitLab CI統合
GitLab CI設定
yaml
# .gitlab-ci.yml
stages:
- analysis
- build
- test
- deploy
variables:
NODE_VERSION: "20"
FLUORITE_LOG_LEVEL: "info"
.fluorite_setup: &fluorite_setup
before_script:
- npm install -g fluorite-mcp
- fluorite-mcp --version
quality_analysis:
stage: analysis
image: node:${NODE_VERSION}
<<: *fluorite_setup
script:
- FRAMEWORK=$(fluorite-mcp --detect-framework .)
- |
fluorite-mcp --static-analysis \
--project-path . \
--framework $FRAMEWORK \
--output-format gitlab \
--output-file gl-code-quality-report.json
- |
fluorite-mcp --security-scan \
--output-format gitlab-sast \
--output-file gl-sast-report.json
artifacts:
reports:
codequality: gl-code-quality-report.json
sast: gl-sast-report.json
expire_in: 1 week
spike_validation:
stage: analysis
image: node:${NODE_VERSION}
<<: *fluorite_setup
script:
- fluorite-mcp --validate-spikes --check-integrity
- fluorite-mcp --analyze-spike-usage --project-path .
build_project:
stage: build
image: node:${NODE_VERSION}
<<: *fluorite_setup
script:
- npm ci
- |
fluorite-mcp --enhanced-build \
--optimize-bundle \
--validate-types \
--check-compatibility
- npm run build
artifacts:
paths:
- dist/
- build/
expire_in: 1 hour
test_suite:
stage: test
image: node:${NODE_VERSION}
<<: *fluorite_setup
dependencies:
- build_project
script:
- npm ci
- |
fluorite-mcp --enhance-tests \
--generate-missing-tests \
--validate-coverage
- npm test
coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'
artifacts:
reports:
junit: test-results.xml
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
deploy_production:
stage: deploy
image: node:${NODE_VERSION}
<<: *fluorite_setup
dependencies:
- build_project
only:
- main
script:
- |
fluorite-mcp --pre-deployment-check \
--validate-environment \
--check-dependencies \
--verify-configs
- ./deploy.sh
environment:
name: production
url: https://your-app.com
IDEとエディタ統合
Visual Studio Code統合
VS Code拡張機能設定
json
// .vscode/settings.json
{
"fluorite-mcp.enableRealTimeAnalysis": true,
"fluorite-mcp.autoFixOnSave": true,
"fluorite-mcp.framework": "auto-detect",
"fluorite-mcp.analysisLevel": "comprehensive",
"fluorite-mcp.showSpikeRecommendations": true,
"fluorite-mcp.securityScanOnSave": true,
"fluorite-mcp.performanceHints": true,
"editor.codeActionsOnSave": {
"source.fixAll.fluorite": true,
"source.organizeImports.fluorite": true
},
"fluorite-mcp.customRules": [
{
"name": "react-performance",
"enabled": true,
"severity": "warning"
},
{
"name": "security-patterns",
"enabled": true,
"severity": "error"
}
]
}
タスク設定
json
// .vscode/tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "Fluorite: 完全解析",
"type": "shell",
"command": "fluorite-mcp",
"args": [
"--static-analysis",
"--project-path", "${workspaceFolder}",
"--comprehensive"
],
"group": "build",
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
},
"problemMatcher": "$fluorite-mcp"
},
{
"label": "Fluorite: Spike検証",
"type": "shell",
"command": "fluorite-mcp",
"args": [
"--validate-spikes",
"--check-integrity",
"--project-path", "${workspaceFolder}"
],
"group": "test"
},
{
"label": "Fluorite: パフォーマンス解析",
"type": "shell",
"command": "fluorite-mcp",
"args": [
"--performance-analysis",
"--project-path", "${workspaceFolder}",
"--suggest-optimizations"
],
"group": "build"
}
]
}
JetBrains IDE統合
WebStorm/IntelliJ設定
xml
<!-- .idea/fluorite-mcp.xml -->
<component name="FluoriteMCPConfiguration">
<option name="enableRealTimeAnalysis" value="true" />
<option name="autoDetectFramework" value="true" />
<option name="analysisScope" value="PROJECT" />
<option name="securityScanLevel" value="COMPREHENSIVE" />
<inspectionProfiles>
<profile name="Fluorite Default">
<inspection name="FluoriteSecurityPatterns" enabled="true" level="ERROR" />
<inspection name="FluoritePerformanceHints" enabled="true" level="WARNING" />
<inspection name="FluoriteSpikeRecommendations" enabled="true" level="INFO" />
</profile>
</inspectionProfiles>
<externalTools>
<tool name="Fluorite Analysis">
<command>fluorite-mcp</command>
<parameters>--static-analysis --project-path $ProjectFileDir$</parameters>
<workingDirectory>$ProjectFileDir$</workingDirectory>
</tool>
</externalTools>
</component>
Vim/Neovim統合
Vim設定
vim
" ~/.vimrc または ~/.config/nvim/init.vim
" Fluorite MCP統合
let g:fluorite_mcp_enabled = 1
let g:fluorite_mcp_auto_analysis = 1
let g:fluorite_mcp_framework = 'auto'
" 自動コマンド
augroup FluoriteMCP
autocmd!
" ファイル保存時の解析
autocmd BufWritePost *.ts,*.tsx,*.js,*.jsx,*.vue call FluoriteAnalyze()
" ファイル開く時のSpike推奨
autocmd BufReadPost *.ts,*.tsx,*.js,*.jsx,*.vue call FluoriteSpikeRecommendations()
augroup END
" カスタム関数
function! FluoriteAnalyze()
if g:fluorite_mcp_enabled
silent execute '!fluorite-mcp --quick-analysis --file ' . expand('%:p')
redraw!
endif
endfunction
function! FluoriteSpikeRecommendations()
if g:fluorite_mcp_enabled
let output = system('fluorite-mcp --spike-recommendations --file ' . expand('%:p'))
if v:shell_error == 0 && len(output) > 0
echo "Fluorite推奨: " . output
endif
endif
endfunction
" キーマッピング
nnoremap <leader>fa :call FluoriteAnalyze()<CR>
nnoremap <leader>fs :call FluoriteSpikeRecommendations()<CR>
nnoremap <leader>fv :!fluorite-mcp --validate-spikes --project-path %:p:h<CR>
カスタムアプリケーション統合
Node.js SDK統合
基本統合例
typescript
// fluorite-integration.ts
import { MCPClient } from '@modelcontextprotocol/sdk';
import { ChildProcess } from 'child_process';
export class FluoriteMCPIntegration {
private client: MCPClient;
private isConnected = false;
constructor(private config: FluoriteConfig = {}) {
this.client = new MCPClient({
command: 'fluorite-mcp',
args: this.buildServerArgs()
});
}
async initialize(): Promise<void> {
try {
await this.client.connect();
this.isConnected = true;
console.log('✅ Fluorite MCPに接続しました');
} catch (error) {
console.error('❌ Fluorite MCP接続エラー:', error);
throw error;
}
}
async analyzeProject(projectPath: string, options: AnalysisOptions = {}): Promise<AnalysisResult> {
if (!this.isConnected) {
throw new Error('Fluorite MCPに接続されていません');
}
const framework = options.framework || await this.detectFramework(projectPath);
const analysisResult = await this.client.callTool('static-analysis', {
projectPath,
framework,
predictErrors: options.predictErrors ?? true,
maxIssues: options.maxIssues ?? 100,
includeMetrics: options.includeMetrics ?? true
});
return {
framework,
issues: analysisResult.issues,
metrics: analysisResult.metrics,
recommendations: analysisResult.recommendations,
timestamp: new Date().toISOString()
};
}
async findSpikeTemplates(query: string, context?: string): Promise<SpikeTemplate[]> {
const result = await this.client.callTool('spike-templates-search', {
query,
context: context || 'general',
includeMetadata: true
});
return result.templates.map((template: any) => ({
name: template.name,
description: template.description,
category: template.category,
framework: template.framework,
complexity: template.complexity,
estimatedTimeMinutes: template.estimatedTime,
dependencies: template.dependencies
}));
}
async generateCode(templateName: string, parameters: Record<string, any>): Promise<GeneratedCode> {
const result = await this.client.callTool('spike-generate', {
templateName,
parameters,
includeTests: true,
includeDocs: true
});
return {
files: result.files,
tests: result.tests,
documentation: result.documentation,
installationInstructions: result.installation,
nextSteps: result.nextSteps
};
}
async validateCode(filePaths: string[]): Promise<ValidationResult> {
const result = await this.client.callTool('code-validation', {
files: filePaths,
checkSecurity: true,
checkPerformance: true,
checkAccessibility: true
});
return {
isValid: result.isValid,
errors: result.errors,
warnings: result.warnings,
suggestions: result.suggestions,
securityScore: result.security.score,
performanceScore: result.performance.score,
accessibilityScore: result.accessibility.score
};
}
private async detectFramework(projectPath: string): Promise<string> {
const result = await this.client.callTool('detect-framework', {
projectPath
});
return result.framework;
}
private buildServerArgs(): string[] {
const args = [];
if (this.config.catalogDir) {
args.push('--catalog-dir', this.config.catalogDir);
}
if (this.config.logLevel) {
args.push('--log-level', this.config.logLevel);
}
if (this.config.cacheEnabled) {
args.push('--enable-cache');
}
return args;
}
async disconnect(): Promise<void> {
if (this.isConnected) {
await this.client.disconnect();
this.isConnected = false;
console.log('🔌 Fluorite MCPから切断しました');
}
}
}
// 型定義
interface FluoriteConfig {
catalogDir?: string;
logLevel?: 'debug' | 'info' | 'warn' | 'error';
cacheEnabled?: boolean;
}
interface AnalysisOptions {
framework?: string;
predictErrors?: boolean;
maxIssues?: number;
includeMetrics?: boolean;
}
interface AnalysisResult {
framework: string;
issues: Issue[];
metrics: ProjectMetrics;
recommendations: Recommendation[];
timestamp: string;
}
interface SpikeTemplate {
name: string;
description: string;
category: string;
framework: string;
complexity: 'simple' | 'moderate' | 'complex';
estimatedTimeMinutes: number;
dependencies: string[];
}
interface GeneratedCode {
files: GeneratedFile[];
tests: GeneratedFile[];
documentation: string;
installationInstructions: string[];
nextSteps: string[];
}
interface ValidationResult {
isValid: boolean;
errors: ValidationIssue[];
warnings: ValidationIssue[];
suggestions: string[];
securityScore: number;
performanceScore: number;
accessibilityScore: number;
}
使用例
Webアプリケーション統合
typescript
// app.ts - Express.jsアプリケーション例
import express from 'express';
import { FluoriteMCPIntegration } from './fluorite-integration';
const app = express();
const fluorite = new FluoriteMCPIntegration({
logLevel: 'info',
cacheEnabled: true
});
app.use(express.json());
// プロジェクト解析エンドポイント
app.post('/api/analyze', async (req, res) => {
try {
const { projectPath, options } = req.body;
const result = await fluorite.analyzeProject(projectPath, options);
res.json(result);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Spikeテンプレート検索エンドポイント
app.get('/api/templates/search', async (req, res) => {
try {
const { query, context } = req.query;
const templates = await fluorite.findSpikeTemplates(query as string, context as string);
res.json(templates);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// コード生成エンドポイント
app.post('/api/generate', async (req, res) => {
try {
const { templateName, parameters } = req.body;
const generatedCode = await fluorite.generateCode(templateName, parameters);
res.json(generatedCode);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// コード検証エンドポイント
app.post('/api/validate', async (req, res) => {
try {
const { files } = req.body;
const validationResult = await fluorite.validateCode(files);
res.json(validationResult);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// サーバー起動
app.listen(3000, async () => {
await fluorite.initialize();
console.log('🚀 サーバーがポート3000で起動しました');
});
// グレースフルシャットダウン
process.on('SIGINT', async () => {
await fluorite.disconnect();
process.exit(0);
});
チームコラボレーションパターン
共有設定とテンプレート
チーム設定ファイル
yaml
# .fluorite/team-config.yml
team:
name: "development-team"
standards:
codeQuality:
minCoverage: 80
maxComplexity: 10
enforceLinting: true
security:
scanLevel: "comprehensive"
blockHighRisk: true
requireReview: true
performance:
bundleSizeLimit: "500KB"
loadTimeTarget: "3s"
enableMonitoring: true
frameworks:
primary: "nextjs"
secondary: ["react", "fastapi"]
standards:
nextjs:
typescript: "strict"
linting: "strict"
testing: "jest"
react:
hooks: "recommended"
accessibility: "wcag-aa"
performance: "optimized"
templates:
approved:
- "nextjs-typescript-tailwind"
- "react-component-library"
- "fastapi-jwt-auth"
- "prisma-postgres-crud"
custom:
directory: ".fluorite/team-templates"
autoSync: true
workflows:
preCommit:
- "static-analysis"
- "security-scan"
- "spike-validation"
prValidation:
- "comprehensive-analysis"
- "performance-check"
- "accessibility-audit"
deployment:
- "pre-deployment-check"
- "security-validation"
- "performance-verification"
カスタムSpike テンプレート
yaml
# .fluorite/team-templates/team-react-component.yml
name: "team-react-component"
description: "チーム標準のReactコンポーネントテンプレート"
category: "react-components"
version: "1.2.0"
author: "development-team"
metadata:
complexity: "simple"
estimatedTime: 15
lastUpdated: "2024-01-15"
parameters:
- name: "componentName"
type: "string"
required: true
pattern: "^[A-Z][a-zA-Z0-9]*$"
description: "PascalCaseのコンポーネント名"
- name: "hasProps"
type: "boolean"
default: true
description: "コンポーネントがpropsを受け取るか"
- name: "includeStorybook"
type: "boolean"
default: true
description: "Storybookストーリーを含めるか"
- name: "includeTests"
type: "boolean"
default: true
description: "テストファイルを含めるか"
dependencies:
required:
- "react"
- "@types/react"
optional:
- "@storybook/react"
- "@testing-library/react"
- "@testing-library/jest-dom"
files:
- path: "src/components/{{componentName}}/{{componentName}}.tsx"
template: |
import React from 'react';
import { {{componentName}}Props } from './{{componentName}}.types';
import styles from './{{componentName}}.module.css';
/**
* {{componentName}}コンポーネント
*
* @param props - コンポーネントのプロパティ
* @returns JSX要素
*/
export const {{componentName}}: React.FC<{{componentName}}Props> = ({
{{#if hasProps}}
className,
children,
...props
{{/if}}
}) => {
return (
<div
className={`${styles.{{componentName | lowercase}} ${className || ''}`}
{{#if hasProps}}...props{{/if}}
>
{children || '{{componentName}}コンポーネント'}
</div>
);
};
{{componentName}}.displayName = '{{componentName}}';
- path: "src/components/{{componentName}}/{{componentName}}.types.ts"
template: |
import { ReactNode, HTMLAttributes } from 'react';
export interface {{componentName}}Props extends HTMLAttributes<HTMLDivElement> {
/** 子要素 */
children?: ReactNode;
/** 追加のCSSクラス */
className?: string;
}
- path: "src/components/{{componentName}}/{{componentName}}.module.css"
template: |
.{{componentName | lowercase}} {
/* {{componentName}}のベーススタイル */
display: block;
}
- path: "src/components/{{componentName}}/index.ts"
template: |
export { {{componentName}} } from './{{componentName}}';
export type { {{componentName}}Props } from './{{componentName}}.types';
- path: "src/components/{{componentName}}/{{componentName}}.stories.tsx"
condition: "includeStorybook"
template: |
import type { Meta, StoryObj } from '@storybook/react';
import { {{componentName}} } from './{{componentName}}';
const meta: Meta<typeof {{componentName}}> = {
title: 'Components/{{componentName}}',
component: {{componentName}},
parameters: {
docs: {
description: {
component: '{{componentName}}コンポーネントの説明'
}
}
},
argTypes: {
children: {
control: 'text',
description: '表示するコンテンツ'
},
className: {
control: 'text',
description: '追加のCSSクラス'
}
}
};
export default meta;
type Story = StoryObj<typeof {{componentName}}>;
export const Default: Story = {
args: {
children: 'デフォルトの{{componentName}}'
}
};
export const WithCustomClass: Story = {
args: {
children: 'カスタムクラス付き{{componentName}}',
className: 'custom-class'
}
};
- path: "src/components/{{componentName}}/{{componentName}}.test.tsx"
condition: "includeTests"
template: |
import React from 'react';
import { render, screen } from '@testing-library/react';
import { {{componentName}} } from './{{componentName}}';
describe('{{componentName}}', () => {
it('デフォルトテキストをレンダリングする', () => {
render(<{{componentName}} />);
expect(screen.getByText('{{componentName}}コンポーネント')).toBeInTheDocument();
});
it('childrenプロパティを正しくレンダリングする', () => {
const testText = 'テストテキスト';
render(<{{componentName}}>{testText}</{{componentName}}>);
expect(screen.getByText(testText)).toBeInTheDocument();
});
it('カスタムクラス名を適用する', () => {
const customClass = 'custom-test-class';
render(<{{componentName}} className={customClass} />);
const element = screen.getByText('{{componentName}}コンポーネント');
expect(element).toHaveClass(customClass);
});
it('追加のpropsを正しく渡す', () => {
const testId = 'test-component';
render(<{{componentName}} data-testid={testId} />);
expect(screen.getByTestId(testId)).toBeInTheDocument();
});
});
validation:
rules:
- "typescript-strict"
- "react-best-practices"
- "accessibility-basic"
- "team-naming-conventions"
postGeneration:
- action: "format"
tool: "prettier"
- action: "validate"
tool: "eslint"
- action: "test"
tool: "jest"
condition: "includeTests"
コードレビュープロセス
自動レビューbot
typescript
// .github/scripts/fluorite-review-bot.ts
import { Octokit } from '@octokit/rest';
import { FluoriteMCPIntegration } from '../lib/fluorite-integration';
export class FluoriteReviewBot {
private octokit: Octokit;
private fluorite: FluoriteMCPIntegration;
constructor(githubToken: string) {
this.octokit = new Octokit({ auth: githubToken });
this.fluorite = new FluoriteMCPIntegration();
}
async reviewPullRequest(owner: string, repo: string, pullNumber: number): Promise<void> {
await this.fluorite.initialize();
try {
// PRの変更ファイルを取得
const { data: files } = await this.octokit.pulls.listFiles({
owner,
repo,
pull_number: pullNumber
});
const relevantFiles = files
.filter(file => file.status !== 'removed')
.filter(file => /\.(ts|tsx|js|jsx|vue)$/.test(file.filename))
.map(file => file.filename);
if (relevantFiles.length === 0) {
console.log('レビュー対象のファイルがありません');
return;
}
// Fluorite MCPで解析
const analysisResult = await this.fluorite.analyzeProject('.', {
framework: 'auto',
predictErrors: true,
includeMetrics: true
});
// Spike推奨の確認
const spikeRecommendations = await this.checkSpikeRecommendations(relevantFiles);
// レビューコメントの生成
const reviewComments = await this.generateReviewComments(
relevantFiles,
analysisResult,
spikeRecommendations
);
// PRにレビューを投稿
if (reviewComments.length > 0) {
await this.octokit.pulls.createReview({
owner,
repo,
pull_number: pullNumber,
event: 'COMMENT',
body: this.generateReviewSummary(analysisResult, spikeRecommendations),
comments: reviewComments
});
}
// ステータスチェックを設定
await this.updateStatusCheck(owner, repo, pullNumber, analysisResult);
} finally {
await this.fluorite.disconnect();
}
}
private async checkSpikeRecommendations(files: string[]): Promise<SpikeRecommendation[]> {
const recommendations = [];
for (const file of files) {
const result = await this.fluorite.findSpikeTemplates(
`similar patterns to ${file}`,
'code-review'
);
if (result.length > 0) {
recommendations.push({
file,
templates: result.slice(0, 3), // 上位3つの推奨
reason: 'Similar patterns found in Spike templates'
});
}
}
return recommendations;
}
private async generateReviewComments(
files: string[],
analysis: any,
spikes: SpikeRecommendation[]
): Promise<ReviewComment[]> {
const comments: ReviewComment[] = [];
// 重要な問題に対するコメント
for (const issue of analysis.issues.filter(i => i.severity === 'error')) {
comments.push({
path: issue.file,
line: issue.line,
body: `🚨 **${issue.rule}**: ${issue.message}\n\n` +
`**修正方法**: ${issue.suggestion || '詳細については開発チームにご相談ください'}`
});
}
// パフォーマンスの警告
for (const issue of analysis.issues.filter(i => i.category === 'performance')) {
comments.push({
path: issue.file,
line: issue.line,
body: `⚡ **パフォーマンス**: ${issue.message}\n\n` +
`**影響**: ${issue.impact}\n` +
`**推奨**: ${issue.suggestion}`
});
}
// Spike推奨
for (const spike of spikes) {
const firstTemplate = spike.templates[0];
comments.push({
path: spike.file,
line: 1,
body: `💡 **Spikeテンプレート推奨**: \n\n` +
`似たパターンがSpikeテンプレート「**${firstTemplate.name}**」にあります。\n` +
`このテンプレートを使用することで、${firstTemplate.estimatedTimeMinutes}分程度の時間短縮が期待できます。\n\n` +
`**説明**: ${firstTemplate.description}\n` +
`**カテゴリ**: ${firstTemplate.category}`
});
}
return comments;
}
private generateReviewSummary(analysis: any, spikes: SpikeRecommendation[]): string {
const errorCount = analysis.issues.filter(i => i.severity === 'error').length;
const warningCount = analysis.issues.filter(i => i.severity === 'warning').length;
const spikeCount = spikes.length;
let summary = '## 🤖 Fluorite MCP自動レビュー\n\n';
if (errorCount > 0) {
summary += `❌ **${errorCount}個のエラー**が見つかりました\n`;
}
if (warningCount > 0) {
summary += `⚠️ **${warningCount}個の警告**が見つかりました\n`;
}
if (spikeCount > 0) {
summary += `💡 **${spikeCount}個のSpikeテンプレート推奨**があります\n`;
}
if (errorCount === 0 && warningCount === 0) {
summary += '✅ **問題は見つかりませんでした!**\n';
}
// メトリクス情報
if (analysis.metrics) {
summary += '\n### 📊 コード品質メトリクス\n\n';
summary += `- **複雑度**: ${analysis.metrics.averageComplexity}/10\n`;
summary += `- **テストカバレッジ**: ${analysis.metrics.testCoverage}%\n`;
summary += `- **保守性インデックス**: ${analysis.metrics.maintainabilityIndex}/100\n`;
}
summary += '\n---\n*このレビューはFluorite MCPによって自動生成されました*';
return summary;
}
private async updateStatusCheck(
owner: string,
repo: string,
pullNumber: number,
analysis: any
): Promise<void> {
const { data: pr } = await this.octokit.pulls.get({
owner,
repo,
pull_number: pullNumber
});
const errorCount = analysis.issues.filter(i => i.severity === 'error').length;
const state = errorCount > 0 ? 'failure' : 'success';
const description = errorCount > 0
? `${errorCount}個のエラーが見つかりました`
: 'コード品質チェックが通過しました';
await this.octokit.repos.createCommitStatus({
owner,
repo,
sha: pr.head.sha,
state,
context: 'fluorite-mcp/code-quality',
description,
target_url: `https://github.com/${owner}/${repo}/pull/${pullNumber}/files`
});
}
}
interface SpikeRecommendation {
file: string;
templates: any[];
reason: string;
}
interface ReviewComment {
path: string;
line: number;
body: string;
}
エンタープライズデプロイ
大規模デプロイアーキテクチャ
Kubernetes デプロイ
yaml
# k8s/fluorite-mcp-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: fluorite-mcp
namespace: development-tools
labels:
app: fluorite-mcp
version: v0.20.1
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
selector:
matchLabels:
app: fluorite-mcp
template:
metadata:
labels:
app: fluorite-mcp
spec:
containers:
- name: fluorite-mcp
image: fluorite-mcp:0.20.0
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: "production"
- name: FLUORITE_LOG_LEVEL
value: "info"
- name: FLUORITE_CATALOG_DIR
value: "/data/catalog"
- name: NODE_OPTIONS
value: "--max-old-space-size=2048"
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "2Gi"
cpu: "1000m"
volumeMounts:
- name: catalog-storage
mountPath: /data/catalog
- name: cache-storage
mountPath: /data/cache
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 30
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
volumes:
- name: catalog-storage
persistentVolumeClaim:
claimName: fluorite-catalog-pvc
- name: cache-storage
emptyDir:
sizeLimit: "1Gi"
---
apiVersion: v1
kind: Service
metadata:
name: fluorite-mcp-service
namespace: development-tools
spec:
selector:
app: fluorite-mcp
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: ClusterIP
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: fluorite-catalog-pvc
namespace: development-tools
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
storageClassName: fast-ssd
ロードバランサー設定
yaml
# k8s/fluorite-mcp-ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: fluorite-mcp-ingress
namespace: development-tools
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: "1m"
spec:
tls:
- hosts:
- fluorite-mcp.company.com
secretName: fluorite-mcp-tls
rules:
- host: fluorite-mcp.company.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: fluorite-mcp-service
port:
number: 80
監視とログ
Prometheus監視設定
yaml
# monitoring/prometheus-config.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'fluorite-mcp'
static_configs:
- targets: ['fluorite-mcp-service:80']
metrics_path: '/metrics'
scrape_interval: 30s
scrape_timeout: 10s
rule_files:
- "fluorite-mcp-alerts.yml"
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
アラートルール
yaml
# monitoring/fluorite-mcp-alerts.yml
groups:
- name: fluorite-mcp
rules:
- alert: FluoriteMCPHighMemoryUsage
expr: fluorite_mcp_memory_usage_mb > 1500
for: 5m
labels:
severity: warning
annotations:
summary: "Fluorite MCP high memory usage"
description: "Memory usage is {{ $value }}MB for 5 minutes"
- alert: FluoriteMCPHighErrorRate
expr: rate(fluorite_mcp_errors_total[5m]) > 0.01
for: 2m
labels:
severity: critical
annotations:
summary: "Fluorite MCP high error rate"
description: "Error rate is {{ $value }} errors/sec"
- alert: FluoriteMCPSlowResponse
expr: fluorite_mcp_response_time_p95 > 200
for: 3m
labels:
severity: warning
annotations:
summary: "Fluorite MCP slow response times"
description: "95th percentile response time is {{ $value }}ms"
Grafana ダッシュボード
json
{
"dashboard": {
"title": "Fluorite MCP Monitoring",
"panels": [
{
"title": "Response Time",
"type": "graph",
"targets": [
{
"expr": "fluorite_mcp_response_time_p50",
"legendFormat": "P50"
},
{
"expr": "fluorite_mcp_response_time_p95",
"legendFormat": "P95"
},
{
"expr": "fluorite_mcp_response_time_p99",
"legendFormat": "P99"
}
]
},
{
"title": "Memory Usage",
"type": "graph",
"targets": [
{
"expr": "fluorite_mcp_memory_usage_mb",
"legendFormat": "Memory (MB)"
}
]
},
{
"title": "Operation Count",
"type": "graph",
"targets": [
{
"expr": "rate(fluorite_mcp_operations_total[5m])",
"legendFormat": "Operations/sec"
}
]
},
{
"title": "Error Rate",
"type": "graph",
"targets": [
{
"expr": "rate(fluorite_mcp_errors_total[5m])",
"legendFormat": "Errors/sec"
}
]
}
]
}
}
監視とオブザーバビリティ
ログ集約
ELKスタック統合
yaml
# logging/filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/fluorite-mcp/*.log
fields:
service: fluorite-mcp
environment: production
fields_under_root: true
multiline.pattern: '^\d{4}-\d{2}-\d{2}'
multiline.negate: true
multiline.match: after
output.elasticsearch:
hosts: ["elasticsearch:9200"]
index: "fluorite-mcp-%{+yyyy.MM.dd}"
logging.level: info
Logstash設定
ruby
# logging/logstash.conf
input {
beats {
port => 5044
}
}
filter {
if [service] == "fluorite-mcp" {
grok {
match => {
"message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} \[%{DATA:component}\] %{GREEDYDATA:msg}"
}
}
date {
match => [ "timestamp", "ISO8601" ]
}
if [level] == "ERROR" {
mutate {
add_tag => [ "error" ]
}
}
if [msg] =~ /performance/ {
mutate {
add_tag => [ "performance" ]
}
}
}
}
output {
elasticsearch {
hosts => ["elasticsearch:9200"]
index => "fluorite-mcp-%{+YYYY.MM.dd}"
}
}
メトリクス収集
カスタムメトリクス
typescript
// monitoring/metrics.ts
import { register, Counter, Histogram, Gauge } from 'prom-client';
export class FluoriteMetrics {
private readonly operationCounter = new Counter({
name: 'fluorite_mcp_operations_total',
help: 'Total number of operations',
labelNames: ['operation_type', 'status']
});
private readonly responseTimeHistogram = new Histogram({
name: 'fluorite_mcp_response_time_seconds',
help: 'Response time in seconds',
labelNames: ['operation_type'],
buckets: [0.01, 0.05, 0.1, 0.2, 0.5, 1, 2, 5]
});
private readonly memoryGauge = new Gauge({
name: 'fluorite_mcp_memory_usage_mb',
help: 'Memory usage in MB'
});
private readonly activeConnectionsGauge = new Gauge({
name: 'fluorite_mcp_active_connections',
help: 'Number of active connections'
});
constructor() {
// メモリ使用量の定期更新
setInterval(() => {
const memUsage = process.memoryUsage();
this.memoryGauge.set(memUsage.heapUsed / 1024 / 1024);
}, 5000);
}
recordOperation(type: string, status: 'success' | 'error'): void {
this.operationCounter.inc({ operation_type: type, status });
}
recordResponseTime(type: string, durationMs: number): void {
this.responseTimeHistogram
.labels({ operation_type: type })
.observe(durationMs / 1000);
}
setActiveConnections(count: number): void {
this.activeConnectionsGauge.set(count);
}
getMetrics(): string {
return register.metrics();
}
}
// 使用例
const metrics = new FluoriteMetrics();
// 操作の測定
export function withMetrics<T>(
operationType: string,
operation: () => Promise<T>
): Promise<T> {
const start = Date.now();
return operation()
.then((result) => {
const duration = Date.now() - start;
metrics.recordOperation(operationType, 'success');
metrics.recordResponseTime(operationType, duration);
return result;
})
.catch((error) => {
const duration = Date.now() - start;
metrics.recordOperation(operationType, 'error');
metrics.recordResponseTime(operationType, duration);
throw error;
});
}
分散トレーシング
Jaeger統合
typescript
// tracing/tracer.ts
import { NodeSDK } from '@opentelemetry/sdk-node';
import { JaegerExporter } from '@opentelemetry/exporter-jaeger';
import { Resource } from '@opentelemetry/resources';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
const jaegerExporter = new JaegerExporter({
endpoint: 'http://jaeger:14268/api/traces',
});
const sdk = new NodeSDK({
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'fluorite-mcp',
[SemanticResourceAttributes.SERVICE_VERSION]: '0.20.0',
}),
traceExporter: jaegerExporter,
});
export function initializeTracing(): void {
sdk.start();
console.log('🔍 分散トレーシングが初期化されました');
}
export function shutdownTracing(): Promise<void> {
return sdk.shutdown();
}
ヘルスチェックエンドポイント
包括的ヘルスチェック
typescript
// health/health-check.ts
import { performance } from 'perf_hooks';
interface HealthCheckResult {
status: 'healthy' | 'unhealthy' | 'degraded';
timestamp: string;
uptime: number;
checks: {
[key: string]: {
status: 'pass' | 'fail' | 'warn';
duration: number;
details?: any;
};
};
}
export class HealthChecker {
private startTime = Date.now();
async performHealthCheck(): Promise<HealthCheckResult> {
const checks: any = {};
let overallStatus: 'healthy' | 'unhealthy' | 'degraded' = 'healthy';
// MCPサーバー接続チェック
checks.mcpConnection = await this.checkMCPConnection();
// ファイルシステムアクセスチェック
checks.filesystem = await this.checkFilesystem();
// メモリ使用量チェック
checks.memory = await this.checkMemory();
// 依存関係チェック
checks.dependencies = await this.checkDependencies();
// パフォーマンスチェック
checks.performance = await this.checkPerformance();
// 全体的なステータス決定
const failedChecks = Object.values(checks).filter(c => c.status === 'fail');
const warnChecks = Object.values(checks).filter(c => c.status === 'warn');
if (failedChecks.length > 0) {
overallStatus = 'unhealthy';
} else if (warnChecks.length > 0) {
overallStatus = 'degraded';
}
return {
status: overallStatus,
timestamp: new Date().toISOString(),
uptime: Date.now() - this.startTime,
checks
};
}
private async checkMCPConnection(): Promise<any> {
const start = performance.now();
try {
// MCP接続の簡単なテスト
await this.testMCPConnection();
return {
status: 'pass',
duration: performance.now() - start,
details: { message: 'MCP connection is working' }
};
} catch (error) {
return {
status: 'fail',
duration: performance.now() - start,
details: { error: error.message }
};
}
}
private async checkFilesystem(): Promise<any> {
const start = performance.now();
try {
const fs = require('fs').promises;
await fs.access('./catalog', fs.constants.R_OK | fs.constants.W_OK);
return {
status: 'pass',
duration: performance.now() - start,
details: { message: 'Filesystem access is working' }
};
} catch (error) {
return {
status: 'fail',
duration: performance.now() - start,
details: { error: error.message }
};
}
}
private async checkMemory(): Promise<any> {
const start = performance.now();
const memUsage = process.memoryUsage();
const heapUsedMB = memUsage.heapUsed / 1024 / 1024;
let status: 'pass' | 'warn' | 'fail' = 'pass';
if (heapUsedMB > 1500) {
status = 'fail';
} else if (heapUsedMB > 1000) {
status = 'warn';
}
return {
status,
duration: performance.now() - start,
details: {
heapUsedMB: Math.round(heapUsedMB),
heapTotalMB: Math.round(memUsage.heapTotal / 1024 / 1024),
rssMB: Math.round(memUsage.rss / 1024 / 1024)
}
};
}
private async checkDependencies(): Promise<any> {
const start = performance.now();
try {
// 重要な依存関係の確認
require('fs');
require('path');
require('yaml');
return {
status: 'pass',
duration: performance.now() - start,
details: { message: 'All dependencies are available' }
};
} catch (error) {
return {
status: 'fail',
duration: performance.now() - start,
details: { error: error.message }
};
}
}
private async checkPerformance(): Promise<any> {
const start = performance.now();
try {
// 簡単なパフォーマンステスト
const testStart = performance.now();
for (let i = 0; i < 1000; i++) {
Math.random();
}
const testDuration = performance.now() - testStart;
let status: 'pass' | 'warn' | 'fail' = 'pass';
if (testDuration > 100) {
status = 'fail';
} else if (testDuration > 50) {
status = 'warn';
}
return {
status,
duration: performance.now() - start,
details: {
testDurationMs: Math.round(testDuration),
message: `Performance test completed in ${Math.round(testDuration)}ms`
}
};
} catch (error) {
return {
status: 'fail',
duration: performance.now() - start,
details: { error: error.message }
};
}
}
private async testMCPConnection(): Promise<void> {
// 実際のMCP接続テストロジック
return new Promise((resolve) => {
setTimeout(resolve, 10); // シミュレーション
});
}
}
このガイドでは、Fluorite MCPの開発ワークフロー、CI/CD、IDE、カスタムアプリケーション、チームコラボレーション、エンタープライズデプロイ、監視の各分野での統合方法を詳しく説明しました。各セクションは実用的な例とベストプラクティスを提供し、様々な環境でFluorite MCPを効果的に活用するための包括的な指針となっています。
詳細情報については以下を参照:
- 使用例・ケーススタディ - 実世界の統合例
- パフォーマンスガイド - パフォーマンス最適化
- トラブルシューティング - 一般的な問題と解決策
- 開発者ガイド - 開発とカスタマイゼーション