Developer Documentation
Complete guide for developers working with, extending, or contributing to Fluorite MCP.
📖 Table of Contents
- Architecture Overview
- Development Setup
- Contributing Guide
- Plugin Development
- Creating Custom Specifications
- Extending the MCP Server
- Testing and Quality Assurance
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
- Push to your fork
- Create pull request with clear description
- Include examples and test cases
- 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 componentsstate-management
- State management solutionsdevelopment-methodology
- Development practicestesting
- Testing frameworksauthentication
- Authentication librariesdatabase
- Database and ORM toolsframework
- Web frameworksinfrastructure
- DevOps and infrastructurelanguage-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 featuresfix:
- Bug fixesdocs:
- Documentation updatesrefactor:
- Code refactoringtest:
- Test updateschore:
- 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