jumperless-mcp 0.1.0

MCP server for the Jumperless V5 — persistent USB-serial bridge exposing the firmware API to LLMs
# Contributing to jumperless-mcp


Thanks for thinking about contributing! This project is small and welcoming.
There's no formal process — issues, PRs, and questions are all good.

## Filing an issue


[github.com/LesbianVelociraptor/jumperless-mcp/issues](https://github.com/LesbianVelociraptor/jumperless-mcp/issues)

Useful info to include for bug reports:
- Output of `jumperless-mcp --version`
- Output of `jumperless-mcp firmware-probe --json`
- Your OS and version
- What you did, what you expected, what happened
- Any error messages or weird behavior

For feature requests: tell us what you're trying to do, not just what
you want added. We might already have a tool that does it, or there
might be a simpler shape we'd land on together.

## Submitting a PR


1. **Fork the repo** on GitHub and clone your fork locally.
2. **Make a branch:** `git checkout -b your-change-name`
3. **Make your changes.** Add tests if you're adding a new tool or
   changing behavior. The test pattern is in any of the existing
   `mcp/jumperless/src/tools/*.rs` modules — mock the serial port,
   feed it canned responses, assert the handler does the right thing.
4. **Run the checks locally** before pushing:
   ```bash
   cargo test --bin jumperless-mcp

   cargo fmt --all -- --check

   cargo clippy --all-targets -- -D warnings

   ```
   If any of these complain, fix them. The CI workflow runs the same
   three commands and will block your PR if they fail.
5. **Push to your fork** and open a PR against `main`.

## Code style


- **Rust:** `cargo fmt` for formatting, `clippy` clean (no warnings).
- **Tool naming:** bare names per the spec (`get_state`, `dac_set`, etc.).
  The federation gateway adds the `jumperless.` prefix when needed.
- **Each tool family in its own module:** `src/tools/<family>.rs` with
  `descriptors()` + `handle_*` functions. See existing modules for the
  pattern.
- **Errors:** use `McpError::Protocol(format!(...))` — propagate, don't swallow.
- **Validation BEFORE device contact:** if an argument is bad, return `Err`
  before writing any bytes to the serial port. Tests should assert
  `port.write_data.is_empty()` on rejection paths.

## Commit messages


Plain English imperative-mood summaries. Examples:

- `Add wavegen_set_phase tool`
- `Fix is_connected returning string instead of bool`
- `Document the firmware probe subcommand`

You don't need conventional-commits (`feat:` / `fix:` prefixes), but it's
fine if you prefer that style.

## Questions


If you're not sure whether something belongs as an issue, a PR, or just
a question, file it as an issue and we'll figure it out together. There's
no bad question; this is a small project and we want it to be approachable.

## License


By contributing, you agree that your contributions are licensed under
the MIT license (same as the project itself).