Skip to content

Developer Documentation ​

Complete guide for developers working with, extending, or contributing to Fluorite MCP.

📖 Table of Contents ​

Architecture Overview ​

System Architecture ​

mermaid
graph TB
    CLI[Claude Code CLI] --> MCP[MCP Protocol]
    MCP --> Server[Fluorite MCP Server]
    
    Server --> Catalog[Specification Catalog]
    Server --> Analysis[Static Analysis Engine]
    Server --> Spikes[Spike Template System]
    Server --> Cache[Caching Layer]
    
    Catalog --> YAML[YAML Specs]
    Catalog --> JSON[JSON Specs] 
    
    Analysis --> NextJS[Next.js Analyzer]
    Analysis --> React[React Analyzer]
    Analysis --> Vue[Vue Analyzer]
    Analysis --> Generic[Generic Analyzer]
    
    Spikes --> Templates[Template Files]
    Spikes --> Renderer[Template Renderer]

Core Components ​

1. MCP Server (src/server.ts) ​

Main entry point implementing the Model Context Protocol:

typescript
interface MCPServer {
  // Resource handling
  listResources(): Promise<Resource[]>;
  getResource(uri: string): Promise<ResourceContent>;
  
  // Tool handling  
  listTools(): Promise<Tool[]>;
  callTool(name: string, args: any): Promise<ToolResult>;
  
  // Lifecycle management
  initialize(): Promise<void>;
  shutdown(): Promise<void>;
}

2. Specification Catalog (src/core/catalog.ts) ​

Manages library specifications and metadata:

typescript
interface SpecificationCatalog {
  loadSpecs(): Promise<PackageSpec[]>;
  getSpec(id: string): Promise<PackageSpec>;
  upsertSpec(pkg: string, content: string): Promise<void>;
  searchSpecs(filter: string): Promise<PackageSpec[]>;
}

3. Static Analysis Engine (src/core/static-analyzer.ts) ​

Framework-specific code analysis:

typescript
interface StaticAnalyzer {
  analyzeProject(path: string, options: AnalysisOptions): Promise<AnalysisResult>;
  validateCode(code: string, language: string): Promise<ValidationResult>;
  predictErrors(code: string): Promise<ErrorPrediction[]>;
}

4. Spike Template System (src/core/spike-catalog.ts) ​

Manages rapid prototyping templates:

typescript
interface SpikeSystem {
  discoverSpikes(query?: string): Promise<SpikeSpec[]>;
  previewSpike(id: string, params: Record<string, string>): Promise<SpikePreview>;
  applySpike(id: string, params: Record<string, string>): Promise<SpikeApplication>;
}

Data Models ​

Package Specification ​

typescript
interface PackageSpec {
  readonly name: string;
  readonly content: string;
  readonly format: "yaml" | "yml" | "json";
  readonly filePath: string;
}

Spike Template ​

typescript
interface SpikeSpec {
  id: string;
  name?: string;
  version?: string;
  stack?: string[];
  tags?: string[];
  description?: string;
  params?: SpikeParam[];
  files: SpikeFileTemplate[];
  patches?: SpikePatch[];
}

Analysis Result ​

typescript
interface AnalysisResult {
  summary: {
    errors: number;
    warnings: number;
    info: number;
  };
  issues: AnalysisIssue[];
  predictions?: ErrorPrediction[];
  metrics?: PerformanceMetrics;
}

Development Setup ​

Prerequisites ​

  • Node.js: 18.0+ (20.0+ recommended)
  • npm: 8.0+
  • Git: Latest version
  • TypeScript: 5.0+ (installed via npm)

Initial Setup ​

bash
# Clone the repository
git clone https://github.com/kotsutsumi/fluorite-mcp.git
cd fluorite-mcp

# Install dependencies
npm install

# Build the project
npm run build

# Run tests
npm test

# Start development server
npm run dev

Development Workflow ​

1. Environment Configuration ​

bash
# Set development environment
export NODE_ENV=development
export FLUORITE_LOG_LEVEL=debug
export FLUORITE_CATALOG_DIR="./src/catalog"

2. Code Structure ​

src/
├── server.ts              # Main MCP server
├── types.ts               # Type definitions
├── utils.ts               # Utility functions
├── core/                  # Core functionality
│   ├── catalog.ts         # Specification catalog
│   ├── handlers.ts        # MCP tool handlers
│   ├── logger.ts          # Logging system
│   ├── static-analyzer.ts # Code analysis
│   └── spike-catalog.ts   # Spike templates
├── test/                  # Test files
└── spikes/                # Spike template files

3. Adding New Features ​

Adding a New Tool:

typescript
// src/core/handlers.ts
export async function handleNewTool(input: NewToolInput): Promise<ToolCallResult> {
  try {
    // Implement tool logic
    const result = await performNewToolOperation(input);
    
    return {
      content: [{ type: 'text', text: result.message }],
      metadata: result.data
    };
  } catch (error) {
    log.error('new-tool failed', error as Error);
    return {
      content: [{ type: 'text', text: `❌ new-tool failed: ${error.message}` }],
      isError: true
    };
  }
}

// Register in server.ts
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  switch (request.params.name) {
    case 'new-tool':
      return await handleNewTool(request.params.arguments);
    // ... other tools
  }
});

Adding a New Analyzer:

typescript
// src/core/my-framework-analyzer.ts
export class MyFrameworkAnalyzer implements FrameworkAnalyzer {
  analyze(files: FileInfo[]): AnalysisResult {
    const issues: AnalysisIssue[] = [];
    
    for (const file of files) {
      // Analyze file content
      const fileIssues = this.analyzeFile(file);
      issues.push(...fileIssues);
    }
    
    return {
      summary: this.createSummary(issues),
      issues
    };
  }
  
  private analyzeFile(file: FileInfo): AnalysisIssue[] {
    // Implementation specific to your framework
    return [];
  }
}

Contributing Guide ​

Contribution Types ​

1. Library Specifications ​

Add support for new libraries by creating YAML specifications:

yaml
# src/catalog/my-library.yaml
name: My Library
version: 2.1.0
description: A comprehensive UI component library
category: ui-components
homepage: # ライブラリのホームページURL
repository: # リポジトリURL

features:
  - Accessible components
  - TypeScript support
  - Theme customization
  - Dark mode

configuration: |
  npm install my-library
  
  // Basic usage
  import { Button } from 'my-library';
  
  function App() {
    return <Button variant="primary">Click me</Button>;
  }

best_practices:
  - Use semantic HTML elements
  - Follow ARIA guidelines
  - Test with screen readers
  - Implement keyboard navigation

2. Static Analysis Rules ​

Add new analysis rules:

typescript
// src/core/rules/my-rule.ts
export const myFrameworkRule: AnalysisRule = {
  id: 'my-framework-component-naming',
  severity: 'warning',
  message: 'Component names should use PascalCase',
  
  check(file: FileInfo): AnalysisIssue[] {
    const issues: AnalysisIssue[] = [];
    
    // Rule implementation
    const componentRegex = /function\s+([a-z][^(]*)/g;
    let match;
    
    while ((match = componentRegex.exec(file.content)) !== null) {
      issues.push({
        severity: 'warning',
        message: this.message,
        file: file.path,
        line: this.getLineNumber(file.content, match.index),
        fix: `Rename to ${toPascalCase(match[1])}`
      });
    }
    
    return issues;
  }
};

3. Spike Templates ​

Create new spike templates:

json
{
  "id": "my-framework-minimal",
  "name": "My Framework Minimal Setup",
  "version": "1.0.0",
  "stack": ["javascript", "my-framework"],
  "tags": ["web", "frontend"],
  "description": "Minimal setup for My Framework",
  "params": [
    { "name": "project_name", "required": false, "default": "my-app" },
    { "name": "version", "required": false, "default": "latest" }
  ],
  "files": [
    {
      "path": "{{project_name}}/package.json",
      "template": "{\n  \"name\": \"{{project_name}}\",\n  \"dependencies\": {\n    \"my-framework\": \"{{version}}\"\n  }\n}"
    }
  ]
}

Pull Request Process ​

1. Preparation ​

bash
# Create feature branch
git checkout -b feature/my-new-feature

# Make changes and test
npm test
npm run lint
npm run build

# Commit with conventional commits
git commit -m "feat: add support for My Framework"

2. Testing Requirements ​

bash
# Run all tests
npm test

# Run specific test suites
npm run test:unit
npm run test:e2e
npm run test:coverage

# Verify build
npm run build:check

3. Documentation Updates ​

  • Update relevant documentation files
  • Add examples for new features
  • Update changelog if applicable

4. PR Submission ​

  1. Push to your fork
  2. Create pull request with clear description
  3. Include examples and test cases
  4. Respond to review feedback

Code Quality Standards ​

TypeScript Guidelines ​

typescript
// Use explicit types
interface ComponentProps {
  title: string;
  optional?: boolean;
}

// Use readonly for immutable data
interface Config {
  readonly apiUrl: string;
  readonly timeout: number;
}

// Use proper error handling
async function processData(data: unknown): Promise<ProcessedData> {
  try {
    const validated = validateData(data);
    return await transform(validated);
  } catch (error) {
    logger.error('Data processing failed', { error, data });
    throw new ProcessingError('Invalid data format');
  }
}

Testing Standards ​

typescript
// Unit tests
describe('SpecificationCatalog', () => {
  let catalog: SpecificationCatalog;
  
  beforeEach(() => {
    catalog = new SpecificationCatalog('/test/fixtures');
  });
  
  it('should load specifications correctly', async () => {
    const specs = await catalog.loadSpecs();
    expect(specs).toHaveLength(3);
    expect(specs[0].name).toBe('test-library');
  });
  
  it('should handle missing specifications', async () => {
    await expect(catalog.getSpec('nonexistent'))
      .rejects.toThrow('Specification not found');
  });
});

// Integration tests  
describe('MCP Server Integration', () => {
  let server: MCPServer;
  
  beforeAll(async () => {
    server = new MCPServer();
    await server.initialize();
  });
  
  afterAll(async () => {
    await server.shutdown();
  });
  
  it('should handle tool calls correctly', async () => {
    const result = await server.callTool('list-specs', {});
    expect(result.content[0].text).toContain('specifications');
  });
});

Plugin Development ​

Creating Custom Plugins ​

Extend Fluorite MCP with custom functionality:

typescript
// plugins/my-plugin.ts
import { FluoriteMCPPlugin } from 'fluorite-mcp';

export class MyPlugin extends FluoriteMCPPlugin {
  name = 'my-plugin';
  version = '1.0.0';
  
  async initialize(): Promise<void> {
    // Plugin initialization
    this.registerTool('my-custom-tool', this.handleCustomTool);
    this.registerAnalyzer('my-framework', new MyFrameworkAnalyzer());
  }
  
  private async handleCustomTool(args: any): Promise<ToolResult> {
    // Custom tool implementation
    return {
      content: [{ type: 'text', text: 'Custom tool executed' }]
    };
  }
}

// Register plugin
import { MyPlugin } from './plugins/my-plugin';

const server = new FluoriteMCPServer();
server.registerPlugin(new MyPlugin());

Plugin API ​

Tool Registration ​

typescript
interface Plugin {
  registerTool(name: string, handler: ToolHandler): void;
  registerResource(uri: string, provider: ResourceProvider): void;
  registerAnalyzer(framework: string, analyzer: FrameworkAnalyzer): void;
}

Lifecycle Hooks ​

typescript
interface PluginLifecycle {
  initialize(): Promise<void>;
  beforeRequest(request: MCPRequest): Promise<MCPRequest>;
  afterResponse(response: MCPResponse): Promise<MCPResponse>;
  shutdown(): Promise<void>;
}

Creating Custom Specifications ​

YAML Specification Format ​

yaml
# Required fields
name: Library Name
version: 1.2.3
description: Brief description of the library
category: ui-components  # See categories below

# Optional fields
subcategory: data-tables
tags:
  - typescript
  - react
  - accessibility
homepage: # ライブラリのホームページURL
repository: # リポジトリURL
language: TypeScript

# Simple library format
features:
  - Feature 1
  - Feature 2

configuration: |
  # Installation
  npm install library-name
  
  # Basic usage
  import { Component } from 'library-name';

best_practices:
  - Use TypeScript for type safety
  - Follow accessibility guidelines

# Ecosystem format (for comprehensive specs)
tools:
  core_library:
    name: Core Library
    description: Main library functionality
    features:
      - Core feature 1
      - Core feature 2
    configuration: |
      import { CoreComponent } from 'library';
  
  extension_library:
    name: Extension Package
    description: Additional functionality
    features:
      - Extended feature 1

workflows:
  basic_setup:
    description: Basic project setup
    steps:
      - Install dependencies
      - Configure project
      - Create first component

templates:
  basic_component:
    description: Basic component template
    code: |
      import React from 'react';
      import { BaseComponent } from 'library';
      
      export function MyComponent() {
        return <BaseComponent>Hello World</BaseComponent>;
      }

Categories and Tags ​

Standard Categories:

  • ui-components - UI libraries and components
  • state-management - State management solutions
  • development-methodology - Development practices
  • testing - Testing frameworks
  • authentication - Authentication libraries
  • database - Database and ORM tools
  • framework - Web frameworks
  • infrastructure - DevOps and infrastructure
  • language-ecosystem - Programming language ecosystems

Common Tags:

  • Languages: typescript, javascript, python, rust
  • Frameworks: react, vue, nextjs, fastapi
  • Features: accessibility, typescript, testing, mobile

Validation ​

Specifications are validated against this schema:

typescript
interface SpecificationSchema {
  name: string;
  version: string;
  description: string;
  category: string;
  subcategory?: string;
  tags?: string[];
  homepage?: string;
  repository?: string;
  language?: string;
  
  // Simple format
  features?: string[];
  configuration?: string;
  best_practices?: string[];
  
  // Ecosystem format
  tools?: Record<string, LibraryTool>;
  workflows?: Record<string, Workflow>;
  templates?: Record<string, Template>;
}

Extending the MCP Server ​

Custom Resource Providers ​

typescript
class CustomResourceProvider implements ResourceProvider {
  async listResources(): Promise<Resource[]> {
    return [
      {
        uri: 'custom://my-resource',
        name: 'My Custom Resource',
        mimeType: 'application/json'
      }
    ];
  }
  
  async getResource(uri: string): Promise<ResourceContent> {
    if (uri === 'custom://my-resource') {
      return {
        uri,
        mimeType: 'application/json',
        content: JSON.stringify({ custom: 'data' })
      };
    }
    throw new Error('Resource not found');
  }
}

// Register provider
server.registerResourceProvider(new CustomResourceProvider());

Custom Analysis Rules ​

typescript
interface AnalysisRule {
  id: string;
  severity: 'error' | 'warning' | 'info';
  message: string;
  framework?: string;
  check(file: FileInfo): AnalysisIssue[];
}

const customRule: AnalysisRule = {
  id: 'custom-naming-convention',
  severity: 'warning',
  message: 'Use consistent naming convention',
  
  check(file: FileInfo): AnalysisIssue[] {
    // Implementation
    return [];
  }
};

// Register rule
analyzer.registerRule(customRule);

Testing and Quality Assurance ​

Test Structure ​

test/
├── unit/                   # Unit tests
│   ├── catalog.test.ts
│   ├── handlers.test.ts
│   └── analyzers/
├── integration/            # Integration tests
│   ├── mcp-server.test.ts
│   └── end-to-end.test.ts
├── fixtures/              # Test data
│   ├── specs/
│   └── projects/
└── utils/                 # Test utilities
    └── test-helpers.ts

Writing Tests ​

Unit Tests ​

typescript
import { describe, it, expect, beforeEach } from 'vitest';
import { SpecificationCatalog } from '../src/core/catalog';

describe('SpecificationCatalog', () => {
  let catalog: SpecificationCatalog;
  
  beforeEach(() => {
    catalog = new SpecificationCatalog('./test/fixtures/specs');
  });
  
  describe('loadSpecs', () => {
    it('should load all valid specifications', async () => {
      const specs = await catalog.loadSpecs();
      expect(specs).toHaveLength(5);
    });
    
    it('should skip invalid specifications', async () => {
      // Test error handling
    });
  });
});

Integration Tests ​

typescript
import { MCPServer } from '../src/server';

describe('MCP Server Integration', () => {
  let server: MCPServer;
  
  beforeAll(async () => {
    server = new MCPServer();
    await server.initialize();
  });
  
  it('should handle list-specs tool', async () => {
    const result = await server.callTool('list-specs', {});
    expect(result.content[0].text).toMatch(/Found \d+ specifications/);
  });
});

Performance Testing ​

typescript
describe('Performance Tests', () => {
  it('should load large catalogs quickly', async () => {
    const startTime = performance.now();
    await catalog.loadSpecs();
    const duration = performance.now() - startTime;
    
    expect(duration).toBeLessThan(100); // 100ms max
  });
  
  it('should handle concurrent requests', async () => {
    const requests = Array(10).fill(null).map(() => 
      server.callTool('list-specs', {})
    );
    
    const results = await Promise.all(requests);
    expect(results).toHaveLength(10);
  });
});

Quality Checks ​

bash
# Type checking
npm run lint

# Test coverage
npm run test:coverage

# Build verification
npm run build:check

# End-to-end tests
npm run test:e2e

Release Process ​

Version Management ​

bash
# Update version
npm version patch  # or minor, major

# Build and test
npm run build
npm test

# Publish
npm publish

Changelog ​

Follow conventional commit format:

  • feat: - New features
  • fix: - Bug fixes
  • docs: - Documentation updates
  • refactor: - Code refactoring
  • test: - Test updates
  • chore: - Maintenance

Resources ​

Development Tools ​

  • TypeScript: Type checking and compilation
  • Vitest: Testing framework
  • ESLint: Code linting
  • Prettier: Code formatting
  • tsx: Development server

Documentation ​

  • Internal Docs: Architecture diagrams and technical specs
  • API Docs: Complete API reference
  • Examples: Sample implementations and use cases

Community ​

  • Issues: Bug reports and feature requests
  • Pull Requests: Code contributions

Last updated: 2025-08-15

Released under the MIT License.