AGENTS.md
This file provides guidance to AI coding assistants when working with code in this repository.
Development Commands
This project uses just as the build tool. Essential commands:
# Full development workflow (default)
just
# Individual commands
just fmt # Format Go code with gofumpt
just lint # Run golangci-lint
just staticcheck # Static analysis
just test # Run tests with go test -v ./...
just vuln # Check for vulnerabilities with govulncheck
just reuse # Check license/copyright headers
# Building and running
just build # Build binary
just run # Run server directly
just install # Install to GOPATH/bin
# Running specific tests
go test -v -run TestName ./internal/mcp # Run single test by name
go test -v ./internal/planning # Run tests for specific package
# Maintenance
go mod tidy # Clean up unused dependencies
The project requires license headers (SPDX format) on all source files and uses REUSE for compliance checking.
Architecture Overview
Core Components
MCP Server Architecture: The server follows a clean layered architecture:
cmd/planning-mcp-server/main.go: CLI entry point with Cobra, supports both STDIO and HTTP modesinternal/mcp/server.go: MCP protocol wrapper that bridges MCP calls to planning operationsinternal/planning/manager.go: Core business logic with thread-safe in-memory storageinternal/planning/types.go: Task and Goal type definitions with status managementinternal/config/: Configuration management with Viper, supports TOML files and env vars
Planning System Design
Task Management: Tasks use deterministic IDs generated via SHA256 hash of title:description, ensuring consistent IDs across sessions without persistence. This is critical - task IDs are not user-provided but generated automatically. The ID is exactly 8 hex characters (first 4 bytes of SHA256 hash). Duplicate task detection happens silently - if a task with the same ID already exists, it's skipped with a warning log but no error is returned.
Thread Safety: The planning manager uses sync.RWMutex for concurrent access. All public methods properly lock/unlock. The UpdateTasks method implements an atomic update pattern - it validates all task IDs exist before applying any updates, ensuring all-or-nothing semantics.
Task List Ordering: Tasks are always displayed sorted by creation time (oldest first) for consistent output across operations. This ordering is maintained even when filtering by status.
Status System: Tasks use emoji indicators with specific meanings:
☐pending⟳in_progress☑completed☒failed⊗cancelled
Task List Legend: The get_tasks() method includes a legend showing status indicators. The legend format is "Legend: ☐ pending ⟳ in progress ☑ completed" and only includes the cancelled icon (⊗) and failed icon (☒) if there are actually cancelled or failed tasks in the current list.
MCP Tool Implementation
The server exposes six MCP tools that map directly to planning manager methods:
set_goal(title: string, description: string): Sets initial goal with title and description (both required). Returns error if goal already exists.change_goal(title: string, description: string, reason: string): Changes existing goal (all parameters required). Only used when operator explicitly requests clearing/changing the goal.add_tasks(tasks: []TaskInput): Batch task creation with duplicate detection. Each task requirestitle(required) anddescription(optional). Encourages breaking tasks down into smallest units of work and regular progress tracking. Output behavior depends on existing tasks: shows verbose instructions + task list when no tasks existed previously, shows brief task list (likeget_tasks) when tasks already existed.get_tasks(status: string): Returns markdown-formatted task list with optional status filter (all, pending, in_progress, completed, cancelled, failed). Default is "all". Should be called frequently to stay organized.update_task_statuses(tasks: []TaskUpdate): Updates status of one or more tasks and returns full list. Never cancels tasks autonomously - marks as failed on errors and asks operator for guidance.delete_tasks(task_ids: []string): Deletes one or more tasks by their IDs. Only used when operator explicitly requests clearing the board. Otherwise, tasks should be marked as cancelled/failed. Returns the resulting task list.
Configuration System
Uses a three-tier config system (defaults → file → environment variables):
- Server mode:
stdio(default) orhttp - Planning limits: max tasks (100), max goal length (1000), max task length (500)
- Environment variables prefixed with
PLANNING_(e.g.,PLANNING_SERVER_MODE) - Config file search paths (in order): current directory,
$HOME/.config/planning-mcp-server,/etc/planning-mcp-server - Config file name:
planning-mcp-server.toml
Development Guidelines
Code Patterns
Error Handling: All functions return descriptive errors. MCP handlers convert errors to CallToolResult with IsError: true. The internal/mcp/helpers.go provides standardized helper functions (createErrorResult, createSuccessResult) for consistent MCP responses.
Goal Formatting: Goals are internally stored as a single text field combining title and description in the format "title: description". The formatGoalText helper ensures consistent formatting across the codebase.
Validation: Input validation happens at multiple layers - MCP parameter parsing, planning manager limits, and config validation.
Logging: Uses structured logging (slog) throughout. All operations log at appropriate levels with contextual fields.
Testing Approach
Testing is planned for future development. Priority areas for testing include:
- Planning manager methods for concurrent access
- MCP request handling with mocked requests
- Configuration loading and validation edge cases
- Deterministic task ID generation
- Session management and persistence (when implemented)
Note: Test files (*_test.go) will be added in future releases to ensure robust coverage of core functionality.
Key Dependencies
github.com/mark3labs/mcp-go: MCP protocol implementationgithub.com/spf13/viper: Configuration managementgithub.com/spf13/cobra: CLI frameworkgithub.com/charmbracelet/fang: Enhanced CLI experience
Important Constraints
Current Storage Model: In-memory storage only - all data is lost on server restart. Session management and persistence are planned for future releases to enable task continuity across sessions.
Deterministic IDs: Task IDs must remain consistent. Never change the ID generation algorithm without migration strategy.
MCP Compliance: All tool responses must follow MCP schema. Responses include both success messages and full task lists where appropriate.
SPDX Licensing: All new files require SPDX headers. Use SPDX-FileCopyrightText: Amolith <amolith@secluded.site> and SPDX-License-Identifier: AGPL-3.0-or-later for source files.