RichCorabbithole MCP Server
README.md
# RichCorabbithole MCP Server
Project-aware MCP server for richcorabbithole-api development. Reduces token usage by caching file contents and providing high-level operations.
## Installation
```bash
npm install
```
## Configuration
1. **Get Asana Personal Access Token**:
- Go to Asana → Settings → Apps → Personal Access Tokens
- Create new token
- Copy it
2. **Add to Claude Desktop config** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"richcorabbithole": {
"command": "node",
"args": ["/Users/richardcompton/projects/richcorabbithole/richcorabbithole-mcp/index.js"],
"env": {
"ASANA_TOKEN": "your_asana_token_here"
}
}
}
}
```
3. **Restart Claude Desktop**
## Available Tools
### API Tools
#### `get_worker_prompts`
Get all worker system prompts (write, edit, seo) in one call.
#### `run_tests`
Run npm test and return summary. Set `verbose: true` for full output.
#### `get_project_status`
Get current git status and modified files.
#### `get_pipeline_info`
Get pipeline architecture and status flow info.
#### `compare_prompts`
Compare prompts across workers to find inconsistencies.
#### `get_file`
Get cached file content. Uses cache to reduce file reads. Set `refresh: true` to force reload.
**Parameters:**
- `path` (required): Relative path from API root
- `refresh` (optional): Force refresh cache
#### `get_asana_tasks`
Get tasks from Asana project by GID. Cached 5 minutes. Set `refresh: true` to force reload.
**Parameters:**
- `project_gid` (required): Asana project GID
- `refresh` (optional): Force refresh cache
**Find your project GID**: Open project in Asana, check URL: `asana.com/0/{project_gid}/...`
### Site Tools
#### `list_blog_posts`
List all blog posts with metadata (title, date, category, depth, draft status).
**Parameters:**
- `drafts` (optional): Include draft posts (default: true)
#### `get_blog_post`
Get full content of a blog post by slug.
**Parameters:**
- `slug` (required): Blog post slug (filename without .md)
#### `run_site_tests`
Run site tests (unit and/or e2e).
**Parameters:**
- `type` (optional): Type of tests to run: 'unit', 'e2e', or 'all' (default: unit)
- `verbose` (optional): Show full output (default: false)
#### `get_site_build_status`
Check if site builds successfully.
#### `get_site_config`
Get Astro site configuration.
#### `validate_blog_frontmatter`
Validate frontmatter of blog posts against schema.
**Parameters:**
- `slug` (optional): Blog post slug to validate (validates all if not provided)
#### `get_category_schema`
Get current hyperfixation categories with colors, Zod enum values, and CSS variables. Use before any category-related work.
## Pipeline Overview
Topics flow through five Lambda workers: Research → Write → Edit → SEO → Publish. Each stage is decoupled by SQS. Task state is tracked in DynamoDB.
Every post has two classification axes resolved at research time:
- **Hyperfixation category** — scored against known categories, can propose new ones
- **Article type** — `knowledge`, `best-of`, `how-to`, or `masterclass`. Inferred from the topic if not provided. Shapes both research focus and post structure.
## Benefits
- **Reduced token usage**: Caches files, provides summaries instead of full output
- **Project context**: Understands pipeline stages, worker relationships
- **High-level operations**: "run tests" instead of bash → parse → summarize
- **Faster iteration**: Pre-indexed project knowledge
## Technical Notes
### Dependencies
- **Zod v4.3.6**: Used for input schema validation. All tool schemas are defined using Zod's type-safe API.
- **MCP SDK v1.26.0**: Requires Zod schemas (v3 or v4) for input validation, not plain JSON schemas.
- **Axios**: For Asana API calls.
### Schema Validation
This server uses Zod schemas for all tool input validation. The MCP SDK automatically validates inputs against these schemas before calling tool handlers. Example:
```javascript
this.server.registerTool('get_file', {
description: 'Get cached file content',
inputSchema: z.object({
path: z.string().describe('Relative path from API root'),
refresh: z.boolean().optional().describe('Force refresh cache'),
}),
}, async (args) => await this.getFile(args.path, args?.refresh));
```
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues