# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
**freelo-mcp** is an MCP (Model Context Protocol) server built with mcp-framework. It exposes custom tools that can be integrated with Claude Desktop or other MCP-compatible clients, allowing Claude to interact with external systems through well-defined tool interfaces.
## Development Commands
### Core Workflow
- `npm install` - Install dependencies
- `npm run build` - Compile TypeScript and build with mcp-build
- `npm run watch` - Watch mode for TypeScript compilation during development
- `npm run start` - Run the compiled server
### Tool Development
- `mcp add tool <name>` - Scaffold a new tool using the mcp-framework CLI
### Local Testing
- `npm link` - Link package locally for testing
- `freelo-mcp` - Run the CLI locally after linking
## Architecture
### MCP Server Setup
The server is initialized in `src/index.ts` using the MCPServer class from mcp-framework:
- STDIO transport for local client communication (standard for Claude Desktop)
- Each client instance runs its own server process with isolated credentials
- Framework handles automatic tool discovery from `src/tools/` directory
### Tool Pattern
Each tool follows a consistent structure by extending `MCPTool<InputType>`:
```typescript
class ToolName extends MCPTool<InputInterface> {
name = "tool_identifier";
description = "Human-readable explanation of what the tool does";
schema = {
// Zod schema for input validation
};
async execute(input: InputInterface) {
// Tool implementation - must be async
return { /* result */ };
}
}
```
**Key components:**
- **Name**: Unique identifier for the tool (used by Claude to invoke it)
- **Description**: Explains the tool's purpose (shown to Claude)
- **Schema**: Zod-based schema for runtime input validation and type safety
- **Execute**: Async method that implements the tool's logic
### Type Safety Strategy
- **Compile-time**: Strict TypeScript mode enabled
- **Runtime**: Zod schemas validate inputs before execution
- **Module System**: ESNext modules (not CommonJS)
## Adding New Tools
1. **Using CLI** (recommended):
```bash
mcp add tool <name>
```
2. **Manual creation**:
- Create new file in `src/tools/`
- Extend `MCPTool<InputType>`
- Define name, description, schema, and execute method
- Framework auto-discovers tools at runtime
## Claude Desktop Integration
The server uses STDIO transport, so each Claude Desktop user runs their own isolated instance with their own Freelo credentials.
### Configuration
**Local Development:**
```json
{
"mcpServers": {
"freelo-mcp": {
"command": "node",
"args": ["/absolute/path/to/freelo-mcp/dist/index.js"],
"env": {
"FREELO_EMAIL": "your-email@example.com",
"FREELO_API_KEY": "your-api-key-here"
}
}
}
}
```
**After Publishing to npm:**
```json
{
"mcpServers": {
"freelo-mcp": {
"command": "npx",
"args": ["freelo-mcp"],
"env": {
"FREELO_EMAIL": "your-email@example.com",
"FREELO_API_KEY": "your-api-key-here"
}
}
}
}
```
### Multi-User Setup
Each user can have their own credentials by configuring their own `env` section in Claude Desktop config:
**User 1 (`~/Library/Application Support/Claude/claude_desktop_config.json`):**
```json
{
"mcpServers": {
"freelo-mcp": {
"command": "npx",
"args": ["freelo-mcp"],
"env": {
"FREELO_EMAIL": "user1@company.com",
"FREELO_API_KEY": "user1-api-key"
}
}
}
}
```
**User 2 (on their own machine):**
```json
{
"mcpServers": {
"freelo-mcp": {
"command": "npx",
"args": ["freelo-mcp"],
"env": {
"FREELO_EMAIL": "user2@company.com",
"FREELO_API_KEY": "user2-api-key"
}
}
}
}
```
**Alternative: Using .env file**
Instead of specifying `env` in the config, users can also create a `.env` file in the project directory with their credentials:
```
FREELO_EMAIL=your-email@example.com
FREELO_API_KEY=your-api-key
```
## Project Structure
- `src/index.ts` - Server entry point and configuration
- `src/tools/` - MCP tool implementations (auto-discovered)
- `dist/` - Compiled JavaScript output (generated by build)