Contributing

Thanks for your interest in improving NovelAI Image MCP! This page covers the practical workflow. For the project’s code of conduct, see CODE_OF_CONDUCT.md.

Before you start

  1. Open an issue describing your proposed change. This is especially important for new features or API changes — we’ll discuss scope and design before you spend time on code.

  2. Check the issue tracker for related work in progress.

Development setup

git clone https://github.com/xinvxueyuan/NovelAI-Image-MCP.git
cd NovelAI-Image-MCP

# Sync the workspace virtualenv (server + docs + dev tools)
uv sync

# (Optional) Install Node-side tooling for husky + markdownlint + turbo
corepack enable pnpm
pnpm install --frozen-lockfile

The first uv sync downloads all transitive dependencies; subsequent runs are instant.

Workflow

# 1. Branch off main
git checkout -b feat/my-feature

# 2. Implement your change.
#    - Source under apps/server/src/
#    - Tests under apps/server/tests/
#    - Docs under apps/docs/source/ (if user-facing)

# 3. Run all checks locally before pushing.
uv run --directory apps/server poe check
# Equivalent to: ruff format-check + ruff check + pyright + pytest

# 4. (If you touched docs) verify the build:
uv run --package novelai-image-mcp-docs sphinx-build -b html apps/docs/source apps/docs/_build/html -W --keep-going

# 5. (If you touched markdown) verify markdownlint:
pnpm exec markdownlint-cli2

# 6. (If you touched licensing) verify REUSE compliance:
uv run reuse lint

# 7. Commit using Conventional Commits + gitmoji:
git commit -m "✨ feat: add support for V5 model ids"

# 8. Push and open a PR:
git push -u origin feat/my-feature
gh pr create --title "..." --body "..."

Pre-commit hook

If you’ve installed pnpm dependencies, a .husky/pre-commit hook runs automatically on every git commit:

  1. prek — ruff --fix, ruff-format, and general hooks (trailing-whitespace, end-of-file-fixer, etc.).

  2. markdownlint — only when .md files are staged.

  3. pyright — only when .py files are staged.

  4. pytest — only when .py files are staged (slowest phase).

If prek modifies files, the hook re-stages them and retries once. If any phase fails, the commit aborts with a clear message.

To bypass for a WIP commit (use sparingly):

git commit --no-verify -m "wip: ..."

Warning

CI runs the same checks as the hook. A --no-verify commit will still fail CI — bypass only for genuinely WIP work that you’ll rebase before opening a PR.

Coding standards

Python

  • Style: enforced by ruff (preview mode). See apps/server/pyproject.toml for the rule set. Run uv run --directory apps/server ruff format to auto-format.

  • Types: enforced by pyright (standard mode). Type-check must pass.

  • Docstrings: Google style (the project’s pydocstyle convention). Required on public APIs; optional on private helpers.

  • Imports: from __future__ import annotations is required at the top of every module (PEP 563 + Ruff TC rules).

  • Async: tools are async. Use httpx.AsyncClient for HTTP, pytest-asyncio for tests (asyncio_mode=auto).

Markdown

  • Use MyST Markdown (the docs site’s parser).

  • Line length is unlimited (MD013 disabled).

  • Headings may not end with .,;:! (MD026).

  • Inline HTML is allowed (MD033 disabled) for callouts / details.

  • Run pnpm exec markdownlint-cli2 --fix to auto-fix most issues.

Licensing

  • All files must carry SPDX license headers. REUSE.toml declares them by glob — usually you don’t need to add anything manually.

  • Run uv run reuse lint to verify compliance.

  • Software code: MIT. Documentation: MIT. Visual elements + infrastructure: CC0-1.0.

Test coverage

  • Coverage floor: 70% (enforced by --cov-fail-under=70).

  • Tests live in apps/server/tests/ and use pytest-asyncio + respx (HTTP mocking).

  • Every new public function should have at least one test.

  • Bugs should include a regression test.

See Testing for the test layout and fixture strategy.

Documentation

User-facing changes (new tool, new parameter, behavior change) must update the docs:

  • Tools → apps/docs/source/tools/<tool>.md

  • Tutorials → apps/docs/source/tutorials/<tutorial>.md

  • Configuration → apps/docs/source/configuration.md

  • API → automatically generated by sphinx.ext.autodoc from docstrings

To preview docs locally:

uv run --package novelai-image-mcp-docs sphinx-autobuild apps/docs/source apps/docs/_build/html --open-browser

Commit messages

Follow Conventional Commits + gitmoji:

<emoji> <type>: <subject>

<body>

Type

Use for

feat

New feature

fix

Bug fix

docs

Documentation only

style

Formatting, whitespace, no code change

refactor

Code restructure, no behavior change

perf

Performance improvement

test

Adding / fixing tests

build

Build system, dependencies, CI

ci

CI configuration changes

chore

Misc maintenance

Common emojis:

Emoji

Type

feat

🐛

fix

📝

docs

🎨

style

♻️

refactor

⚡️

perf

test

🏗️

build

🔧

chore

Pull request

  • One PR per logical change.

  • Title: Conventional Commit format (feat:, fix:, etc.).

  • Description: link the issue, summarize the change, list any breaking changes.

  • All CI checks must pass before merge.

  • Squash-and-merge into main (the default branch).

Reporting bugs

Open a bug report issue. Include:

  • The exact command you ran.

  • The full error output (stack trace if Python).

  • The server version (via uv run python -c "import novelai_image_mcp; print(novelai_image_mcp.__version__)").

  • Your OS, Python version, and uv version.

  • A minimal reproduction (script or steps).

Reporting security issues

Do not open a public issue for security vulnerabilities. See SECURITY.md for the private disclosure process.

See also