---
description: "Task breakdown for HackerNews MCP Server implementation"
---
# Tasks: HackerNews MCP Server
**Input**: Design documents from `/specs/001-hackernews-mcp-server/`
**Prerequisites**: plan.md ✅, spec.md ✅, research.md ✅, data-model.md ✅, contracts/mcp-tools.json ✅
**Tests**: Tests are included per constitution requirement (Test-First Development)
**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story.
## Format: `[ID] [P?] [Story] Description`
- **[P]**: Can run in parallel (different files, no dependencies)
- **[Story]**: Which user story this task belongs to (US1, US2, US3, US4)
- Include exact file paths in descriptions
## Path Conventions
Single project structure at repository root:
- Source: `src/`
- Tests: `tests/`
- Docs: `docs/`
---
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Project initialization and basic structure
**Constitution Alignment**: Code Quality First, Latest Dependencies Always
- [X] T001 Create project directory structure (src/, tests/, docs/)
- `src/tools/` - MCP tool implementations
- `src/lib/` - Shared utilities (hn-client, rate-limiter, logger, errors, validators)
- `src/types/` - TypeScript type definitions
- `tests/unit/` - Unit tests
- `tests/integration/` - Integration tests against live API
- `tests/contract/` - MCP contract validation tests
- `docs/` - API documentation
- [X] T002 Initialize Node.js project with TypeScript 5.7+ and latest stable dependencies
- Run `npm init -y`
- Install @modelcontextprotocol/sdk (latest), zod (latest)
- Install dev dependencies: vitest, @types/node, typescript
- Verify all versions are latest stable (npm outdated)
- [X] T003 [P] Configure TypeScript strict mode in tsconfig.json
- Enable strict: true
- Set target: ES2022, module: Node16
- Configure paths for clean imports
- Enable sourceMap for debugging
- [X] T004 [P] Configure Biome for linting and formatting with strict settings
- Create biome.json
- Enable all recommended rules
- Configure for TypeScript/JavaScript
- Add npm scripts: lint, format, check
- [X] T005 [P] Setup Vitest test framework with coverage reporting
- Create vitest.config.ts
- Configure coverage thresholds (≥80%)
- Setup test globals and environment
- Add npm scripts: test, test:watch, test:coverage
- [X] T006 [P] Setup structured logging with pino
- Install pino (latest)
- Configure JSON output format
- Enable debug mode via DEBUG env var
- Setup correlation ID generation
- [ ] T007 [P] Setup CI pipeline in .github/workflows/ci.yml
- Automated linting (Biome)
- Type checking (tsc --noEmit)
- Test execution with coverage
- Build verification
- Fail on any quality gate failure
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Core infrastructure that MUST be complete before ANY user story can be implemented
**Constitution Alignment**: Documentation-Driven Development, Observability & Debuggability, Latest Dependencies Always
**⚠️ CRITICAL**: No user story work can begin until this phase is complete
- [X] T008 **Context7 Research**: Retrieve latest MCP SDK documentation via Context7 MCP
- Verify McpServer API patterns
- Confirm tool registration with Zod schemas
- Check stdio transport setup
- Document key patterns in research.md if not already present
- [X] T009 [P] Define TypeScript types for HN API responses in src/types/hn-api.ts
- HNStory interface
- HNComment interface
- HNUser interface
- HNPollOption interface
- HNSearchResult<T> generic interface
- HNItemResponse interface (nested comments)
- Export all types
- [X] T010 [P] Define MCP-specific types in src/types/mcp.ts
- ToolRegistration type helpers
- MCPError types
- MCPResponse type helpers
- Correlation ID types
- [X] T011 [P] Create custom error classes in src/lib/errors.ts
- HNAPIError (statusCode, response)
- RateLimitError (current, limit, resetTime)
- ValidationError (field, value, message)
- NetworkError (timeout, connection failures)
- All extend base Error with toMCPError() method
- Include error context for debugging
- [X] T012 Implement rate limiter in src/lib/rate-limiter.ts
- Track request count (10,000/hour limit)
- Hourly reset via setInterval
- checkLimit() method with warning at 90%, error at 95%
- getCurrentUsage() for monitoring
- Export singleton instance
- [X] T013 Implement structured logger in src/lib/logger.ts
- Pino-based logger with JSON output
- createChildLogger(context) for correlation IDs
- Debug level controlled by DEBUG env var
- Export configured logger instance
- [X] T014 Implement HN API client in src/lib/hn-client.ts
- Use Node.js built-in fetch API
- Methods: search(), searchByDate(), getItem(), getUser()
- Integrate rate limiter (call before each request)
- Add retry logic with exponential backoff (3 attempts)
- 30-second timeout per request
- Parse JSON responses with type validation
- Throw custom errors (HNAPIError, NetworkError)
- Structured logging for all requests/responses
- [X] T015 [P] Create Zod validation schemas in src/lib/validators.ts
- searchParamsSchema (query, tags, numericFilters, page, hitsPerPage)
- storySchema (validate HNStory structure)
- commentSchema (validate HNComment structure)
- userSchema (validate HNUser structure)
- searchResultSchema (validate HNSearchResult structure)
- Export all schemas for reuse in tools
- [X] T016 Initialize MCP server in src/server.ts
- Import McpServer from @modelcontextprotocol/sdk
- Create server instance with name: "hn-mcp-server", version: "1.0.0"
- Export server instance for tool registration
- Add server info/capabilities
- [X] T017 Create main entry point in src/index.ts
- Import server from src/server.ts
- Import all tool registration functions
- Create HNClient instance
- Register all tools with server
- Setup stdio transport (StdioServerTransport)
- Connect server to transport
- Add error handling for startup failures
- Add graceful shutdown handlers
- [ ] T018 [P] Create integration test setup in tests/integration/setup.ts
- Rate-limited test runner (respect 10k/hr limit)
- Serial test execution helper
- Known stable test queries (e.g., "AI", "JavaScript")
- Shared HNClient instance for tests
- Test timeout configuration (10s per test)
- [ ] T019 [P] Create contract test fixtures in tests/contract/fixtures.ts
- Sample valid tool inputs for each MCP tool
- Sample expected outputs
- Error case scenarios
- Schema validation helpers
- [ ] T020 [P] Document architecture decisions in docs/ARCHITECTURE.md
- Why one tool per file
- Rate limiting strategy
- Error handling approach
- Logging patterns
- Type safety approach
**Checkpoint**: Foundation ready - user story implementation can now begin in parallel
---
## Phase 3: User Story 1 - Search Stories and Comments (Priority: P1) 🎯 MVP
**Goal**: Enable users to search HN for specific topics, keywords, or discussions with filtering capabilities
**Independent Test**: Search for "AI" with tag "story" and receive relevant results with metadata
**Constitution Alignment**: Test-First Development, UX Consistency, Integration Testing
### Tests for User Story 1 (TDD Approach)
**NOTE: Write these tests FIRST, ensure they FAIL before implementation (TDD cycle)**
**Constitution Check**: These tests satisfy Test-First Development and Integration Testing principles
- [ ] T021 [P] [US1] Contract test for search_stories tool in tests/contract/search-stories.test.ts
- Import schema from src/lib/validators.ts
- Test valid input schema (query, tags, numericFilters, page, hitsPerPage)
- Test invalid inputs (missing required fields, invalid types)
- Test output schema matches contract (hits, nbHits, nbPages, page, hitsPerPage, processingTimeMS)
- Test error response format
- Aim for 100% schema coverage
- [ ] T022 [P] [US1] Contract test for search_by_date tool in tests/contract/search-by-date.test.ts
- Test valid input schema (query, tags, numericFilters, page, hitsPerPage)
- Test invalid inputs
- Test output schema matches contract
- Test sorting by date validation
- [ ] T023 [P] [US1] Contract test for search_comments tool in tests/contract/search-comments.test.ts
- Test valid input schema (query, tags, sortByDate, page, hitsPerPage)
- Test invalid inputs
- Test output schema matches contract
- Test comment-specific fields
- [ ] T024 [P] [US1] Integration test for search_stories in tests/integration/search-stories.test.ts
- Test against real HN API with query "machine learning" and tag "story"
- Verify results contain title, url, author, points, num_comments
- Test with numericFilters (points>=100)
- Test with restrictSearchableAttributes (url only)
- Test pagination (page=0, page=1)
- Test empty query with tags only
- Test zero results case
- Test rate limit tracking
- Test network error handling (timeout simulation)
- Run serially (integration/setup.ts)
- [ ] T025 [P] [US1] Integration test for search_by_date in tests/integration/search-by-date.test.ts
- Test against real HN API with query "JavaScript"
- Verify results sorted by date (created_at_i descending)
- Test with date range filter (created_at_i>X,created_at_i<Y)
- Test with author filter (author_pg)
- Run serially
- [ ] T026 [P] [US1] Integration test for search_comments in tests/integration/search-comments.test.ts
- Test against real HN API with query "React"
- Verify results contain comment_text, author, story_id, parent_id
- Test with story filter (story_8863)
- Test with author filter
- Test sortByDate=true
- Run serially
- [ ] T027 [P] [US1] Unit tests for HNClient search methods in tests/unit/hn-client.test.ts
- Mock fetch API
- Test query parameter construction
- Test response parsing
- Test rate limiter integration
- Test retry logic with exponential backoff
- Test timeout handling
- Test error mapping (API errors → custom errors)
- Aim for 80%+ coverage
### Implementation for User Story 1
**Constitution Check**: Follow Code Quality First, Latest Dependencies, Documentation-Driven principles
- [X] T028 [US1] Implement search_stories tool in src/tools/search-stories.ts
- Export registerSearchStories(server, hnClient) function
- Register tool with server.registerTool()
- Define tool name: "search_stories"
- Define title: "Search Stories"
- Define description: "Search Hacker News stories by relevance..."
- Define inputSchema using Zod (query: string, tags?: string, numericFilters?: string, page?: number, hitsPerPage?: number)
- Define outputSchema using Zod (matches SearchResult<HNStory>)
- Implement handler: async ({ query, tags, numericFilters, page = 0, hitsPerPage = 20 })
- Validate inputs with searchParamsSchema
- Create child logger with correlation ID
- Call hnClient.search() with parameters
- Handle errors and return MCP-formatted error responses
- Return structured content with hits and metadata
- Add JSDoc with usage examples
- [X] T029 [US1] Implement search_by_date tool in src/tools/search-by-date.ts
- Export registerSearchByDate(server, hnClient) function
- Register tool with server.registerTool()
- Define tool name: "search_by_date"
- Define title: "Search by Date"
- Define description: "Search HN content sorted by date..."
- Define inputSchema (same as search_stories)
- Define outputSchema (same as search_stories)
- Implement handler calling hnClient.searchByDate()
- Validate inputs, log requests, handle errors
- Add JSDoc with usage examples
- [X] T030 [US1] Implement search_comments tool in src/tools/search-comments.ts
- Export registerSearchComments(server, hnClient) function
- Register tool with server.registerTool()
- Define tool name: "search_comments"
- Define title: "Search Comments"
- Define description: "Search HN comments by text content..."
- Define inputSchema (query: string, tags?: string, sortByDate?: boolean, page?: number, hitsPerPage?: number)
- Define outputSchema (SearchResult<HNComment>)
- Implement handler: route to search() or searchByDate() based on sortByDate flag
- Always add "comment" to tags filter
- Validate inputs, log requests, handle errors
- Add JSDoc with usage examples
- [X] T031 [US1] Add search tools to main server in src/index.ts
- Import registerSearchStories, registerSearchByDate, registerSearchComments
- Call all three registration functions with server and hnClient
- Ensure tools are registered before server.connect()
- [ ] T032 [US1] Document search_stories tool in docs/tools/search-stories.md
- Tool description and use cases
- Parameter documentation with examples
- Numeric filters guide (created_at_i, points, num_comments)
- Tag combinations (AND/OR logic)
- Usage examples (basic search, filtered search, pagination)
- Error scenarios and solutions
- Rate limit considerations
- [ ] T033 [US1] Document search_by_date tool in docs/tools/search-by-date.md
- Tool description and use cases
- Parameter documentation
- Date range filtering examples
- Author filtering examples
- Usage examples
- Error scenarios
- [ ] T034 [US1] Document search_comments tool in docs/tools/search-comments.md
- Tool description and use cases
- Parameter documentation
- Story filtering examples
- Sort by date vs relevance
- Usage examples
- Error scenarios
- [ ] T035 [US1] Verify User Story 1 quality gates
- Run `npm run lint` - zero warnings/errors (Biome)
- Run `tsc --noEmit` - type checking passes
- Run `npm test` - all tests pass
- Run `npm run test:coverage` - coverage ≥80% for US1 code
- Review documentation completeness
- Test search_stories, search_by_date, search_comments independently
**Checkpoint**: At this point, User Story 1 (search functionality) is fully functional and testable independently
---
## Phase 4: User Story 2 - Get Front Page and Latest Stories (Priority: P2)
**Goal**: Enable users to access current front page stories and latest submissions to stay updated
**Independent Test**: Retrieve front page stories and verify they match current HN homepage (within 1-minute freshness)
**Constitution Alignment**: Test-First Development, Integration Testing
### Tests for User Story 2 (TDD Approach)
- [ ] T036 [P] [US2] Contract test for get_front_page tool in tests/contract/get-front-page.test.ts
- Test input schema (page?: number, hitsPerPage?: number)
- Test output schema (SearchResult<HNStory>)
- Test default values (page=0, hitsPerPage=30)
- Test input validation (page >= 0, hitsPerPage 1-100)
- [ ] T037 [P] [US2] Contract test for get_latest_stories tool in tests/contract/get-latest-stories.test.ts
- Test input schema (page?: number, hitsPerPage?: number)
- Test output schema (SearchResult<HNStory>)
- Test default values
- [ ] T038 [P] [US2] Contract test for get_ask_hn tool in tests/contract/get-ask-hn.test.ts
- Test input schema
- Test output schema
- Test ask_hn tag is enforced
- [ ] T039 [P] [US2] Contract test for get_show_hn tool in tests/contract/get-show-hn.test.ts
- Test input schema
- Test output schema
- Test show_hn tag is enforced
- [ ] T040 [P] [US2] Integration test for get_front_page in tests/integration/get-front-page.test.ts
- Test against real HN API
- Verify results have front_page tag
- Verify results count (should get ~30 stories)
- Verify results match current HN homepage (spot check top 5)
- Test pagination
- Run serially
- [ ] T041 [P] [US2] Integration test for get_latest_stories in tests/integration/get-latest-stories.test.ts
- Test against real HN API
- Verify results sorted by date descending
- Verify created_at_i timestamps are recent (within last hour)
- Test pagination
- Run serially
- [ ] T042 [P] [US2] Integration test for get_ask_hn in tests/integration/get-ask-hn.test.ts
- Test against real HN API
- Verify all results have ask_hn tag
- Verify results sorted by date descending
- Test pagination
- Run serially
- [ ] T043 [P] [US2] Integration test for get_show_hn in tests/integration/get-show-hn.test.ts
- Test against real HN API
- Verify all results have show_hn tag
- Verify results sorted by date descending
- Test pagination
- Run serially
### Implementation for User Story 2
- [X] T044 [P] [US2] Implement get_front_page tool in src/tools/get-front-page.ts
- Export registerGetFrontPage(server, hnClient) function
- Register tool with server.registerTool()
- Define tool name: "get_front_page"
- Define title: "Get Front Page Stories"
- Define description: "Retrieve stories currently on HN front page..."
- Define inputSchema (page?: number = 0, hitsPerPage?: number = 30)
- Define outputSchema (SearchResult<HNStory>)
- Implement handler: call hnClient.search() with tags="front_page"
- Validate inputs, log requests, handle errors
- Add JSDoc with usage examples
- [X] T045 [P] [US2] Implement get_latest_stories tool in src/tools/get-latest-stories.ts
- Export registerGetLatestStories(server, hnClient) function
- Register tool with server.registerTool()
- Define tool name: "get_latest_stories"
- Define title: "Get Latest Stories"
- Define description: "Retrieve most recently submitted stories..."
- Define inputSchema (page?: number = 0, hitsPerPage?: number = 20)
- Define outputSchema (SearchResult<HNStory>)
- Implement handler: call hnClient.searchByDate() with query="" and tags="story"
- Validate inputs, log requests, handle errors
- Add JSDoc with usage examples
- [X] T046 [P] [US2] Implement get_ask_hn tool in src/tools/get-ask-hn.ts
- Export registerGetAskHN(server, hnClient) function
- Register tool with server.registerTool()
- Define tool name: "get_ask_hn"
- Define title: "Get Ask HN Posts"
- Define description: "Retrieve Ask HN posts (questions to HN community)..."
- Define inputSchema (page?: number = 0, hitsPerPage?: number = 20)
- Define outputSchema (SearchResult<HNStory>)
- Implement handler: call hnClient.searchByDate() with query="" and tags="ask_hn"
- Validate inputs, log requests, handle errors
- Add JSDoc with usage examples
- [X] T047 [P] [US2] Implement get_show_hn tool in src/tools/get-show-hn.ts
- Export registerGetShowHN(server, hnClient) function
- Register tool with server.registerTool()
- Define tool name: "get_show_hn"
- Define title: "Get Show HN Posts"
- Define description: "Retrieve Show HN posts (projects shared with community)..."
- Define inputSchema (page?: number = 0, hitsPerPage?: number = 20)
- Define outputSchema (SearchResult<HNStory>)
- Implement handler: call hnClient.searchByDate() with query="" and tags="show_hn"
- Validate inputs, log requests, handle errors
- Add JSDoc with usage examples
- [X] T048 [US2] Add listing tools to main server in src/index.ts
- Import registerGetFrontPage, registerGetLatestStories, registerGetAskHN, registerGetShowHN
- Call all four registration functions with server and hnClient
- Ensure tools are registered before server.connect()
- [ ] T049 [P] [US2] Document get_front_page tool in docs/tools/get-front-page.md
- Tool description and use cases
- Parameter documentation
- Freshness expectations (~1 minute)
- Usage examples
- Error scenarios
- [ ] T050 [P] [US2] Document get_latest_stories tool in docs/tools/get-latest-stories.md
- Tool description and use cases
- Parameter documentation
- Usage examples
- Difference from front_page
- [ ] T051 [P] [US2] Document get_ask_hn tool in docs/tools/get-ask-hn.md
- Tool description and use cases
- Parameter documentation
- What qualifies as Ask HN
- Usage examples
- [ ] T052 [P] [US2] Document get_show_hn tool in docs/tools/get-show-hn.md
- Tool description and use cases
- Parameter documentation
- What qualifies as Show HN
- Usage examples
- [ ] T053 [US2] Verify User Story 2 quality gates
- Run `npm run lint` - zero warnings/errors
- Run `tsc --noEmit` - type checking passes
- Run `npm test` - all tests pass
- Run `npm run test:coverage` - coverage ≥80% overall
- Review documentation completeness
- Test get_front_page, get_latest_stories, get_ask_hn, get_show_hn independently
**Checkpoint**: At this point, User Stories 1 AND 2 should both work independently
---
## Phase 5: User Story 3 - Retrieve Specific Items and User Profiles (Priority: P3)
**Goal**: Enable users to fetch complete information about specific stories, comments, polls, or user profiles
**Independent Test**: Fetch story ID 8863 with full comment tree and user "pg" profile, verify complete data
**Constitution Alignment**: Test-First Development, Integration Testing
### Tests for User Story 3 (TDD Approach)
- [ ] T054 [P] [US3] Contract test for get_story tool in tests/contract/get-story.test.ts
- Test input schema (id: number, minimum: 1)
- Test output schema (HNItemResponse with nested children)
- Test invalid inputs (id <= 0, non-numeric)
- Test nested comment tree structure validation
- [ ] T055 [P] [US3] Contract test for get_user tool in tests/contract/get-user.test.ts
- Test input schema (username: string, pattern: alphanumeric/hyphens/underscores)
- Test output schema (username, karma, about?, created_at)
- Test invalid inputs (empty username, special characters)
- [ ] T056 [P] [US3] Integration test for get_story in tests/integration/get-story.test.ts
- Test against real HN API with known story ID (e.g., 8863)
- Verify story metadata (title, url, author, points)
- Verify nested comment tree (children array)
- Test multiple levels of nesting (depth >= 3)
- Test story with no comments
- Test deleted/dead story (404 handling)
- Test very large comment tree (>100 comments)
- Run serially
- [ ] T057 [P] [US3] Integration test for get_user in tests/integration/get-user.test.ts
- Test against real HN API with known users ("pg", "sama", "dang")
- Verify user fields (username, karma, about, created_at)
- Test user with no about text
- Test non-existent user (404 handling)
- Run serially
- [ ] T058 [P] [US3] Unit tests for HNClient.getItem() in tests/unit/hn-client.test.ts
- Mock fetch API
- Test URL construction (/items/{id})
- Test response parsing with nested children
- Test error cases (404, 500)
- Test rate limiter integration
- Aim for 80%+ coverage
- [ ] T059 [P] [US3] Unit tests for HNClient.getUser() in tests/unit/hn-client.test.ts
- Mock fetch API
- Test URL construction (/users/{username})
- Test response parsing
- Test error cases (404, 500)
- Test rate limiter integration
- Aim for 80%+ coverage
### Implementation for User Story 3
- [X] T060 [US3] Implement get_story tool in src/tools/get-story.ts
- Export registerGetStory(server, hnClient) function
- Register tool with server.registerTool()
- Define tool name: "get_story"
- Define title: "Get Story"
- Define description: "Retrieve specific story by ID with full nested comment tree..."
- Define inputSchema (id: number, minimum: 1)
- Define outputSchema (HNItemResponse with recursive children)
- Implement handler: async ({ id })
- Validate id > 0
- Create child logger with correlation ID and story ID
- Call hnClient.getItem(id)
- Handle errors (404 → clear "Story not found", others → API error)
- Return structured content with full item tree
- Add JSDoc with usage examples (story ID 8863)
- [X] T061 [US3] Implement get_user tool in src/tools/get-user.ts
- Export registerGetUser(server, hnClient) function
- Register tool with server.registerTool()
- Define tool name: "get_user"
- Define title: "Get User Profile"
- Define description: "Retrieve user profile by username..."
- Define inputSchema (username: string, pattern: ^[a-zA-Z0-9_-]+$)
- Define outputSchema (HNUserResponse)
- Implement handler: async ({ username })
- Validate username pattern
- Create child logger with correlation ID and username
- Call hnClient.getUser(username)
- Handle errors (404 → clear "User not found", others → API error)
- Return structured content with user profile
- Add JSDoc with usage examples (users "pg", "sama")
- [X] T062 [US3] Add getItem() method to HNClient in src/lib/hn-client.ts
- Method signature: async getItem(id: number): Promise<HNItemResponse>
- Check rate limit before request
- Build URL: https://hn.algolia.com/api/v1/items/{id}
- Fetch with timeout (30s)
- Handle 404 specifically (throw HNAPIError with clear message)
- Parse JSON response
- Validate response structure (has id, author, created_at)
- Log request/response with correlation ID
- Return typed HNItemResponse
- [X] T063 [US3] Add getUser() method to HNClient in src/lib/hn-client.ts
- Method signature: async getUser(username: string): Promise<HNUserResponse>
- Check rate limit before request
- Build URL: https://hn.algolia.com/api/v1/users/{username}
- Fetch with timeout (30s)
- Handle 404 specifically (throw HNAPIError with clear message)
- Parse JSON response
- Validate response structure (has username, karma)
- Log request/response with correlation ID
- Return typed HNUserResponse
- [X] T064 [US3] Add item/user tools to main server in src/index.ts
- Import registerGetStory, registerGetUser
- Call both registration functions with server and hnClient
- Ensure tools are registered before server.connect()
- [ ] T065 [P] [US3] Document get_story tool in docs/tools/get-story.md
- Tool description and use cases
- Parameter documentation (ID format)
- Nested comment tree explanation
- Usage examples (famous story IDs)
- Error scenarios (404, malformed ID)
- Performance note (large trees may take 2-3s)
- [ ] T066 [P] [US3] Document get_user tool in docs/tools/get-user.md
- Tool description and use cases
- Parameter documentation (username rules)
- Usage examples (famous users: pg, sama, dang)
- Error scenarios (404, invalid username)
- Privacy note (all data is public)
- [ ] T067 [US3] Verify User Story 3 quality gates
- Run `npm run lint` - zero warnings/errors
- Run `tsc --noEmit` - type checking passes
- Run `npm test` - all tests pass
- Run `npm run test:coverage` - coverage ≥80% overall
- Review documentation completeness
- Test get_story and get_user independently
**Checkpoint**: All core user stories (US1, US2, US3) are now independently functional
---
## Phase 6: User Story 4 - Advanced Filtering and Pagination (Priority: P4)
**Goal**: Enable power users to filter stories by time ranges, points, comment counts with efficient pagination
**Independent Test**: Filter for stories with >100 points from last week with pagination, verify results match criteria
**Constitution Alignment**: Test-First Development, Integration Testing
### Tests for User Story 4 (TDD Approach)
**NOTE**: US4 tests primarily validate existing tools (search_stories, search_by_date) with advanced parameters
- [ ] T068 [P] [US4] Integration test for advanced numeric filters in tests/integration/advanced-filters.test.ts
- Test points filter: numericFilters="points>=100"
- Test comment count filter: numericFilters="num_comments>=50"
- Test date range filter: numericFilters="created_at_i>X,created_at_i<Y"
- Test combined filters: "created_at_i>X,points>=100,num_comments>=50"
- Verify all results match filter criteria
- Run serially against real API
- [ ] T069 [P] [US4] Integration test for tag combinations in tests/integration/tag-combinations.test.ts
- Test AND logic: tags="story,front_page"
- Test OR logic: tags="(story,poll)"
- Test author filter: tags="author_pg"
- Test story-specific: tags="story_8863"
- Test complex: tags="author_pg,(story,poll)"
- Run serially against real API
- [ ] T070 [P] [US4] Integration test for pagination in tests/integration/pagination.test.ts
- Test page=0 vs page=1 (different results)
- Test hitsPerPage variations (10, 20, 50, 100)
- Test nbPages calculation accuracy
- Test last page behavior (partial results)
- Test beyond last page (empty results)
- Verify pagination metadata matches actual results
- Run serially against real API
- [ ] T071 [P] [US4] Unit tests for query parameter construction in tests/unit/hn-client.test.ts
- Test numeric filters URL encoding
- Test tag combinations URL encoding
- Test page/hitsPerPage parameters
- Test empty/optional parameter handling
- Mock fetch and verify correct URLs
### Implementation for User Story 4
**NOTE**: US4 implementation is mostly validation and documentation - core functionality exists in US1 tools
- [ ] T072 [P] [US4] Add advanced filter examples to docs/tools/search-stories.md
- Section: "Advanced Numeric Filters"
- Points threshold examples
- Comment count examples
- Date range examples (with Unix timestamp conversion)
- Combined filter examples
- Section: "Tag Combinations"
- AND logic examples
- OR logic examples
- Author filtering
- Story-specific filtering
- Section: "Pagination Best Practices"
- Optimal hitsPerPage values
- Handling large result sets
- Rate limit considerations
- Example: paginating through 500 results
- [ ] T073 [P] [US4] Create filtering guide in docs/FILTERING.md
- Complete numeric filter reference
- created_at_i operators (>, >=, =, <=, <)
- points operators
- num_comments operators
- Combining filters (comma = AND)
- Complete tag filter reference
- Content type tags
- Special tags (front_page, ask_hn, show_hn)
- Author tags (author_USERNAME)
- Story tags (story_ID)
- Combining tags (comma = AND, parentheses = OR)
- Common filtering patterns
- "Popular stories from last week"
- "Active discussions (many comments)"
- "Recent posts by specific author"
- "Show HN from last month with >50 points"
- Pagination strategies
- When to use hitsPerPage
- Calculating page ranges
- Rate limit efficiency
- [ ] T074 [P] [US4] Create pagination guide in docs/PAGINATION.md
- Understanding nbPages, nbHits, page, hitsPerPage
- Calculating total available pages
- Best practices for large result sets
- Rate limit implications (fewer, larger pages vs many small pages)
- Example code patterns for iterating through all results
- [ ] T075 [P] [US4] Add Unix timestamp helper to docs/UTILITIES.md
- JavaScript/TypeScript timestamp conversion examples
- Common date ranges (last 24h, last week, last month, last year)
- UTC vs local time considerations
- Example: "Get stories from last 7 days"
```typescript
const sevenDaysAgo = Math.floor((Date.now() - 7 * 24 * 60 * 60 * 1000) / 1000);
numericFilters: `created_at_i>${sevenDaysAgo}`
```
- [ ] T076 [US4] Verify User Story 4 quality gates
- Run `npm run lint` - zero warnings/errors
- Run `tsc --noEmit` - type checking passes
- Run `npm test` - all tests pass (including new US4 tests)
- Run `npm run test:coverage` - coverage ≥80% overall
- Review documentation completeness (advanced guides)
- Manually test complex filter combinations
**Checkpoint**: All user stories (US1, US2, US3, US4) are complete and independently functional
---
## Phase 7: Polish & Cross-Cutting Concerns
**Purpose**: Final improvements that affect multiple user stories or overall project quality
**Constitution Alignment**: All principles, final compliance check
- [ ] T077 [P] Create comprehensive README.md at repository root
- Project description and features
- Installation instructions (npm, from source)
- Quick start guide (link to quickstart.md)
- Available tools summary (9 tools with brief descriptions)
- Claude Desktop configuration
- Rate limit information
- Links to documentation
- Contributing guidelines
- License information
- [ ] T078 [P] Create API reference in docs/API.md
- Complete tool reference (all 9 tools)
- For each tool:
- Name and description
- Input parameters with types and examples
- Output structure with types
- Error cases
- Usage examples
- Generated from JSDoc comments if possible
- [ ] T079 [P] Create development guide in docs/DEVELOPMENT.md
- Setting up development environment
- Running tests (unit, integration, contract)
- Debugging MCP tools (stdio transport challenges)
- Adding new tools (template and best practices)
- Code style guidelines
- Release process
- [ ] T080 [P] Create CHANGELOG.md
- Version 1.0.0 initial release
- List all implemented features (9 tools)
- Known limitations
- Planned features (if any)
- [ ] T081 [P] Add examples to docs/EXAMPLES.md
- Common Claude Desktop prompts
- Expected tool calls
- Example outputs
- Multi-step workflows
- "Research a topic" (search → get story → get comments)
- "Follow a user" (get user → search author)
- "Track trending topics" (front page → search by date)
- [ ] T082 Add rate limit monitoring to src/lib/rate-limiter.ts
- Add getCurrentUsage() method returning { current, limit, percentage, resetTime }
- Add getResetTime() method
- Add export for monitoring dashboard/logging
- [ ] T083 Add debug logging for rate limiter
- Log every rate limit check with current usage
- Log when approaching limits (90%, 95%)
- Log when limit is exceeded
- Log hourly reset events
- [ ] T084 Add performance metrics to HNClient
- Track request duration (start to finish)
- Log slow requests (>2s warning, >3s error)
- Track retry attempts
- Aggregate metrics (total requests, avg duration, error rate)
- [ ] T085 [P] Add comprehensive error handling examples to docs/ERROR-HANDLING.md
- Common error scenarios
- Rate limit exceeded → what to do
- Item not found → typical causes
- Network timeout → troubleshooting
- Invalid parameters → how to fix
- Error message reference
- Debugging tips
- Logging and monitoring
- [ ] T086 Run constitution compliance audit
- **Code Quality First**: Run final lint/format check (zero warnings)
- **Test-First Development**: Verify TDD was followed (tests written first, pass/fail/refactor cycle)
- **UX Consistency**: Audit all tool names, parameters, error messages for consistency
- **Latest Dependencies**: Run `npm outdated` and update any outdated packages
- **Documentation-Driven**: Verify all tools documented with examples
- **Integration Testing**: Verify integration tests cover all tools against real API
- **Observability**: Verify structured logging present in all code paths
- Document any deviations with justification
- [ ] T087 Run full test suite with coverage report
- `npm run test:coverage`
- Verify ≥80% coverage overall
- Identify any gaps and add tests if below threshold
- Generate HTML coverage report for review
- [ ] T088 Validate quickstart.md guide
- Follow quickstart.md step by step
- Verify all commands work
- Test Claude Desktop integration
- Test all 9 tools with example prompts
- Fix any inaccuracies or outdated information
- [ ] T089 Run npm audit and fix security vulnerabilities
- `npm audit`
- Fix any HIGH or CRITICAL vulnerabilities
- Document any MODERATE/LOW vulnerabilities that can't be fixed
- Re-run audit to verify clean state
- [ ] T090 Create package.json scripts for common tasks
- `npm start` → build and run server
- `npm run build` → compile TypeScript
- `npm run dev` → watch mode for development
- `npm test` → run all tests
- `npm run test:unit` → unit tests only
- `npm run test:integration` → integration tests only
- `npm run test:contract` → contract tests only
- `npm run test:watch` → watch mode
- `npm run test:coverage` → coverage report
- `npm run lint` → run Biome linter
- `npm run format` → run Biome formatter
- `npm run check` → lint + format + type-check
- `npm run ci` → full CI workflow (lint, type-check, test, build)
- [ ] T091 [P] Add GitHub issue templates
- Bug report template (.github/ISSUE_TEMPLATE/bug_report.md)
- Feature request template (.github/ISSUE_TEMPLATE/feature_request.md)
- Question template (.github/ISSUE_TEMPLATE/question.md)
- [ ] T092 [P] Add pull request template
- Create .github/pull_request_template.md
- Checklist: tests added, docs updated, lint passing, constitution compliance
- [ ] T093 Final code cleanup and refactoring
- Remove any TODO comments
- Remove unused imports
- Ensure consistent naming conventions
- Ensure consistent error handling patterns
- Ensure consistent logging patterns
- Final Biome format pass
- [ ] T094 Prepare for npm publication (optional)
- Update package.json with repository, keywords, author, license
- Add .npmignore (exclude tests/, docs/, specs/)
- Add LICENSE file (MIT)
- Add engines field (node >= 20)
- Test local installation: `npm pack && npm install -g hn-mcp-server-*.tgz`
- Verify binary works: `hn-mcp-server --version`
---
## Dependencies & Execution Order
### Phase Dependencies
- **Setup (Phase 1)**: No dependencies - can start immediately
- Duration: ~2 hours
- **Foundational (Phase 2)**: Depends on Setup completion - BLOCKS all user stories
- Duration: ~1 day
- Critical path: Types → Errors → Rate Limiter → HN Client → Server Setup
- **User Stories (Phase 3-6)**: All depend on Foundational phase completion
- **User Story 1 (P1)**: Can start immediately after Foundational - MVP priority
- Duration: ~1 day (tests + implementation + docs)
- **User Story 2 (P2)**: Can start after Foundational - Independent of US1
- Duration: ~0.5 day
- **User Story 3 (P3)**: Can start after Foundational - Independent of US1/US2
- Duration: ~0.5 day
- **User Story 4 (P4)**: Can start after Foundational - Validates US1 capabilities
- Duration: ~0.25 day (mostly documentation and tests)
- **Polish (Phase 7)**: Depends on all desired user stories being complete
- Duration: ~0.5 day
- Can start after US1-US4 are complete
### Critical Path (Fastest Implementation)
For MVP (User Story 1 only):
1. Setup (Phase 1) - 2 hours
2. Foundational (Phase 2) - 1 day
3. User Story 1 (Phase 3) - 1 day
4. Polish (Phase 7, subset) - 2 hours
**Total MVP Time**: ~2.5 days
For Full Feature Set (US1-US4):
1. Setup - 2 hours
2. Foundational - 1 day
3. User Stories (sequential) - 2.25 days OR (parallel with 4 devs) - 1 day
4. Polish - 0.5 day
**Total Time (Sequential)**: ~4 days
**Total Time (Parallel)**: ~3 days
### Within Each User Story
**TDD Order (Constitution Requirement)**:
1. Write contract tests → ensure they fail
2. Write integration tests → ensure they fail
3. Write unit tests → ensure they fail
4. Get test approval
5. Implement code → tests pass
6. Refactor → tests still pass
7. Write documentation
**Task Dependencies Within Story**:
- Tests [P] can all run in parallel (different files)
- Tool implementations depend on tests written first (TDD)
- Tool implementations for same story [P] can run in parallel (different files)
- Documentation [P] can run in parallel (different files)
- Registration in main server depends on tool implementations
- Quality gate verification is last step
### Parallel Opportunities
**Phase 1 (Setup) - 5 tasks in parallel**:
```
T003 [P] Configure TypeScript
T004 [P] Configure Biome
T005 [P] Configure Vitest
T006 [P] Configure pino
T007 [P] Configure CI
```
**Phase 2 (Foundational) - Multiple parallel groups**:
```
Group 1 (after T008):
T009 [P] Define HN types
T010 [P] Define MCP types
T011 [P] Create error classes
T015 [P] Create Zod schemas
Group 2 (after Group 1):
T012 Rate limiter
T013 Logger
Group 3 (after Group 2):
T014 HN Client
Group 4 (after T017):
T018 [P] Integration test setup
T019 [P] Contract test fixtures
T020 [P] Architecture docs
```
**Phase 3 (User Story 1) - Tests in parallel**:
```
T021 [P] Contract test: search_stories
T022 [P] Contract test: search_by_date
T023 [P] Contract test: search_comments
T024 [P] Integration test: search_stories
T025 [P] Integration test: search_by_date
T026 [P] Integration test: search_comments
T027 [P] Unit tests: HNClient search
```
**Phase 3 (User Story 1) - Implementation in parallel**:
```
After tests pass:
T028 Implement search_stories
T029 Implement search_by_date
T030 Implement search_comments
(These can run in parallel if multiple developers)
Then docs in parallel:
T032 [P] Document search_stories
T033 [P] Document search_by_date
T034 [P] Document search_comments
```
**Phase 4 (User Story 2) - Tests in parallel**:
```
T036 [P] Contract test: get_front_page
T037 [P] Contract test: get_latest_stories
T038 [P] Contract test: get_ask_hn
T039 [P] Contract test: get_show_hn
T040 [P] Integration test: get_front_page
T041 [P] Integration test: get_latest_stories
T042 [P] Integration test: get_ask_hn
T043 [P] Integration test: get_show_hn
```
**Phase 4 (User Story 2) - Implementation in parallel**:
```
T044 [P] Implement get_front_page
T045 [P] Implement get_latest_stories
T046 [P] Implement get_ask_hn
T047 [P] Implement get_show_hn
Then docs in parallel:
T049 [P] Document get_front_page
T050 [P] Document get_latest_stories
T051 [P] Document get_ask_hn
T052 [P] Document get_show_hn
```
**Phase 5 (User Story 3) - Tests in parallel**:
```
T054 [P] Contract test: get_story
T055 [P] Contract test: get_user
T056 [P] Integration test: get_story
T057 [P] Integration test: get_user
T058 [P] Unit test: HNClient.getItem
T059 [P] Unit test: HNClient.getUser
```
**Phase 5 (User Story 3) - Implementation in parallel**:
```
T060 Implement get_story
T061 Implement get_user
T062 Add getItem() to HNClient
T063 Add getUser() to HNClient
(T062 and T063 can run in parallel)
Then docs in parallel:
T065 [P] Document get_story
T066 [P] Document get_user
```
**Phase 6 (User Story 4) - Tests in parallel**:
```
T068 [P] Integration test: advanced filters
T069 [P] Integration test: tag combinations
T070 [P] Integration test: pagination
T071 [P] Unit test: query construction
```
**Phase 6 (User Story 4) - Docs in parallel**:
```
T072 [P] Update search_stories.md
T073 [P] Create FILTERING.md
T074 [P] Create PAGINATION.md
T075 [P] Create UTILITIES.md
```
**Phase 7 (Polish) - Many tasks in parallel**:
```
T077 [P] README.md
T078 [P] API.md
T079 [P] DEVELOPMENT.md
T080 [P] CHANGELOG.md
T081 [P] EXAMPLES.md
T085 [P] ERROR-HANDLING.md
T091 [P] Issue templates
T092 [P] PR template
```
---
## Parallel Example: Full User Story 1 Implementation
```bash
# Step 1: Write all tests in parallel (TDD)
parallel_tasks=(
"T021: Contract test for search_stories in tests/contract/search-stories.test.ts"
"T022: Contract test for search_by_date in tests/contract/search-by-date.test.ts"
"T023: Contract test for search_comments in tests/contract/search-comments.test.ts"
"T024: Integration test for search_stories in tests/integration/search-stories.test.ts"
"T025: Integration test for search_by_date in tests/integration/search-by-date.test.ts"
"T026: Integration test for search_comments in tests/integration/search-comments.test.ts"
"T027: Unit tests for HNClient.search() in tests/unit/hn-client.test.ts"
)
# Step 2: Verify all tests FAIL (TDD requirement)
npm test # Should fail
# Step 3: Implement tools (can be parallel if multiple devs)
parallel_tasks=(
"T028: Implement search_stories in src/tools/search-stories.ts"
"T029: Implement search_by_date in src/tools/search-by-date.ts"
"T030: Implement search_comments in src/tools/search-comments.ts"
)
# Step 4: Verify all tests PASS
npm test # Should pass
# Step 5: Register tools (sequential - same file)
# T031: Update src/index.ts
# Step 6: Write documentation in parallel
parallel_tasks=(
"T032: Document search_stories in docs/tools/search-stories.md"
"T033: Document search_by_date in docs/tools/search-by-date.md"
"T034: Document search_comments in docs/tools/search-comments.md"
)
# Step 7: Quality gates (sequential checks)
# T035: Verify all quality gates
```
---
## Implementation Strategy
### MVP First (User Story 1 Only) - Recommended for Initial Development
**Goal**: Get core search functionality working and testable ASAP
1. **Complete Phase 1: Setup** (~2 hours)
- T001-T007: Project structure, dependencies, tooling
2. **Complete Phase 2: Foundational** (~1 day)
- T008-T020: Core infrastructure (types, errors, rate limiter, HN client, server setup)
- **GATE**: Foundation must be complete and tested before proceeding
3. **Complete Phase 3: User Story 1** (~1 day)
- T021-T027: Write tests first (TDD)
- T028-T031: Implement search tools
- T032-T035: Document and verify
- **GATE**: Test US1 independently - can search HN, get results, handle errors
4. **Validate MVP** (~1 hour)
- Follow quickstart.md
- Test in Claude Desktop
- Verify all acceptance scenarios from spec.md US1
- Demo to stakeholders
5. **Decision Point**: Ship MVP or continue to US2+
**Total MVP Time**: ~2.5 days
**Deliverable**: Working MCP server with 3 search tools
### Incremental Delivery (After MVP)
**Advantage**: Each story adds value without breaking previous functionality
1. **Add User Story 2** (~0.5 day)
- T036-T053: Tests, implementation, docs for front page/latest/Ask HN/Show HN tools
- **GATE**: Test US1 still works, US2 works independently
- **Deliverable**: 7 tools total
2. **Add User Story 3** (~0.5 day)
- T054-T067: Tests, implementation, docs for get_story/get_user tools
- **GATE**: Test US1, US2, US3 all work independently
- **Deliverable**: 9 tools total (all tools from spec!)
3. **Add User Story 4** (~0.25 day)
- T068-T076: Tests and documentation for advanced features
- **GATE**: Verify complex filters and pagination work
- **Deliverable**: Full-featured server with advanced capabilities
4. **Polish & Release** (~0.5 day)
- T077-T094: Documentation, monitoring, final quality checks
- **Deliverable**: Production-ready v1.0.0
**Total Time (Sequential)**: ~4 days
**Total Time (Parallel with 2-3 devs)**: ~3 days
### Parallel Team Strategy
If you have 2-4 developers available:
**Phase 1 & 2**: Entire team works together (critical path)
- Pair on foundation setup
- Code review on core infrastructure
**Phase 3-6**: Divide user stories
- **Developer A**: User Story 1 (search) - highest priority
- **Developer B**: User Story 2 (listings) - can start after Foundation
- **Developer C**: User Story 3 (items/users) - can start after Foundation
- **Developer D**: User Story 4 (advanced) - depends on US1 completion
**Integration**: Each developer tests their story independently, then test together
**Phase 7**: Entire team collaborates on polish and docs
**Benefits**:
- Faster time to full feature set (~3 days vs ~4 days)
- Built-in code review (developers review each other's stories)
- Knowledge sharing (each dev becomes expert in their story domain)
---
## Summary
**Total Tasks**: 94 tasks
- Phase 1 (Setup): 7 tasks (~2 hours)
- Phase 2 (Foundational): 13 tasks (~1 day) **[BLOCKING]**
- Phase 3 (User Story 1): 15 tasks (~1 day) - **MVP**
- Phase 4 (User Story 2): 18 tasks (~0.5 day)
- Phase 5 (User Story 3): 14 tasks (~0.5 day)
- Phase 6 (User Story 4): 9 tasks (~0.25 day)
- Phase 7 (Polish): 18 tasks (~0.5 day)
**Task Count Per User Story**:
- User Story 1 (Search): 15 tasks (tests: 7, implementation: 5, docs: 3)
- User Story 2 (Listings): 18 tasks (tests: 8, implementation: 5, docs: 5)
- User Story 3 (Items/Users): 14 tasks (tests: 6, implementation: 5, docs: 3)
- User Story 4 (Advanced): 9 tasks (tests: 4, implementation: 0, docs: 5)
**Parallel Opportunities**: 52 tasks marked [P] can run in parallel with others
- Setup phase: 5 parallel tasks
- Foundational phase: 8 parallel tasks across 4 groups
- User Story 1: 10 parallel tasks (7 tests + 3 docs)
- User Story 2: 12 parallel tasks (8 tests + 4 docs)
- User Story 3: 8 parallel tasks (6 tests + 2 docs)
- User Story 4: 7 parallel tasks (4 tests + 3 docs)
- Polish phase: 8 parallel tasks
**Independent Test Criteria**:
- **User Story 1**: Run search_stories with query "AI" → get relevant results
- **User Story 2**: Run get_front_page → compare with HN homepage (match top 5)
- **User Story 3**: Run get_story(8863) → get story with comments; run get_user("pg") → get profile
- **User Story 4**: Run search_stories with numericFilters="points>=100" → all results have points>=100
**Suggested MVP Scope**: User Story 1 only (search functionality)
- Delivers core value (search HN programmatically)
- Fastest path to working product (~2.5 days)
- Independently testable and demonstrable
- Foundation for all other stories
**Estimated Total Time**:
- Sequential implementation: ~4 days
- Parallel implementation (2-3 devs): ~3 days
- MVP only (US1): ~2.5 days
**Constitution Compliance**:
- ✅ Code Quality First: Biome linting, TypeScript strict mode, zero warnings
- ✅ Test-First Development: TDD approach enforced (write tests, fail, implement, pass)
- ✅ UX Consistency: MCP naming conventions, consistent parameters, clear errors
- ✅ Latest Dependencies: Context7 research, latest stable versions
- ✅ Documentation-Driven: Specs first, API docs complete, examples provided
- ✅ Integration Testing: Real API tests, contract validation, error scenarios
- ✅ Observability: Structured logging, error context, performance metrics
All tasks are immediately executable by an LLM - each task has specific file paths, clear acceptance criteria, and sufficient context.