Freedcamp MCP Server
by mahrukh-n8n
README.md
# Freedcamp MCP Server
A [Model Context Protocol](https://modelcontextprotocol.io/) server that wraps the [Freedcamp](https://freedcamp.com) REST API. It lets any MCP-compatible LLM client (Claude Code, Claude Desktop, etc.) manage Freedcamp projects, tasks, users, and comments through natural language.
## Features
- **17 tools** covering projects, tasks, users, comments, and health checks
- **HMAC-SHA1 authentication** — the API secret never leaves the server; only a signed hash is sent per request
- **Name resolution** — pass user names, emails, or project names instead of raw numeric IDs; the server resolves them automatically with TTL-based caching
- **Field limiting** — request only the fields you need with dot-notation (`id,title,comments.created_ts`) to reduce response size
- **Status label mapping** — accept human-readable strings like `"in progress"` instead of numeric codes
- **Response filtering** — internal API fields are automatically stripped from responses
- **Graceful shutdown** — drains in-flight requests before exiting
- **Retry + backoff** — retries on 429 and 5xx with exponential backoff
- **No build step** — runs TypeScript directly via tsx
## Prerequisites
- Node.js >= 18
- A Freedcamp account with API credentials (Settings → API)
## Installation
```bash
git clone https://github.com/mahrukh-n8n/freedcampMCP.git
cd freedcampMCP
npm install
```
## Configuration
### Option A: .env file
```bash
cp .env.example .env
# Edit .env with your Freedcamp API key and secret
```
### Option B: Claude Code MCP settings
No `.env` file needed — pass credentials as environment variables:
```bash
claude mcp add freedcamp npx tsx /path/to/freedcampMCP/scripts/mcp-server.ts \
-e FREEDCAMP_API_KEY=your_key \
-e FREEDCAMP_API_SECRET=your_secret
```
### Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
| `FREEDCAMP_API_KEY` | Yes | — | Freedcamp API key |
| `FREEDCAMP_API_SECRET` | Yes | — | Freedcamp API secret |
| `FREEDCAMP_API_URL` | No | `https://freedcamp.com` | Base URL (for self-hosted) |
| `LOG_LEVEL` | No | `info` | Log level: debug, info, warn, error |
| `REQUEST_TIMEOUT_MS` | No | `30000` | HTTP request timeout (ms) |
| `CACHE_TTL_MS` | No | `60000` | Name resolution cache TTL (ms) |
| `MAX_CONCURRENT_REQUESTS` | No | `6` | Max concurrent API requests |
## Running
### With Claude Code (recommended)
After adding the MCP server with `claude mcp add`, just start a conversation. Claude will call tools automatically when needed.
### With MCP Inspector
```bash
npx @modelcontextprotocol/inspector npx tsx scripts/mcp-server.ts
```
Opens a browser UI where you can call each tool and inspect responses.
### Direct (stdio)
```bash
npx tsx scripts/mcp-server.ts
```
The server listens on stdin/stdout using the MCP stdio transport. The host process (Claude Code, Claude Desktop) manages its lifecycle.
## Tools
### Health
| Tool | Description |
|---|---|
| `health.check` | Verify API credentials and connection status |
### Projects
| Tool | Write | Description |
|---|---|---|
| `project.list` | | List projects (paginated, sortable, field-limitable) |
| `project.get` | | Get project by ID or name |
| `project.create` | Yes | Create a project (name, description, color, group, members) |
| `project.update` | Yes | Update project fields (partial update) |
### Tasks
| Tool | Write | Description |
|---|---|---|
| `task.list` | | List tasks with filters (assignee, status, date range, search, tags) |
| `task.get` | | Get task by ID with comments and tag detail; injects `task_url` |
| `task.create` | Yes | Create task (status labels accepted, file attachments) |
| `task.update` | Yes | Update task fields (partial update, file attachments) |
| `task.delete` | Yes | Delete a task |
| `task.assign` | Yes | Assign users to a task |
### Users
| Tool | Write | Description |
|---|---|---|
| `user.list` | | List users (optionally filter by project) |
| `user.get` | | Get user by ID, email, or name |
| `user.current` | | Get authenticated user's profile |
| `user.create` | Yes | Create user (email, password, first_name, OAuth) |
| `user.update_current` | Yes | Update authenticated user's profile |
### Comments
| Tool | Write | Description |
|---|---|---|
| `comment.add` | Yes | Add a comment (requires item_id + app_id) |
| `comment.update` | Yes | Update comment text |
| `comment.delete` | Yes | Delete a comment |
## Name Resolution
Most ID parameters accept names, emails, or numeric IDs. Examples:
- `project_id: "Marketing"` — resolves to the project's numeric ID
- `assigned_to_id: "alice@example.com"` — resolves to the user's numeric ID
- `assigned_to_id: ["Alice", 42]` — mixed lists accepted
Resolution results are cached with a configurable TTL (`CACHE_TTL_MS`).
## Status Mapping
Task status accepts both numeric codes and string labels:
| Code | Label |
|---|---|
| 0 | not started |
| 1 | in progress |
| 2 | completed |
Example: `status: "in progress"` is equivalent to `status: 1`.
## Field Limiting
All list and get tools accept a `fields` parameter with dot-notation paths:
```
fields="id,title,priority,comments.created_ts"
```
This reduces response size and focuses the LLM on relevant data. Nested arrays are preserved — `comments.created_ts` on `[{created_ts: 1}]` yields `[{created_ts: 1}]`, not a flat list.
## App ID Constants (for comments)
| App | ID |
|---|---|
| tasks | 2 |
| milestones | 3 |
| discussions | 5 |
| files | 6 |
| time | 8 |
| issue_tracker | 9 |
## Authentication
The server uses **HMAC-SHA1** authentication. On every request:
1. A Unix timestamp is generated
2. A hash is computed: `HMAC-SHA1(secret, apiKey + timestamp)`
3. Auth params are sent as query string: `?api_key=...×tamp=...&hash=...`
The **secret never goes over the wire**. At boot, the server validates credentials with `GET /api_key/check`.
## Error Codes
| Code | Meaning |
|---|---|
| `PERMISSION_DENIED` | Invalid API key/secret or insufficient access |
| `NOT_FOUND` | Requested resource or name resolution target does not exist |
| `VALIDATION_ERROR` | Invalid input parameters |
| `CONFLICT` | Resource already exists |
| `INTERNAL_ERROR` | Server error, rate limit, or network failure |
## Development
```bash
# Type check
npx tsc --noEmit
# Run tests
npx vitest run
# Watch mode
npx vitest
# Run server in dev mode
npm run dev
```
## Testing
The test suite uses Vitest with mocked API responses:
```bash
npx vitest run # Single run
npx vitest # Watch mode
npx vitest --coverage # With coverage
```
## Project Structure
```
scripts/mcp-server.ts Entry point
src/lib/freedcamp/
api-client.ts HTTP client with HMAC auth, retry, filtering
register-tools.ts Wire all tools to the MCP registry
auth/hmac.ts HMAC-SHA1 computation
auth/hmac-validator.ts Boot-time credential validation
tools/
health.ts health.check
projects.ts project.list/get/create/update
tasks.ts task.list/get/create/update/delete/assign
users.ts user.list/get/current/create/update_current
comments.ts comment.add/update/delete
utils/
name-resolver.ts Name/email → ID resolution with caching
response-filter.ts Strip internal fields from API responses
field-limiter.ts Dot-notation field extraction
date-utils.ts Date validation and formatting
resolution-cache.ts TTL-based LRU cache
logger.ts Structured logging with verbose mode
validation.ts Input validation helpers
src/modules/mcp/
registry/tool-registry.ts MCP tool registry
services/create-mcp-server.ts MCP server factory
services/stdio-transport.ts Stdio transport
types.ts MCP result types
utils/serialize.ts Result envelope helpers (dataResult, commitResult, etc.)
```
## License
MITThis server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues