Building on Mirobody
Contributing
How to report issues, propose features, and land a change in the Mirobody Python engine.
Mirobody is a Python project, and contributions are welcome. This page follows the repository’s own CONTRIBUTING.md; where the two differ, the file in the repository wins.
Three areas to contribute
Section titled “Three areas to contribute”Contributions are organized around the engine’s three stages, and they differ enormously in size — start with ② if you want a first PR that lands.
| Area | What to contribute | Typical size |
|---|---|---|
| ① Collect | A new device provider: implement BasePullProvider in one mirobody_<slug>/ directory and the platform discovers it at startup. mirobody_pgsql/ is the smallest reference, mirobody_whoop/ the OAuth2 one. Or a new file format for the parser. See Building a Provider. | medium |
| ② Standardize | Make a term resolve. Find one that comes back wrong or empty — mirobody resolve "<term>" — then add one row to resolver_overrides.tsv and one case to test_engine_coverage.py. Any language. Also: unit mappings, taxonomy fixes. | tiny |
| ③ Answers | An Agent Skill (a SKILL.md directory — copy lab-report-walkthrough), an MCP tool, a chart schema. See Agent Skills and Adding Custom Tools. | medium |
A lab report that parses incorrectly, or an indicator name that fails to resolve, makes a good issue — attach a de-identified sample.
Before you write code
Section titled “Before you write code”Reporting a bug
Open a GitHub issue with a clear title and description, the steps to reproduce, and your environment details (OS, Docker version, Python version).
Suggesting a feature
Open an issue to discuss the idea before implementing it. That keeps your time well spent and the feature aligned with the project’s direction.
Development workflow
Section titled “Development workflow”Fork and clone
git clone https://github.com/YOUR_USERNAME/mirobody.gitcd mirobodyCreate a branch
git checkout -b feature/my-new-feature# orgit checkout -b fix/bug-fix-nameMake your change
Follow the surrounding code style. Everything user-extensible — tools, agents, skills, providers — is discovered at runtime from a configured directory, so adding a capability means adding a file, not editing a registry.
Test it
pip install -e '.[agents,test]'
pytest # the whole suite; tests live next to the codelint-imports # the engine/agent boundary, machine-checked'.[test]' alone is enough to work on the engine: the agent-layer tests are skipped at collection rather than aborting the run. lint-imports runs against the repository source. Details in Development Setup.
Push and open a pull request
git push origin feature/my-new-featureThen open a PR against the main branch of the upstream repository.
Coding style
Section titled “Coding style”- Python — follow PEP 8, and match the conventions of the file you’re editing.
- Documentation — update the README (or the module README next to your code) whenever you change how something works.
- Commits — write descriptive messages; one concern per commit.
- Config keys — read them through
safe_read_cfg("YOUR_KEY")rather than reaching into the environment, so overrides and automatic encryption keep working. Anything whose name contains_KEY,_PASSWORD,_PASS,_PWD,_SECRET,_SKor_TOKENis encrypted at rest. - New optional dependencies belong in an extra in
pyproject.toml(server,agents,cn,test,indicator-build), not in the base requirement list — a feature nobody enabled shouldn’t be able to breakpip install -e .. - Never import an agent framework outside
agent/orserver/.lint-importsfails the build on it, function-local imports included. The engine must import with numpy as its only third-party package.
Pull request guidelines
Section titled “Pull request guidelines”Title
A short, descriptive summary of the change. Conventional prefixes (feat:, fix:, docs:, chore:) appear in parts of the history; what the project asks for is simply that the message says what changed.
Description
- What the PR does and why
- How to run / test it
- Linked issues
Checklist
-
mirobody servestarts against a localdocker compose up -d pg redis -
pytestpasses with no database or network access, andlint-importsis clean - Touched
format_data()? The Pulse gate tests pass, and new behaviour has a fixture - New optional dependencies are behind an extra in
pyproject.toml - Docs updated if behaviour changed
License
Section titled “License”By contributing, you agree that your contributions are licensed under the project’s LICENSE.
Getting help
Section titled “Getting help”Bug reports and feature requests
Direct technical support
Thank you for contributing!