Services Layer
Overview
The services layer provides clean abstraction for external integrations. It separates core logic from external dependencies, making the system highly modular and maintainable.
Service Directory Structure
src/services/
├── api/ - Anthropic SDK, file uploads, bootstrap
├── mcp/ - Model Context Protocol client
├── oauth/ - Authentication flows
├── lsp/ - Language Server Protocol manager
├── analytics/ - GrowthBook feature flags
├── policyLimits/ - Policy limit management
├── remoteManagedSettings/ - Remote settings sync
├── tips/ - Tip registry
└── [10+ service modules]
Core Services
API Service (src/services/api/)
Handles all Anthropic API interactions:
// src/services/api/claude.ts
export async function query(
messages: Message[],
options: QueryOptions
): Promise<QueryResult> {
// Send request to Anthropic API
// Handle streaming responses
// Track usage and costs
}
export function accumulateUsage(usage: Usage): void {
// Accumulate token usage across queries
}
export function getTotalCost(usage: Usage): number {
// Calculate total API cost
}
Key Functions:
query()- Main API query functionfetchBootstrapData()- Fetch initial configurationdownloadSessionFiles()- Download session artifactscategorizeRetryableAPIError()- Error classification
MCP Service (src/services/mcp/)
Model Context Protocol integration:
// src/services/mcp/client.ts
export async function getMcpToolsCommandsAndResources(
servers: MCPServerConnection[]
): Promise<Tools> {
// Fetch tools from connected MCP servers
}
export async function prefetchAllMcpResources(): Promise<void> {
// Prefetch MCP resources for performance
}
export function parseMcpConfig(configPath: string): McpServerConfig {
// Parse MCP server configuration
}
Key Functions:
getMcpToolsCommandsAndResources()- Aggregate MCP toolsprefetchOfficialMcpUrls()- Prefetch official MCP URLsparseMcpConfig()- Parse server configurationclearServerCache()- Clear MCP server cache
OAuth Service (src/services/oauth/)
Authentication and session management:
// src/services/oauth/index.ts
export async function authenticateUser(): Promise<AuthResult> {
// Authenticate user via OAuth flow
}
export function getOauthConfig(): OauthConfig {
// Get OAuth configuration
}
export function refreshAuthToken(): Promise<string> {
// Refresh authentication token
}
LSP Service (src/services/lsp/)
Language Server Protocol integration:
// src/services/lsp/manager.ts
export function initializeLspServerManager(): void {
// Initialize LSP server manager
}
export function getDiagnostics(filePath: string): Diagnostic[] {
// Get LSP diagnostics for a file
}
export function completeSymbol(symbol: string): Completion[] {
// Get symbol completions
}
Analytics Service (src/services/analytics/)
Feature flags and telemetry:
// src/services/analytics/growthbook.ts
export function initializeGrowthBook(): void {
// Initialize GrowthBook feature flags
}
export function getFeatureValue_CACHED_MAY_BE_STALE(flag: string): unknown {
// Get cached feature flag value
}
export function refreshGrowthBookAfterAuthChange(): void {
// Refresh feature flags after authentication change
}
// src/services/analytics/index.ts
export function logEvent(
eventName: string,
metadata: AnalyticsMetadata
): void {
// Log analytics event
}
Service Integration Pattern
Services follow a consistent integration pattern:
// Service initialization
export async function initializeService(): Promise<void> {
// Initialize service dependencies
// Set up event listeners
// Prefetch data if needed
}
// Service operation
export async function performOperation(params: Params): Promise<Result> {
// Execute service operation
// Handle errors gracefully
// Return structured result
}
// Service state management
export function getServiceState(): ServiceState {
// Get current service state
}
export function updateServiceState(updater: StateUpdater): void {
// Update service state
}
Service Best Practices
- Lazy Loading: Heavy services loaded on demand
- Error Handling: Graceful degradation on failures
- Caching: Results cached for performance
- Event-Driven: Services emit events for state changes
- Configuration: Services respect global settings
Service Dependencies
API Service Dependencies
- Anthropic SDK
- File system operations
- Network requests
MCP Service Dependencies
- MCP SDK
- Configuration files
- Server connections
OAuth Service Dependencies
- Keychain access
- Token storage
- Authentication flows
LSP Service Dependencies
- Language servers
- File watchers
- Diagnostic engines
Analytics Service Dependencies
- GrowthBook SDK
- Event logging
- Feature flag management
Service Initialization Order
Services are initialized in a specific order for optimal performance:
// src/main.tsx
// 1. API service (bootstrap data)
await fetchBootstrapData();
// 2. OAuth service (authentication)
await authenticateUser();
// 3. MCP service (server connections)
await prefetchAllMcpResources();
// 4. LSP service (language servers)
initializeLspServerManager();
// 5. Analytics service (feature flags)
initializeGrowthBook();
Service Communication
Services communicate via:
- Event Emitters: Real-time state changes
- Shared State: AppState store
- Direct Calls: Synchronous operations
- Callbacks: Asynchronous notifications
Service Error Handling
try {
await serviceOperation();
} catch (error) {
if (isRetryableError(error)) {
// Retry with backoff
await retryOperation(error);
} else {
// Log and continue
logEvent('service_error', { service: 'api', error: error.message });
}
}
Service Performance Optimization
- Parallel Initialization: Multiple services start simultaneously
- Prefetching: Data fetched before needed
- Caching: Results cached to avoid redundant calls
- Lazy Loading: Heavy services loaded on demand
- Background Tasks: Non-critical work deferred
Security Considerations
- Permission Checks: Services respect permission modes
- Working Directory: Services respect cwd restrictions
- Feature Flags: Conditional service availability
- Error Boundaries: Isolated failure handling
- State Isolation: Service state separate from app state
Service Configuration
Services can be configured via:
- Settings File:
settings.json - Environment Variables:
CLAUDE_CODE_* - Command Line Flags:
--settings,--model - Remote Config: Enterprise MCP configurations