Skip to main content
Glama

Time Tracking MCP

by markwharton
development.md8.22 kB
# Development Guide Quick guide for developers working on Time Tracking MCP. ## Quick Setup ```bash git clone <repo-url> time-tracking-mcp cd time-tracking-mcp npm install npm run build ``` ## Project Structure ``` src/ ├── server.ts # MCP server entry point ├── config/ │ └── environment.ts # Environment variable handling ├── tools/ # MCP tool implementations (thin orchestration layer) │ ├── registry.ts # Tool registration system │ ├── log-time.ts │ ├── status.ts │ ├── check-hours.ts │ └── weekly-report.ts ├── services/ # Business logic (heavy lifting) │ ├── markdown-manager.ts │ ├── duration-parser.ts │ └── summary-calculator.ts ├── utils/ # Shared utilities │ ├── date-utils.ts │ ├── file-utils.ts │ └── report-formatters.ts └── types/ └── index.ts # TypeScript interfaces ``` ### Architecture Diagram ```mermaid graph TB SERVER[Server Entry Point<br/>server.ts] TOOLS[Tools Layer<br/>Thin orchestration<br/>4 MCP tools] SERVICES[Services Layer<br/>Business logic<br/>Markdown, Duration, Summary] UTILS[Utils Layer<br/>Shared helpers<br/>Date, File, Formatting, Strings] CONFIG[Configuration & Types<br/>Environment, Types] SERVER --> TOOLS TOOLS --> SERVICES SERVICES --> UTILS TOOLS --> UTILS TOOLS -.-> CONFIG SERVICES -.-> CONFIG style SERVER fill:#e1f5ff style TOOLS fill:#ffe1f5 style SERVICES fill:#e1ffe1 style UTILS fill:#f5e1ff style CONFIG fill:#fff9e1 ``` ## Key Design Decisions ### Markdown Storage Store time entries in human-readable markdown files instead of a database. This provides: - Human-readable and editable files - Git-friendly version control - Zero database setup or corruption risks - Future-proof format ### Direct Entry Model Log completed tasks directly instead of start/stop tracking: - Simpler mental model - Works retroactively ("yesterday I spent 2h...") - No "forgot to stop timer" problems ### Auto-Calculated Summaries Calculate summaries on-the-fly from entries rather than storing them: - Always accurate - Manual edits automatically reflected - Single source of truth ### Stateless Server MCP server has no memory between calls: - Each request is independent - Markdown files are the source of truth - No caching complexity ## Development Commands ```bash npm run dev # Auto-reload development mode npm run build # Compile TypeScript npm run rebuild # Clean + build ``` ## Adding a New Tool 1. **Create tool file** in `src/tools/`: ```typescript import { registerTool } from './registry.js'; import { createTextResponse, withErrorHandler } from '../utils/tool-response.js'; registerTool({ name: 'my_new_tool', description: `Description that helps Claude understand when to use this. Natural language examples: - "Example user query" - "Another example"`, inputSchema: { type: 'object', properties: { param1: { type: 'string', description: 'Parameter description' } }, required: ['param1'] }, handler: withErrorHandler('doing my task', async (args) => { // Implementation return createTextResponse('Result'); }) }); ``` 2. **Import in server.ts**: ```typescript import './tools/my-new-tool.js'; ``` 3. **Rebuild and test** in Claude Desktop ### Tool Registration Lifecycle ```mermaid flowchart TD START([Create Tool File]) --> REG[Call registerTool with<br/>name, description, schema, handler] REG --> STORE[Tool stored in<br/>toolRegistry Map] IMPORT[server.ts imports tool file] --> EXEC[Tool file executes] EXEC --> REG SERVER[MCP Server starts] --> IMPORT SERVER --> LISTEN[Listen for tool_list request] LISTEN --> REQUEST{Tool List<br/>Request?} REQUEST -->|Yes| GETALL[getAllTools returns<br/>all registered tools] GETALL --> SEND[Send to Claude] SEND --> DISCOVER[Claude discovers<br/>available tools] DISCOVER --> INVOKE{User Request<br/>Matches Tool?} INVOKE -->|Yes| CALL[Claude calls tool<br/>via call_tool request] CALL --> LOOKUP[Look up handler<br/>in toolRegistry] LOOKUP --> WRAP[withErrorHandler wrapper] WRAP --> RUN[Execute tool handler] RUN --> RESULT[Return response<br/>to Claude] RESULT --> USER[Display to user] INVOKE -->|No| WAIT[Wait for next request] WAIT --> INVOKE style START fill:#e1f5ff style REG fill:#fff4e1 style STORE fill:#ffe1f5 style DISCOVER fill:#e1ffe1 style RUN fill:#f5e1ff style RESULT fill:#fff9e1 style USER fill:#e1f5ff ``` ## Code Organization Principles ### Layer Responsibilities - **Tools** - Validate input, call services, format output - **Services** - Business logic, file operations - **Utils** - Reusable helpers - **Types** - Shared interfaces ### DRY Principle See [CLAUDE.md](../../CLAUDE.md) for detailed guidance on avoiding code duplication. **Key rule:** If logic appears in multiple places, extract to a shared utility. ### Error Handling Always use `withErrorHandler` wrapper: ```typescript handler: withErrorHandler('context', async (args) => { // Your code - errors are caught automatically }) ``` ## Testing ### Manual Testing 1. Build: `npm run build` 2. Update Claude Desktop config 3. Restart Claude Desktop 4. Test with natural language queries ### Debugging Check Claude logs: ```bash tail -f ~/Library/Logs/Claude/mcp*.log ``` ## Commit Conventions Use [Conventional Commits](https://www.conventionalcommits.org/): ```bash feat: add monthly report tool fix: correct duration parsing for fractional hours perf: optimize summary calculations refactor: extract date parsing utilities docs: update usage examples ``` ## Releasing ```bash npm run release # Patch version (0.1.0 → 0.1.1) npm run release:minor # Minor version (0.1.0 → 0.2.0) npm run release:major # Major version (0.1.0 → 1.0.0) npm run release:dry # Preview without committing ``` This automatically: 1. Bumps version in package.json 2. Updates CHANGELOG.md 3. Creates git commit and tag ## Data Flow ```mermaid flowchart LR A[User<br/>natural language] --> B[Claude<br/>parses intent] B --> C[Tool Layer<br/>validates parameters] C --> D[Service Layer<br/>implements logic] D --> E[Storage Layer<br/>markdown files] E --> F[Response<br/>formatted text] F --> A subgraph "MCP Server Architecture" C D E end style A fill:#e1f5ff,stroke:#333,stroke-width:2px style B fill:#fff4e1,stroke:#333,stroke-width:2px style C fill:#ffe1f5 style D fill:#e1ffe1 style E fill:#f5e1ff style F fill:#e1f5ff,stroke:#333,stroke-width:2px ``` ## Common Tasks ### Adding a New Duration Format Update `parseDuration` in `src/services/duration-parser.ts` ### Changing Markdown Format ⚠️ **Breaking change** - requires migration script and major version bump ### Adding Configuration Options 1. Add to environment.ts 2. Update README.md configuration section 3. Update docs/example-config.json if needed ## Performance Notes - Week files typically < 10KB (50 entries) - Read time: < 1ms - Summary calculation: O(n) where n = entries, typically < 1ms - No optimization needed for expected workload ## File Structure Each company has its own directory: ``` ~/Documents/time-tracking/ company-name/ config.json # Company configuration 2025-W42.md # Time entries 2025-W43.md ``` ## Philosophy **Keep it simple.** - Do one thing well (time tracking) - Minimal dependencies - Easy to understand - Prioritize user workflow - Remain hackable When in doubt, choose simplicity over features. ## See Also - [Development Principles](../architecture/development-principles.md) - Code standards and principles - [Tag System Guide](../architecture/tag-system.md) - Core architecture understanding - [Format Specification](../reference/format-specification.md) - Technical file format details

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/markwharton/time-tracking-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server