Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,31 @@ mypy mcp_nixos/

## Testing Approach

- 367+ async tests using pytest-asyncio
- 334+ async tests using pytest-asyncio (89% coverage)
- Real API calls (no mocks) for integration tests
- Unit tests marked with `@pytest.mark.unit`
- Integration tests marked with `@pytest.mark.integration`
- Tests ensure plain text output (no XML/JSON leakage)
- Comprehensive test coverage including:
- Search relevance fixes (darwin_search dock prioritization)
- Enhanced Home Manager option display
- Error handling edge cases
- AI usability evaluations

## Code Quality Commands

When making changes, always run:
```bash
# Lint and format
ruff check mcp_nixos/ --fix
ruff format mcp_nixos/

# Run tests
pytest tests/

# Type check (note: some type issues are known and non-critical)
mypy mcp_nixos/
```

## Local Development with MCP Clients

Expand Down Expand Up @@ -95,12 +115,21 @@ Create `.mcp.json` in project root (already gitignored):

2. **Error Handling**: All tools return helpful plain text error messages. API failures gracefully degrade with user-friendly messages.

3. **No Caching**: Version 1.0+ removed all caching for simplicity. All queries hit live APIs.
3. **No Caching**: Version 1.0+ removed all caching for simplicity. All queries hit live APIs. **IMPORTANT**: Never implement caching for external services like NixHub - this is over-engineering for an MCP server. Always prefer simple, direct API calls.

4. **Async Everything**: Version 1.0.1 migrated to FastMCP 2.x. All tools are async functions.

5. **Plain Text Output**: All responses are formatted as human-readable plain text. Never return raw JSON or XML to users.

6. **Keep It Simple**: This is an MCP server, not a web application. Avoid over-engineering solutions like:
- Caching layers for external APIs
- Complex retry mechanisms with backoff
- Database storage
- Background workers or queues
- Complicated state management

Always prefer simple, direct implementations that are easy to understand and maintain.

## CI/CD Workflows

- **CI**: Runs on all PRs - tests (unit + integration), linting, type checking
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ nix profile install github:utensils/mcp-nixos
- **Deduped flake results** - No more duplicate spam
- **Version-aware searches** - Find that old Ruby version you need
- **Category browsing** - Explore options systematically
- **Search relevance fixes** - Darwin dock searches now find dock, not Docker (revolutionary!)
- **Enhanced Home Manager display** - Now shows default values like a proper tool

## For Developers (The Brave Ones)

Expand Down Expand Up @@ -205,11 +207,12 @@ twine upload dist/* # Upload to PyPI
```

### Testing Philosophy
- **367 tests** that actually test things (now async because why not)
- **334 tests** that actually test things (now async because why not)
- **89% coverage** because perfection is overrated (but we're close)
- **Real API calls** because mocks are for cowards (await real_courage())
- **Plain text validation** ensuring no XML leaks through
- **Cross-platform tests** because Windows users deserve pain too
- **15 test files** down from 29 because organization is a virtue
- **19 test files** perfectly organized because naming things is half the battle

## Environment Variables

Expand Down
38 changes: 38 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Codecov configuration
# https://docs.codecov.com/docs/codecovyml-reference

coverage:
status:
project:
default:
target: 85%
threshold: 1%
paths:
- "mcp_nixos/"
patch:
default:
target: 85%
threshold: 1%

parsers:
gcov:
branch_detection:
conditional: yes
loop: yes
method: no
macro: no

comment:
layout: "reach,diff,flags,files,footer"
behavior: default
require_changes: false
require_base: yes
require_head: yes

ignore:
- "tests/**"
- "setup.py"
- "**/__pycache__/**"
- "**/*.egg-info/**"
- "website/**"
- "docs/**"
Loading
Loading