# CLAUDE.md
This file provides guidance to Claude Code when working with this repository.
## Project Overview
This is an MCP (Model Context Protocol) server for Attio CRM. It integrates Attio with AI clients like Claude Code, Claude Desktop, ChatGPT, Windsurf, and Cursor.
## Technology Stack
- **Runtime**: Node.js with TypeScript (strict mode)
- **MCP SDK**: `@modelcontextprotocol/sdk`
- **Transport**: Standard I/O (stdio)
## Available Tools (14)
| Category | Tools |
|----------|-------|
| Schema | `get_workspace_schema` |
| Companies | `search_companies`, `get_company`, `create_company`, `update_company`, `manage_company_domains` |
| People | `search_people`, `get_person`, `create_person`, `update_person`, `manage_person_emails`, `manage_person_tags` |
| Notes | `create_note`, `get_note` |
## Key Files
- `src/index.ts` - MCP server entry point
- `src/attio-client.ts` - Attio API wrapper
- `src/tools/` - Tool implementations
- `src/tools/index.ts` - Tool registry
- `src/utils/error-handler.ts` - Centralized error handling
- `src/utils/errors.ts` - Custom error classes
- `src/lib/schema-cache.ts` - Workspace schema cache
- `src/types/attio.d.ts` - Auto-generated Attio API types (do not edit manually)
## Build Configuration
- **Source**: `src/` directory
- **Build output**: `dist/` directory
- **Entry point**: `dist/index.js`
```bash
npm run build # Build the project
npm run dev # Development with watch mode
npm test # Run tests
```
## Adding New Tools
1. Create a new file in `src/tools/` following the naming pattern `{action}-{object}.ts`
2. Use existing tools as templates (e.g., `search-companies.ts`)
3. Register the tool in `src/tools/index.ts`
4. Add tests in `tests/unit/tools/`
## Error Handling Pattern
All tools use unified error handling:
```typescript
import { createSuccessResponse, handleToolError } from "../utils/error-handler.js";
import { ConfigurationError, ValidationError } from "../utils/errors.js";
export async function handleMyTool(args: Args): Promise<CallToolResult> {
try {
// Validate config
const apiKey = process.env.ATTIO_API_KEY;
if (!apiKey) throw new ConfigurationError('ATTIO_API_KEY not found');
// Business logic
const client = createAttioClient(apiKey);
const result = await client.get('/objects/...');
return createSuccessResponse(result);
} catch (error) {
return handleToolError(error, 'my_tool');
}
}
```
## Environment Variables
- `ATTIO_API_KEY` (required) - Your Attio API key
- `ATTIO_WORKSPACE_SLUG` (optional) - Workspace slug for web URLs
## File Naming Conventions
- Tools: `{action}-{object}.ts` (e.g., `search-companies.ts`)
- Tests: `{filename}.test.ts`
- **Always kebab-case**, never PascalCase or camelCase for filenames