atlassian-agent-mcp 0.3.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.
Files changed (36) hide show
  1. atlassian_agent_mcp-0.3.0/.editorconfig +23 -0
  2. atlassian_agent_mcp-0.3.0/.env.example +11 -0
  3. atlassian_agent_mcp-0.3.0/.github/dependabot.yml +41 -0
  4. atlassian_agent_mcp-0.3.0/.github/workflows/ci.yml +77 -0
  5. atlassian_agent_mcp-0.3.0/.github/workflows/release.yml +116 -0
  6. atlassian_agent_mcp-0.3.0/.gitignore +218 -0
  7. atlassian_agent_mcp-0.3.0/.pre-commit-config.yaml +76 -0
  8. atlassian_agent_mcp-0.3.0/.python-version +1 -0
  9. atlassian_agent_mcp-0.3.0/AGENTS.md +315 -0
  10. atlassian_agent_mcp-0.3.0/CHANGELOG.md +162 -0
  11. atlassian_agent_mcp-0.3.0/CLAUDE.md +6 -0
  12. atlassian_agent_mcp-0.3.0/GEMINI.md +6 -0
  13. atlassian_agent_mcp-0.3.0/LICENSE +21 -0
  14. atlassian_agent_mcp-0.3.0/Makefile +83 -0
  15. atlassian_agent_mcp-0.3.0/PKG-INFO +310 -0
  16. atlassian_agent_mcp-0.3.0/README.md +281 -0
  17. atlassian_agent_mcp-0.3.0/SECURITY.md +34 -0
  18. atlassian_agent_mcp-0.3.0/docs/assets/banner-dark.svg +42 -0
  19. atlassian_agent_mcp-0.3.0/docs/assets/banner-light.svg +44 -0
  20. atlassian_agent_mcp-0.3.0/pyproject.toml +95 -0
  21. atlassian_agent_mcp-0.3.0/scripts/list_mcp_tools.py +22 -0
  22. atlassian_agent_mcp-0.3.0/scripts/run-atlassian-agent-mcp.sh +14 -0
  23. atlassian_agent_mcp-0.3.0/scripts/verify-wheel.sh +53 -0
  24. atlassian_agent_mcp-0.3.0/src/atlassian_agent/__init__.py +19 -0
  25. atlassian_agent_mcp-0.3.0/src/atlassian_agent/cli.py +148 -0
  26. atlassian_agent_mcp-0.3.0/src/atlassian_agent/common.py +23 -0
  27. atlassian_agent_mcp-0.3.0/src/atlassian_agent/confluence.py +662 -0
  28. atlassian_agent_mcp-0.3.0/src/atlassian_agent/jira.py +474 -0
  29. atlassian_agent_mcp-0.3.0/src/atlassian_agent/local_files.py +86 -0
  30. atlassian_agent_mcp-0.3.0/src/atlassian_agent/mcp_server.py +112 -0
  31. atlassian_agent_mcp-0.3.0/src/atlassian_agent/runtime.py +16 -0
  32. atlassian_agent_mcp-0.3.0/src/atlassian_agent/tools.py +67 -0
  33. atlassian_agent_mcp-0.3.0/tests/test_library_contract.py +188 -0
  34. atlassian_agent_mcp-0.3.0/tests/test_packaging.py +64 -0
  35. atlassian_agent_mcp-0.3.0/tests/test_tools.py +1217 -0
  36. atlassian_agent_mcp-0.3.0/uv.lock +2213 -0
@@ -0,0 +1,23 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ trim_trailing_whitespace = true
8
+
9
+ [*.py]
10
+ indent_style = space
11
+ indent_size = 4
12
+
13
+ [*.{yml,yaml,json,toml}]
14
+ indent_style = space
15
+ indent_size = 2
16
+
17
+ [Makefile]
18
+ indent_style = tab
19
+
20
+ [*.md]
21
+ indent_style = space
22
+ indent_size = 2
23
+ trim_trailing_whitespace = false
@@ -0,0 +1,11 @@
1
+ # Copy to .env and fill in. .env is gitignored and must never be committed.
2
+ # Both services use a personal access token, sent as:
3
+ # Authorization: Bearer <token>
4
+
5
+ # Confluence — required by the confluence_* tools.
6
+ CONFLUENCE_URL=https://confluence.example.com
7
+ CONFLUENCE_TOKEN=your-personal-access-token
8
+
9
+ # Jira — required only by the jira_* tools. Leave unset to run Confluence-only.
10
+ JIRA_URL=https://jira.example.com
11
+ JIRA_TOKEN=your-personal-access-token
@@ -0,0 +1,41 @@
1
+ ---
2
+ # Both ecosystems here exist because this repository pins things by hand and a
3
+ # hand-written pin is a pin that rots. The actions in the workflows are pinned
4
+ # to commit SHAs, which is the right thing for supply-chain reasons and also
5
+ # the reason nobody would ever notice a security fix: a SHA never moves.
6
+ version: 2
7
+
8
+ updates:
9
+ # The workflows run with this repository's token. An action pinned to a SHA
10
+ # is safe from a moved tag and blind to a patched vulnerability, so something
11
+ # has to bring the new SHA to a pull request where it can be read.
12
+ - package-ecosystem: github-actions
13
+ directory: /
14
+ schedule:
15
+ interval: weekly
16
+ commit-message:
17
+ prefix: "ci"
18
+ groups:
19
+ actions:
20
+ patterns: ["*"]
21
+
22
+ # uv.lock is committed, so a dependency only ever moves when somebody moves
23
+ # it. Grouped, because a lockfile refresh that arrives as eight separate pull
24
+ # requests gets ignored as eight separate pull requests.
25
+ - package-ecosystem: uv
26
+ directory: /
27
+ schedule:
28
+ interval: weekly
29
+ commit-message:
30
+ prefix: "chore"
31
+ groups:
32
+ dev-dependencies:
33
+ dependency-type: development
34
+ patterns: ["*"]
35
+ runtime-dependencies:
36
+ dependency-type: production
37
+ # Kept separate and ungrouped from dev: atlassian-python-api and
38
+ # fastmcp are capped at a major for reasons written into pyproject.toml,
39
+ # and a major bump of either needs the comment read, not merged.
40
+ patterns: ["*"]
41
+ update-types: ["minor", "patch"]
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: CI
3
+
4
+ on:
5
+ push:
6
+ branches: [main]
7
+ pull_request:
8
+ branches: [main]
9
+ # So the release workflow can run exactly this gate rather than a copy of it
10
+ # that drifts. Nothing reaches PyPI without passing what main passes.
11
+ workflow_call:
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ concurrency:
17
+ group: ${{ github.workflow }}-${{ github.ref }}
18
+ cancel-in-progress: true
19
+
20
+ # Every action is pinned to a commit, not a tag: a tag can be moved onto other
21
+ # code, and an action runs with access to this workflow's token. The comment
22
+ # after each one says which release the commit is, for the human reading it.
23
+ jobs:
24
+ test:
25
+ name: test (py${{ matrix.python-version }})
26
+ runs-on: ubuntu-latest
27
+ strategy:
28
+ fail-fast: false
29
+ matrix:
30
+ python-version: ["3.11", "3.12", "3.13", "3.14"]
31
+
32
+ steps:
33
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
34
+
35
+ - name: Install uv
36
+ uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
37
+ with:
38
+ enable-cache: true
39
+ cache-dependency-glob: uv.lock
40
+ python-version: ${{ matrix.python-version }}
41
+
42
+ - name: Install the project
43
+ run: uv sync --frozen
44
+
45
+ - name: Lint
46
+ run: uv run ruff check --output-format=github .
47
+
48
+ - name: Format
49
+ run: uv run ruff format --check .
50
+
51
+ - name: Typecheck
52
+ run: uv run mypy
53
+
54
+ # No Atlassian credentials exist in CI, and none should: the suite fakes
55
+ # the HTTP layer, so a test that needs a live Jira is a test that has
56
+ # stopped testing this repository.
57
+ - name: Test
58
+ run: uv run pytest
59
+
60
+ # The MCP surface is the product. Listing it without credentials catches
61
+ # a tool that fails to register long before an agent session does.
62
+ - name: MCP tools register
63
+ run: uv run python scripts/list_mcp_tools.py
64
+
65
+ secrets:
66
+ name: gitleaks
67
+ runs-on: ubuntu-latest
68
+ steps:
69
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
70
+ with:
71
+ # Full history: a token committed once and reverted is still leaked.
72
+ fetch-depth: 0
73
+
74
+ - name: Scan history for secrets
75
+ uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2.3.9
76
+ env:
77
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,116 @@
1
+ ---
2
+ name: Release
3
+
4
+ # Publishes to PyPI when a `v*` tag is pushed. Tagging is the whole release.
5
+ #
6
+ # There is no token anywhere — not in the repository, not in a secret, not on
7
+ # anyone's laptop. PyPI's trusted publishing exchanges this workflow's OIDC
8
+ # identity for a credential that lasts minutes, which is the same reason this
9
+ # project keeps Atlassian tokens in the environment rather than in a file.
10
+ # Three things are load-bearing rather than decorative, and PyPI matches on all
11
+ # of them: the filename `release.yml`, the `pypi` environment, and
12
+ # `id-token: write`. Rename any of them and the upload fails with a 403 that
13
+ # does not explain itself.
14
+ #
15
+ # The distribution is `atlassian-agent-mcp`, not `atlassian-agent`: that name
16
+ # belongs to an unrelated project on PyPI. The import package is still
17
+ # `atlassian_agent`.
18
+
19
+ on:
20
+ push:
21
+ tags: ["v*"]
22
+ workflow_dispatch:
23
+
24
+ permissions:
25
+ contents: read
26
+
27
+ jobs:
28
+ # The same gate main gets, called rather than copied. A tag that cannot pass
29
+ # CI is not a release.
30
+ ci:
31
+ uses: ./.github/workflows/ci.yml
32
+
33
+ # Build and publish are separate jobs on purpose. Only `publish` can mint a
34
+ # PyPI credential, and all it does is upload files it did not produce; the
35
+ # build — which runs hatchling and resolves the dependency tree, i.e. other
36
+ # people's code — never holds one.
37
+ build:
38
+ name: build and check the artifacts
39
+ needs: ci
40
+ runs-on: ubuntu-latest
41
+ steps:
42
+ # Pinned to a commit, not a tag: a tag can be moved onto other code.
43
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
44
+ - uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
45
+ with:
46
+ enable-cache: true
47
+ cache-dependency-glob: uv.lock
48
+ python-version: "3.13"
49
+
50
+ # A tag is typed by hand and the version lives in a file, so the two can
51
+ # disagree. Without this, tagging v0.3.0 on a tree that still says 0.2.0
52
+ # publishes 0.2.0 under a tag claiming otherwise — and a version on PyPI
53
+ # cannot be replaced, only yanked.
54
+ - name: the tag must be the version being published
55
+ run: |
56
+ tag="${GITHUB_REF_NAME#v}"
57
+ version=$(uv run --no-project python -c \
58
+ 'import tomllib,pathlib; print(tomllib.loads(pathlib.Path("pyproject.toml").read_text())["project"]["version"])')
59
+ if [ "$tag" != "$version" ]; then
60
+ echo "::error::tag $GITHUB_REF_NAME does not match pyproject version $version"
61
+ exit 1
62
+ fi
63
+ echo "publishing $version"
64
+
65
+ # A release nobody can read the notes for is half a release, and the
66
+ # changelog is the only place this project records what changed.
67
+ - name: the changelog must have an entry for this version
68
+ run: |
69
+ version="${GITHUB_REF_NAME#v}"
70
+ grep -q "^## \[$version\]" CHANGELOG.md || {
71
+ echo "::error::CHANGELOG.md has no '## [$version]' heading"
72
+ exit 1
73
+ }
74
+ echo "changelog entry found"
75
+
76
+ - name: build
77
+ run: uv build
78
+
79
+ - name: the artifacts are well-formed
80
+ run: uvx twine check dist/*
81
+
82
+ # Installing the wheel somewhere clean is the last cheap point at which
83
+ # a packaging mistake is noticeable: every test above imports from the
84
+ # working tree, where a missing module or an unresolvable entry point is
85
+ # invisible. The same script backs `make dist-check`, so the rehearsal
86
+ # somebody runs before tagging is this exact check.
87
+ - name: the installed wheel runs, and registers every tool
88
+ run: scripts/verify-wheel.sh dist/*.whl
89
+
90
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
91
+ with:
92
+ name: dist
93
+ path: dist/
94
+ if-no-files-found: error
95
+
96
+ publish:
97
+ name: publish to PyPI
98
+ needs: build
99
+ runs-on: ubuntu-latest
100
+ environment:
101
+ name: pypi
102
+ url: https://pypi.org/p/atlassian-agent-mcp
103
+ permissions:
104
+ id-token: write # the whole mechanism; without it there is no credential
105
+ steps:
106
+ - uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
107
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
108
+ with:
109
+ name: dist
110
+ path: dist/
111
+
112
+ # `always`, not `automatic`: if trusted publishing is unavailable for any
113
+ # reason, fail rather than quietly looking for a token that should not
114
+ # exist.
115
+ - name: publish
116
+ run: uv publish --trusted-publishing always
@@ -0,0 +1,218 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ # Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ # poetry.lock
109
+ # poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ # pdm.lock
116
+ # pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ # pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # Redis
135
+ *.rdb
136
+ *.aof
137
+ *.pid
138
+
139
+ # RabbitMQ
140
+ mnesia/
141
+ rabbitmq/
142
+ rabbitmq-data/
143
+
144
+ # ActiveMQ
145
+ activemq-data/
146
+
147
+ # SageMath parsed files
148
+ *.sage.py
149
+
150
+ # Environments
151
+ .env
152
+ .envrc
153
+ .venv
154
+ env/
155
+ venv/
156
+ ENV/
157
+ env.bak/
158
+ venv.bak/
159
+
160
+ # Spyder project settings
161
+ .spyderproject
162
+ .spyproject
163
+
164
+ # Rope project settings
165
+ .ropeproject
166
+
167
+ # mkdocs documentation
168
+ /site
169
+
170
+ # mypy
171
+ .mypy_cache/
172
+ .dmypy.json
173
+ dmypy.json
174
+
175
+ # Pyre type checker
176
+ .pyre/
177
+
178
+ # pytype static type analyzer
179
+ .pytype/
180
+
181
+ # Cython debug symbols
182
+ cython_debug/
183
+
184
+ # PyCharm
185
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
186
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
187
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
188
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
189
+ # .idea/
190
+
191
+ # Abstra
192
+ # Abstra is an AI-powered process automation framework.
193
+ # Ignore directories containing user credentials, local state, and settings.
194
+ # Learn more at https://abstra.io/docs
195
+ .abstra/
196
+
197
+ # Visual Studio Code
198
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
199
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
200
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
201
+ # you could uncomment the following to ignore the entire vscode folder
202
+ # .vscode/
203
+ # Temporary file for partial code execution
204
+ tempCodeRunnerFile.py
205
+
206
+ # Ruff stuff:
207
+ .ruff_cache/
208
+
209
+ # PyPI configuration file
210
+ .pypirc
211
+
212
+ # Marimo
213
+ marimo/_static/
214
+ marimo/_lsp/
215
+ __marimo__/
216
+
217
+ # Streamlit
218
+ .streamlit/secrets.toml
@@ -0,0 +1,76 @@
1
+ ---
2
+ # Install with: uv run pre-commit install --install-hooks
3
+ # Run over everything with: uv run pre-commit run --all-files
4
+ default_install_hook_types: [pre-commit, commit-msg]
5
+ default_language_version:
6
+ python: python3.11
7
+
8
+ repos:
9
+ - repo: https://github.com/pre-commit/pre-commit-hooks
10
+ rev: v6.0.0
11
+ hooks:
12
+ - id: check-added-large-files
13
+ args: [--maxkb=512]
14
+ # uv.lock is a generated text file we deliberately commit, and it is
15
+ # legitimately over the limit. Excluding it by name keeps the guard
16
+ # tight for everything else rather than raising it globally.
17
+ exclude: ^uv\.lock$
18
+ - id: check-merge-conflict
19
+ - id: check-toml
20
+ - id: check-yaml
21
+ - id: detect-private-key
22
+ - id: end-of-file-fixer
23
+ - id: mixed-line-ending
24
+ args: [--fix=lf]
25
+ - id: trailing-whitespace
26
+
27
+ - repo: https://github.com/astral-sh/ruff-pre-commit
28
+ rev: v0.15.15
29
+ hooks:
30
+ - id: ruff-check
31
+ args: [--fix]
32
+ - id: ruff-format
33
+
34
+ - repo: https://github.com/astral-sh/uv-pre-commit
35
+ rev: 0.9.28
36
+ hooks:
37
+ # Keeps uv.lock honest whenever pyproject.toml moves.
38
+ - id: uv-lock
39
+
40
+ - repo: https://github.com/gitleaks/gitleaks
41
+ rev: v8.30.1
42
+ hooks:
43
+ - id: gitleaks
44
+
45
+ - repo: local
46
+ hooks:
47
+ # The upstream mypy mirror runs in its own isolated environment and
48
+ # cannot see project dependencies, which produces phantom import errors.
49
+ # Run the project's own mypy instead.
50
+ - id: mypy
51
+ name: mypy
52
+ entry: uv run --frozen mypy
53
+ language: system
54
+ types: [python]
55
+ pass_filenames: false
56
+ require_serial: true
57
+
58
+ # This repository's whole point is that Atlassian credentials stay in the
59
+ # environment. A committed .env would defeat it, so refuse it explicitly
60
+ # rather than relying on .gitignore, which a `git add -f` walks straight
61
+ # past.
62
+ - id: no-dotenv-committed
63
+ name: no .env committed
64
+ language: fail
65
+ files: '^\.env$|(^|/)\.env\.(local|[^.]*)$'
66
+ exclude: '(^|/)\.env\.example$'
67
+ entry: >-
68
+ .env files hold live Atlassian tokens and must never be committed.
69
+ Put placeholders in .env.example instead.
70
+
71
+ - id: no-agent-coauthors
72
+ name: no AI Co-Authored-By trailers
73
+ language: pygrep
74
+ stages: [commit-msg]
75
+ args: [--ignore-case, --multiline]
76
+ entry: 'co-authored-by:.*(claude|anthropic|copilot|cursor|gemini|codex|chatgpt|openai)'
@@ -0,0 +1 @@
1
+ 3.11