CONTRIBUTING.md•13.3 kB
# Contributing to HackerNews MCP Server
Thank you for your interest in contributing! This document provides guidelines and instructions for contributing to the project.
## Table of Contents
- [Code of Conduct](#code-of-conduct)
- [Getting Started](#getting-started)
- [Development Setup](#development-setup)
- [Project Structure](#project-structure)
- [Development Workflow](#development-workflow)
- [Testing](#testing)
- [Code Style](#code-style)
- [Commit Guidelines](#commit-guidelines)
- [Pull Request Process](#pull-request-process)
- [Issue Guidelines](#issue-guidelines)
---
## Code of Conduct
This project follows a Code of Conduct to ensure a welcoming and inclusive environment:
- **Be respectful**: Treat all contributors with respect
- **Be constructive**: Provide helpful feedback
- **Be collaborative**: Work together towards common goals
- **Be inclusive**: Welcome diverse perspectives
---
## Getting Started
### Prerequisites
- **Node.js** 18.0.0 or higher
- **npm** 9.0.0 or higher
- **Git** for version control
- **VS Code** (recommended) or your preferred editor
### Fork and Clone
1. **Fork** the repository on GitHub
2. **Clone** your fork locally:
```bash
git clone https://github.com/YOUR-USERNAME/hn-mcp-server.git
cd hn-mcp-server
```
3. **Add upstream** remote:
```bash
git remote add upstream https://github.com/ORIGINAL-OWNER/hn-mcp-server.git
```
---
## Development Setup
### Install Dependencies
```bash
npm install
```
### Build the Project
```bash
npm run build
```
### Run Tests
```bash
# Run all tests
npm test
# Run with coverage
npm run test:coverage
# Run in watch mode
npm test -- --watch
# Run specific test file
npm test -- search-posts
```
### Lint and Format
```bash
# Check code quality
npm run lint
# Fix linting issues
npm run lint:fix
# Format code
npm run format
# Check formatting without changes
npm run format:check
```
### Development Mode
```bash
# Watch for changes and rebuild
npm run dev
```
---
## Project Structure
```
hn-mcp-server/
├── src/
│ ├── index.ts # Main entry point
│ ├── tools/ # Tool implementations
│ │ ├── search-posts.ts
│ │ ├── get-front-page.ts
│ │ ├── get-latest-posts.ts
│ │ ├── get-item.ts
│ │ └── get-user.ts
│ ├── services/ # Business logic
│ │ └── hn-api.ts
│ ├── types/ # Type definitions
│ │ ├── hn-types.ts
│ │ ├── mcp-types.ts
│ │ └── index.ts
│ └── utils/ # Utilities
│ ├── validators.ts
│ └── error-handlers.ts
├── tests/
│ ├── unit/ # Unit tests
│ ├── integration/ # Integration tests
│ └── contract/ # Contract tests
├── docs/ # Documentation
│ ├── API.md
│ ├── ARCHITECTURE.md
│ └── CONTRIBUTING.md
├── dist/ # Build output (gitignored)
├── package.json
├── tsconfig.json
├── biome.json
└── vitest.config.ts
```
---
## Development Workflow
### 1. Create a Branch
```bash
git checkout -b feature/your-feature-name
# or
git checkout -b fix/your-bug-fix
```
**Branch naming**:
- `feature/` - New features
- `fix/` - Bug fixes
- `docs/` - Documentation updates
- `refactor/` - Code refactoring
- `test/` - Test additions/improvements
### 2. Make Changes
- Write code following project conventions
- Add/update tests for your changes
- Update documentation if needed
- Ensure tests pass: `npm test`
- Ensure code is formatted: `npm run format`
### 3. Commit Changes
```bash
git add .
git commit -m "type(scope): description"
```
See [Commit Guidelines](#commit-guidelines) for format.
### 4. Sync with Upstream
```bash
git fetch upstream
git rebase upstream/main
```
### 5. Push to Your Fork
```bash
git push origin feature/your-feature-name
```
### 6. Create Pull Request
- Go to GitHub and create a Pull Request
- Fill out the PR template
- Link related issues
- Wait for review
---
## Testing
### Test Organization
**Unit Tests** (`tests/unit/`):
- Test pure functions
- No I/O operations
- Fast execution
- Mock external dependencies
**Integration Tests** (`tests/integration/`):
- Test with real API calls
- End-to-end tool testing
- Slower execution
- Use live HackerNews API
**Contract Tests** (`tests/contract/`):
- Validate input/output schemas
- Ensure MCP protocol compliance
- Zod schema validation
### Writing Tests
#### Unit Test Example
```typescript
import { describe, it, expect } from 'vitest';
import { validateInput, SearchPostsInputSchema } from '../src/utils/validators';
describe('SearchPostsInputSchema', () => {
it('should validate correct input', () => {
const input = { query: 'AI', page: 0, hitsPerPage: 20 };
const result = validateInput(SearchPostsInputSchema, input);
expect(result).toEqual(input);
});
it('should reject empty query', () => {
const input = { query: '' };
expect(() => validateInput(SearchPostsInputSchema, input))
.toThrow('query must contain at least 1 character');
});
});
```
#### Integration Test Example
```typescript
import { describe, it, expect } from 'vitest';
import { searchPostsTool } from '../src/tools/search-posts';
describe('search-posts tool', () => {
it('should return results for valid query', async () => {
const result = await searchPostsTool({ query: 'AI', hitsPerPage: 5 });
expect(result.isError).toBe(false);
expect(result.content[0].type).toBe('text');
const data = JSON.parse(result.content[0].text);
expect(data.hits).toBeDefined();
expect(Array.isArray(data.hits)).toBe(true);
});
});
```
### Test Coverage
- **Minimum**: 80% overall coverage (project requirement)
- **Target**:
- Validators: 100%
- Error handlers: 100%
- API client: 90%+
- Tools: 85%+
**Check coverage**:
```bash
npm run test:coverage
```
---
## Code Style
### TypeScript Guidelines
**Strict Mode**:
- Always enabled in `tsconfig.json`
- No `any` types without justification
- Explicit return types on public functions
- Proper null/undefined handling
**Example**:
```typescript
// ✅ Good
export async function getTool(id: string): Promise<ToolResult> {
const result = await api.fetch(id);
return createSuccessResult(result);
}
// ❌ Bad
export async function getTool(id) {
const result = await api.fetch(id);
return result;
}
```
### Formatting
**Biome Configuration** (`biome.json`):
- Tabs for indentation
- Line width: 100 characters
- Double quotes for strings
- Trailing commas (ES5)
**Auto-format**:
```bash
npm run format
```
### Naming Conventions
- **Files**: `kebab-case.ts` (e.g., `search-posts.ts`)
- **Classes**: `PascalCase` (e.g., `HNAPIClient`)
- **Functions**: `camelCase` (e.g., `searchPostsTool`)
- **Constants**: `UPPER_SNAKE_CASE` (e.g., `HN_API_BASE_URL`)
- **Types**: `PascalCase` (e.g., `SearchResult`)
### Documentation
**JSDoc Comments**:
```typescript
/**
* Search HackerNews by keyword
*
* @param params - Search parameters
* @returns Search results with pagination
* @throws Error on API failure
*
* @example
* ```typescript
* const results = await search({ query: 'AI', page: 0 });
* ```
*/
export async function search(params: SearchParams): Promise<SearchResult> {
// Implementation
}
```
**Required Documentation**:
- All exported functions
- Complex algorithms
- API endpoints
- Error handling strategies
---
## Commit Guidelines
### Commit Message Format
```
type(scope): subject
body (optional)
footer (optional)
```
### Types
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation changes
- `style`: Code style changes (formatting, etc.)
- `refactor`: Code refactoring
- `test`: Test additions/modifications
- `chore`: Build process, dependencies, etc.
### Scopes
- `tools`: Tool implementations
- `api`: API client
- `validators`: Input validation
- `errors`: Error handling
- `types`: Type definitions
- `tests`: Test files
- `docs`: Documentation
### Examples
```bash
feat(tools): add get-latest-posts tool
Implements the get-latest-posts tool that retrieves recent HN posts
sorted by date. Supports filtering by tags and pagination.
Closes #42
---
fix(api): handle timeout errors correctly
Previously, timeout errors were not caught properly. Now using
AbortController to handle timeouts gracefully.
---
docs(readme): update installation instructions
Added instructions for npm global install and updated examples.
---
test(validators): add edge case tests
Added tests for boundary conditions in pagination and hitsPerPage.
```
### Best Practices
- **Present tense**: "add feature" not "added feature"
- **Imperative mood**: "fix bug" not "fixes bug"
- **Lowercase**: "feat(tools)" not "Feat(tools)"
- **No period**: at end of subject line
- **50 characters**: subject line limit
- **72 characters**: body line width
- **Blank line**: between subject and body
---
## Pull Request Process
### Before Submitting
1. **Tests pass**: `npm test`
2. **No lint errors**: `npm run lint`
3. **Code formatted**: `npm run format`
4. **Coverage maintained**: `npm run test:coverage`
5. **Documentation updated**: if needed
6. **Builds successfully**: `npm run build`
### PR Template
```markdown
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Related Issues
Closes #123
## Testing
- [ ] All existing tests pass
- [ ] Added new tests for changes
- [ ] Manual testing completed
## Checklist
- [ ] Code follows project style guidelines
- [ ] Self-review completed
- [ ] Comments added for complex code
- [ ] Documentation updated
- [ ] No new warnings generated
```
### Review Process
1. **Automated Checks**: CI/CD runs tests, linting, build
2. **Code Review**: At least one maintainer reviews
3. **Feedback**: Address review comments
4. **Approval**: Required before merge
5. **Merge**: Maintainer merges to main
### Review Criteria
- Code quality and style
- Test coverage
- Documentation completeness
- Breaking change handling
- Performance implications
- Security considerations
---
## Issue Guidelines
### Creating Issues
**Bug Reports**:
```markdown
**Describe the bug**
Clear description of the bug
**To Reproduce**
Steps to reproduce:
1. Call tool '...'
2. With parameters '...'
3. See error
**Expected behavior**
What should happen
**Actual behavior**
What actually happens
**Environment**
- Node version:
- npm version:
- OS:
**Additional context**
Any other relevant information
```
**Feature Requests**:
```markdown
**Feature Description**
Clear description of the proposed feature
**Use Case**
Why is this feature needed?
**Proposed Solution**
How should it work?
**Alternatives Considered**
Other approaches you've thought about
**Additional Context**
Screenshots, examples, etc.
```
### Issue Labels
- `bug` - Something isn't working
- `enhancement` - New feature or request
- `documentation` - Documentation improvements
- `good first issue` - Good for newcomers
- `help wanted` - Extra attention needed
- `question` - Further information requested
---
## Development Tips
### Testing Individual Tools
```bash
# Test specific tool
npm test -- search-posts
# Test with coverage for one tool
npm test -- --coverage search-posts
```
### Debugging
**VS Code Launch Configuration** (`.vscode/launch.json`):
```json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug Tests",
"runtimeExecutable": "npm",
"runtimeArgs": ["test", "--", "--run"],
"console": "integratedTerminal"
}
]
}
```
### Local Testing with MCP Client
1. Build project: `npm run build`
2. Configure MCP client to use local path
3. Test tools in client
4. Check stderr logs for errors
### API Testing Without MCP
```typescript
import { searchPostsTool } from './src/tools/search-posts';
const result = await searchPostsTool({
query: 'AI',
hitsPerPage: 5
});
console.log(JSON.stringify(result, null, 2));
```
---
## Getting Help
### Resources
- **Documentation**: Check `docs/` directory
- **Issues**: Search existing issues on GitHub
- **Discussions**: GitHub Discussions for questions
- **MCP Docs**: https://modelcontextprotocol.io
- **HN API Docs**: https://hn.algolia.com/api
### Asking Questions
When asking for help, include:
- What you're trying to do
- What you've tried
- Relevant code snippets
- Error messages
- Environment details
### Community
- Be patient and respectful
- Search before asking
- Provide context and details
- Follow up on solutions
- Help others when you can
---
## Release Process
(For maintainers)
1. Update version in `package.json`
2. Update CHANGELOG.md
3. Commit: `chore: release v1.2.3`
4. Tag: `git tag v1.2.3`
5. Push: `git push --tags`
6. GitHub Actions builds and publishes
---
## License
By contributing, you agree that your contributions will be licensed under the MIT License.
---
Thank you for contributing to HackerNews MCP Server! 🎉