imbi-mcp 0.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,95 @@
1
+ name: "Build and Publish Docker Image"
2
+ on:
3
+ release:
4
+ types: [published]
5
+
6
+ permissions:
7
+ attestations: write
8
+ contents: write
9
+ id-token: write
10
+ packages: write
11
+
12
+ jobs:
13
+ build-python-package:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v5
17
+
18
+ - name: Install uv
19
+ uses: astral-sh/setup-uv@v7
20
+ with:
21
+ enable-cache: true
22
+
23
+ - name: Build python package
24
+ run: uv build
25
+
26
+ - name: Upload build artifacts
27
+ uses: actions/upload-artifact@v6
28
+ with:
29
+ name: python-distributions
30
+ path: dist/*
31
+
32
+ - name: Attach distributions
33
+ env:
34
+ GH_TOKEN: ${{ github.token }}
35
+ RELEASE_TAG: ${{ github.event.release.tag_name }}
36
+ run: |
37
+ tag="$RELEASE_TAG"
38
+ existing=$(gh release view "$tag" --json assets --jq '.assets[].name')
39
+ for file in dist/*.whl dist/*.tar.gz; do
40
+ name=$(basename "$file")
41
+ if echo "$existing" | grep -Fxq "$name"; then
42
+ echo "Asset exists, skipping: $name"
43
+ else
44
+ gh release upload "$tag" "$file"
45
+ fi
46
+ done
47
+
48
+ build-and-publish-docker:
49
+ runs-on: ubuntu-latest
50
+ needs: build-python-package
51
+ steps:
52
+ - uses: actions/checkout@v5
53
+
54
+ - name: Download python distributions
55
+ uses: actions/download-artifact@v6
56
+ with:
57
+ name: python-distributions
58
+ path: dist
59
+
60
+ - uses: docker/setup-qemu-action@v3
61
+
62
+ - uses: docker/setup-buildx-action@v3
63
+
64
+ - name: Log in to ghcr.io
65
+ uses: docker/login-action@v3
66
+ with:
67
+ registry: ghcr.io
68
+ username: ${{ github.actor }}
69
+ password: ${{ secrets.GITHUB_TOKEN }}
70
+
71
+ - id: meta
72
+ uses: docker/metadata-action@v5
73
+ with:
74
+ images: ghcr.io/${{ github.repository }}
75
+ tags: |
76
+ type=semver,pattern={{version}}
77
+ type=semver,pattern={{major}}.{{minor}}
78
+ type=semver,pattern={{major}}
79
+
80
+ - id: build
81
+ uses: docker/build-push-action@v6
82
+ with:
83
+ context: .
84
+ platforms: linux/amd64,linux/arm64
85
+ push: true
86
+ tags: ${{ steps.meta.outputs.tags }}
87
+ labels: ${{ steps.meta.outputs.labels }}
88
+ cache-from: type=gha
89
+ cache-to: type=gha,mode=max
90
+
91
+ - uses: actions/attest-build-provenance@v3
92
+ with:
93
+ subject-name: ghcr.io/${{ github.repository }}
94
+ subject-digest: ${{ steps.build.outputs.digest }}
95
+ push-to-registry: true
@@ -0,0 +1,45 @@
1
+ name: Publish to PyPI
2
+ on:
3
+ release:
4
+ types: [published]
5
+
6
+ permissions:
7
+ id-token: write
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout repository
14
+ uses: actions/checkout@v6
15
+ with:
16
+ fetch-depth: 0
17
+
18
+ - name: Install uv
19
+ uses: astral-sh/setup-uv@v5
20
+
21
+ - name: Set up Python
22
+ run: uv python install 3.14
23
+
24
+ - name: Build
25
+ run: uv build
26
+
27
+ - name: Upload dist
28
+ uses: actions/upload-artifact@v4
29
+ with:
30
+ name: dist
31
+ path: dist/
32
+
33
+ publish:
34
+ needs: build
35
+ runs-on: ubuntu-latest
36
+ environment: pypi
37
+ steps:
38
+ - name: Download dist
39
+ uses: actions/download-artifact@v4
40
+ with:
41
+ name: dist
42
+ path: dist/
43
+
44
+ - name: Publish package
45
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,50 @@
1
+ name: "Run Tests"
2
+ on:
3
+ push:
4
+ branches: [ main ]
5
+ pull_request:
6
+ branches: [ main ]
7
+
8
+ jobs:
9
+ lint:
10
+ name: "Static Analysis"
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout repository
14
+ uses: actions/checkout@v5
15
+ - name: Install just
16
+ uses: extractions/setup-just@v2
17
+ - name: Install uv
18
+ uses: astral-sh/setup-uv@v7
19
+ with:
20
+ enable-cache: true
21
+ - name: Run lint checks
22
+ run: just lint
23
+
24
+ test:
25
+ name: "Automated Tests"
26
+ runs-on: ubuntu-latest
27
+ strategy:
28
+ fail-fast: false
29
+ matrix:
30
+ python: [ "3.14" ]
31
+ steps:
32
+ - name: Checkout repository
33
+ uses: actions/checkout@v5
34
+ - name: Install just
35
+ uses: extractions/setup-just@v2
36
+ - name: Install uv
37
+ uses: astral-sh/setup-uv@v7
38
+ with:
39
+ enable-cache: true
40
+ python-version: ${{ matrix.python }}
41
+ - name: Run tests
42
+ env:
43
+ UV_FROZEN: "1"
44
+ run: just test
45
+ - name: Upload coverage reports
46
+ uses: codecov/codecov-action@v5
47
+ with:
48
+ token: ${{ secrets.CODECOV_TOKEN }}
49
+ files: "build/coverage.xml"
50
+ flags: unittests
@@ -0,0 +1,8 @@
1
+ .*
2
+ !/.coderabbit.yaml
3
+ !/.github
4
+ !/.gitignore
5
+ !/.pre-commit-config.yaml
6
+ !/.python-version
7
+ /build
8
+ /dist
@@ -0,0 +1,22 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v6.0.0 # unrelated to the pre-commit utility version
4
+ hooks:
5
+ - id: check-executables-have-shebangs
6
+ - id: check-json
7
+ - id: check-shebang-scripts-are-executable
8
+ - id: check-toml
9
+ - id: check-yaml
10
+ - id: end-of-file-fixer
11
+ - id: mixed-line-ending
12
+ - id: trailing-whitespace
13
+ - repo: https://github.com/astral-sh/ruff-pre-commit
14
+ rev: v0.15.0
15
+ hooks:
16
+ - id: ruff-check
17
+ args: [--fix]
18
+ - id: ruff-format
19
+ - repo: https://github.com/tombi-toml/tombi-pre-commit
20
+ rev: v0.7.27
21
+ hooks:
22
+ - id: tombi-format
@@ -0,0 +1 @@
1
+ 3.14
@@ -0,0 +1,75 @@
1
+ # Agent Instructions for imbi-mcp
2
+
3
+ ## Project Overview
4
+
5
+ imbi-mcp is an MCP (Model Context Protocol) server that auto-generates tools
6
+ and resources from the imbi-api OpenAPI specification. It acts as a bridge
7
+ between AI agents and the Imbi DevOps service management platform.
8
+
9
+ ## Architecture
10
+
11
+ ```
12
+ AI Agent ──MCP──► imbi-mcp ──HTTP──► imbi-api ──► Neo4j / ClickHouse
13
+ ```
14
+
15
+ - `src/imbi_mcp/server.py` -- Core server logic. Fetches the OpenAPI spec
16
+ from imbi-api at startup and generates MCP tools/resources via FastMCP.
17
+ Route maps control which endpoints are exposed and how they are classified.
18
+ - `src/imbi_mcp/app.py` -- Typer CLI entry point. The `serve` command
19
+ creates the server and starts it on the configured transport.
20
+ - `src/imbi_mcp/__init__.py` -- Package version from installed metadata.
21
+
22
+ ## Key Design Decisions
23
+
24
+ - The server requires a running imbi-api instance at startup to fetch the
25
+ OpenAPI spec. If the API is unreachable, startup fails with a clear error.
26
+ - Auth is forwarded transparently: the MCP caller's `Authorization` header
27
+ is injected into every request to imbi-api via an httpx event hook.
28
+ - Route maps are evaluated in order (first match wins). Exclusions come
29
+ before semantic mappings.
30
+
31
+ ## Code Standards
32
+
33
+ - **Line length**: 79 characters
34
+ - **Quotes**: Single quotes for strings, double quotes for docstrings
35
+ - **Type checking**: basedpyright strict mode + mypy strict mode
36
+ - **Testing**: unittest, 90% minimum coverage
37
+ - **Imports**: Prefer module imports (`from unittest import mock`)
38
+ over object imports (`from unittest.mock import patch`)
39
+ - **Logging**: Use `%s` formatting, not f-strings
40
+ - **Async**: All I/O in production code must be async
41
+
42
+ ## Development Commands
43
+
44
+ ```bash
45
+ just setup # Install dependencies and pre-commit hooks
46
+ just test # Run pytest with coverage
47
+ just lint # Run pre-commit, basedpyright, mypy
48
+ just format # Auto-format with ruff and tombi
49
+ ```
50
+
51
+ ## Testing
52
+
53
+ Tests use `unittest.TestCase` and `unittest.IsolatedAsyncioTestCase`.
54
+ All external I/O (httpx calls, FastMCP context) is mocked.
55
+
56
+ ```bash
57
+ uv run pytest # Run all tests
58
+ uv run pytest tests/test_server.py # Run specific test file
59
+ ```
60
+
61
+ ## CI/CD
62
+
63
+ GitHub Actions runs on Python 3.12, 3.13, and 3.14:
64
+ - **Static Analysis**: pre-commit hooks + basedpyright
65
+ - **Automated Tests**: pytest with coverage reporting
66
+
67
+ ## Dependencies
68
+
69
+ - **fastmcp** -- MCP server framework with OpenAPI auto-generation
70
+ - **httpx** -- Async HTTP client for API communication
71
+ - **imbi-common** -- Shared models and utilities (installed from git)
72
+ - **typer** -- CLI framework (via fastmcp dependency)
73
+
74
+ Manage dependencies with `uv`. After changing `pyproject.toml`, run
75
+ `uv lock` to update the lock file.
@@ -0,0 +1,24 @@
1
+ FROM python:3.14-slim AS builder
2
+
3
+ WORKDIR /tmp/install
4
+
5
+ RUN pip install uv \
6
+ && apt update \
7
+ && apt install git --yes
8
+
9
+ COPY dist/*.whl pyproject.toml uv.lock /tmp/install/
10
+
11
+ RUN uv venv /app \
12
+ && . /app/bin/activate \
13
+ && uv sync --no-dev --active --frozen --no-install-project \
14
+ && uv pip install *.whl
15
+
16
+ FROM python:3.14-slim AS service
17
+ EXPOSE 8001
18
+ ENV PATH="/app/bin:$PATH"
19
+ WORKDIR /app
20
+ COPY --from=builder /app/ /app/
21
+ RUN useradd -r -g users imbi \
22
+ && chown -R imbi /app
23
+ USER imbi
24
+ CMD ["/app/bin/imbi-mcp", "serve", "--transport", "streamable-http", "--host", "0.0.0.0"]
imbi_mcp-0.0.0/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2025, Gavin M. Roy
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,89 @@
1
+ Metadata-Version: 2.4
2
+ Name: imbi-mcp
3
+ Version: 0.0.0
4
+ Summary: Imbi MCP server
5
+ Author-email: "Gavin M. Roy" <gavinr@aweber.com>
6
+ License-Expression: BSD-3-Clause
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.14
9
+ Requires-Dist: fastmcp>=2.0.0
10
+ Requires-Dist: httpx>=0.28.1
11
+ Requires-Dist: imbi-common
12
+ Requires-Dist: pydantic~=2.12
13
+ Description-Content-Type: text/markdown
14
+
15
+ # imbi-mcp
16
+
17
+ MCP server for the [Imbi](https://github.com/AWeber-Imbi/imbi) DevOps service
18
+ management platform. Exposes Imbi API functionality to AI agents via the
19
+ [Model Context Protocol](https://modelcontextprotocol.io/).
20
+
21
+ ## How It Works
22
+
23
+ At startup the server fetches the OpenAPI spec from a running
24
+ [imbi-api](https://github.com/AWeber-Imbi/imbi-api) instance and
25
+ auto-generates MCP tools, resources, and resource templates using
26
+ [FastMCP](https://github.com/jlowin/fastmcp).
27
+
28
+ Route mapping rules control what gets exposed:
29
+
30
+ - **Excluded** -- Auth, MFA, status, and thumbnail endpoints are hidden.
31
+ - **Resources** -- `GET` endpoints that return collections.
32
+ - **Resource templates** -- `GET` endpoints with path parameters.
33
+ - **Tools** -- Everything else (create, update, delete operations).
34
+
35
+ The caller's `Authorization` header is forwarded to the API so that
36
+ requests run with the caller's permissions.
37
+
38
+ ## Requirements
39
+
40
+ - Python 3.12+
41
+ - A running imbi-api instance
42
+
43
+ ## Quick Start
44
+
45
+ ```bash
46
+ # Install dependencies
47
+ just setup
48
+
49
+ # Run the server (imbi-api must be reachable)
50
+ just serve
51
+
52
+ # Or with explicit options
53
+ imbi-mcp serve --api-url http://localhost:8000 --transport streamable-http
54
+ ```
55
+
56
+ ## CLI Options
57
+
58
+ ```
59
+ imbi-mcp serve [OPTIONS]
60
+ ```
61
+
62
+ | Option | Default | Env Var | Description |
63
+ | --------------- | ------------------------ | -------------- | ------------------------ |
64
+ | `--api-url` | `http://localhost:8000` | `IMBI_INTERNAL_API_URL` | Base URL of the Imbi API |
65
+ | `--transport` | `streamable-http` | | MCP transport type |
66
+ | `--host` | `127.0.0.1` | | Host to bind to |
67
+ | `--port` | `8001` | | Port to bind to |
68
+
69
+ Supported transports: `stdio`, `http`, `sse`, `streamable-http`
70
+
71
+ ## Docker
72
+
73
+ ```bash
74
+ docker build -t imbi-mcp .
75
+ docker run -p 8001:8001 -e IMBI_INTERNAL_API_URL=http://imbi-api:8000 imbi-mcp
76
+ ```
77
+
78
+ ## Development
79
+
80
+ ```bash
81
+ just setup # Install deps and pre-commit hooks
82
+ just test # Run tests (90% coverage minimum)
83
+ just lint # Run ruff, basedpyright, mypy
84
+ just format # Auto-format code
85
+ ```
86
+
87
+ ## License
88
+
89
+ BSD-3-Clause
@@ -0,0 +1,75 @@
1
+ # imbi-mcp
2
+
3
+ MCP server for the [Imbi](https://github.com/AWeber-Imbi/imbi) DevOps service
4
+ management platform. Exposes Imbi API functionality to AI agents via the
5
+ [Model Context Protocol](https://modelcontextprotocol.io/).
6
+
7
+ ## How It Works
8
+
9
+ At startup the server fetches the OpenAPI spec from a running
10
+ [imbi-api](https://github.com/AWeber-Imbi/imbi-api) instance and
11
+ auto-generates MCP tools, resources, and resource templates using
12
+ [FastMCP](https://github.com/jlowin/fastmcp).
13
+
14
+ Route mapping rules control what gets exposed:
15
+
16
+ - **Excluded** -- Auth, MFA, status, and thumbnail endpoints are hidden.
17
+ - **Resources** -- `GET` endpoints that return collections.
18
+ - **Resource templates** -- `GET` endpoints with path parameters.
19
+ - **Tools** -- Everything else (create, update, delete operations).
20
+
21
+ The caller's `Authorization` header is forwarded to the API so that
22
+ requests run with the caller's permissions.
23
+
24
+ ## Requirements
25
+
26
+ - Python 3.12+
27
+ - A running imbi-api instance
28
+
29
+ ## Quick Start
30
+
31
+ ```bash
32
+ # Install dependencies
33
+ just setup
34
+
35
+ # Run the server (imbi-api must be reachable)
36
+ just serve
37
+
38
+ # Or with explicit options
39
+ imbi-mcp serve --api-url http://localhost:8000 --transport streamable-http
40
+ ```
41
+
42
+ ## CLI Options
43
+
44
+ ```
45
+ imbi-mcp serve [OPTIONS]
46
+ ```
47
+
48
+ | Option | Default | Env Var | Description |
49
+ | --------------- | ------------------------ | -------------- | ------------------------ |
50
+ | `--api-url` | `http://localhost:8000` | `IMBI_INTERNAL_API_URL` | Base URL of the Imbi API |
51
+ | `--transport` | `streamable-http` | | MCP transport type |
52
+ | `--host` | `127.0.0.1` | | Host to bind to |
53
+ | `--port` | `8001` | | Port to bind to |
54
+
55
+ Supported transports: `stdio`, `http`, `sse`, `streamable-http`
56
+
57
+ ## Docker
58
+
59
+ ```bash
60
+ docker build -t imbi-mcp .
61
+ docker run -p 8001:8001 -e IMBI_INTERNAL_API_URL=http://imbi-api:8000 imbi-mcp
62
+ ```
63
+
64
+ ## Development
65
+
66
+ ```bash
67
+ just setup # Install deps and pre-commit hooks
68
+ just test # Run tests (90% coverage minimum)
69
+ just lint # Run ruff, basedpyright, mypy
70
+ just format # Auto-format code
71
+ ```
72
+
73
+ ## License
74
+
75
+ BSD-3-Clause
@@ -0,0 +1,51 @@
1
+ [doc("Bootstrap the environment and run the MCP server")]
2
+ [group("Testing")]
3
+ serve *ARGS: setup
4
+ -uv run --env-file=.env imbi-mcp serve {{ ARGS }}
5
+
6
+ [default]
7
+ [private]
8
+ ci: lint test
9
+
10
+ [doc("Set up your development environment")]
11
+ [group("Environment")]
12
+ setup:
13
+ uv sync --all-groups --all-extras --frozen
14
+ uv run pre-commit install --install-hooks --overwrite
15
+
16
+ [doc("Run tests")]
17
+ [group("Testing")]
18
+ test: setup
19
+ uv run pytest
20
+
21
+ [doc("Run linters")]
22
+ [group("Testing")]
23
+ lint: setup
24
+ uv run pre-commit run --all-files
25
+ uv run basedpyright
26
+ uv run mypy
27
+
28
+ [doc("Reformat code (optionally pass specific files)")]
29
+ [group("Development")]
30
+ format *FILES: setup
31
+ #!/usr/bin/env sh
32
+ set -x
33
+ if [ "{{FILES}}" = '' ]; then
34
+ args='--all-files'
35
+ else
36
+ args='--files {{FILES}}'
37
+ fi
38
+ uv run pre-commit run ruff-format $args
39
+ uv run pre-commit run tombi-format $args
40
+
41
+ [doc("Remove runtime artifacts")]
42
+ [group("Environment")]
43
+ clean:
44
+ rm -f .coverage
45
+ rm -fR build
46
+
47
+ [confirm]
48
+ [doc("Remove caches, virtual env, and output files")]
49
+ [group("Environment")]
50
+ real-clean: clean
51
+ rm -fR .venv .*_cache dist
@@ -0,0 +1,125 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "imbi-mcp"
7
+ version = "0.0.0"
8
+ description = "Imbi MCP server"
9
+ readme = "README.md"
10
+ requires-python = ">=3.14"
11
+ license = "BSD-3-Clause"
12
+ authors = [{ name = "Gavin M. Roy", email = "gavinr@aweber.com" }]
13
+ dependencies = [
14
+ "fastmcp>=2.0.0",
15
+ "httpx>=0.28.1",
16
+ "imbi-common",
17
+ "pydantic~=2.12",
18
+ ]
19
+
20
+ [project.scripts]
21
+ imbi-mcp = "imbi_mcp.app:cli"
22
+
23
+ [dependency-groups]
24
+ dev = [
25
+ "basedpyright>=1.37.1",
26
+ "coverage[toml]>=7.13.1",
27
+ "mypy~=1.19.1",
28
+ "pre-commit>=4.5.1",
29
+ "pytest>=9.0.2",
30
+ "pytest-cov>=7.0.0",
31
+ "python-dotenv>=1.1.0",
32
+ "ruff~=0.14.6",
33
+ ]
34
+
35
+ [tool.coverage.report]
36
+ fail_under = 90
37
+ show_missing = true
38
+
39
+ [tool.coverage.run]
40
+ branch = true
41
+ source = ["src"]
42
+
43
+ [tool.mypy]
44
+ namespace_packages = true
45
+ show_error_codes = true
46
+ strict = true
47
+ packages = ["imbi_mcp", "tests"]
48
+
49
+ [tool.pyright]
50
+ deprecateTypingAliases = true
51
+ reportMissingSuperCall = "hint"
52
+ typeCheckingMode = "strict"
53
+
54
+ [[tool.pyright.executionEnvironments]]
55
+ root = "src"
56
+ reportUnusedFunction = "warning"
57
+
58
+ [[tool.pyright.executionEnvironments]]
59
+ root = "tests"
60
+ reportPrivateUsage = "none"
61
+ reportUnusedFunction = "none"
62
+ extraPaths = ["src", "."]
63
+
64
+ [tool.ruff]
65
+ line-length = 79
66
+ target-version = "py314"
67
+
68
+ [tool.ruff.format]
69
+ quote-style = "single"
70
+
71
+ [tool.ruff.lint]
72
+ select = [
73
+ "A",
74
+ "ANN",
75
+ "ARG",
76
+ "ASYNC",
77
+ "B",
78
+ "BLE",
79
+ "C4",
80
+ "C90",
81
+ "DTZ",
82
+ "E",
83
+ "ERA",
84
+ "F",
85
+ "FLY",
86
+ "FURB",
87
+ "G",
88
+ "I",
89
+ "LOG",
90
+ "N",
91
+ "PIE",
92
+ "PL",
93
+ "PTH",
94
+ "Q",
95
+ "RET",
96
+ "RSE",
97
+ "RUF",
98
+ "S",
99
+ "SIM",
100
+ "T10",
101
+ "T20",
102
+ "TC",
103
+ "TRY",
104
+ "W",
105
+ ]
106
+ ignore = [
107
+ "TRY003",
108
+ "TRY400",
109
+ ]
110
+ flake8-quotes = { inline-quotes = "single" }
111
+
112
+ [tool.pytest.ini_options]
113
+ testpaths = ["tests"]
114
+ addopts = [
115
+ "--cov=src/imbi_mcp",
116
+ "--cov-report=xml:build/coverage.xml",
117
+ "--cov-report=term",
118
+ ]
119
+
120
+ [[tool.uv.index]]
121
+ url = "https://pypi.org/simple"
122
+ default = true
123
+
124
+ [tool.uv.sources]
125
+ imbi-common = { git = "https://github.com/AWeber-Imbi/imbi-common", rev = "main" }