django-stateless-mcp 0.1.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 (82) hide show
  1. django_stateless_mcp-0.1.0/.editorconfig +37 -0
  2. django_stateless_mcp-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +61 -0
  3. django_stateless_mcp-0.1.0/.github/ISSUE_TEMPLATE/config.yml +1 -0
  4. django_stateless_mcp-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +30 -0
  5. django_stateless_mcp-0.1.0/.github/conformance/expected-failures.2026-07-28.yml +26 -0
  6. django_stateless_mcp-0.1.0/.github/dependabot.yml +24 -0
  7. django_stateless_mcp-0.1.0/.github/pull_request_template.md +17 -0
  8. django_stateless_mcp-0.1.0/.github/workflows/ci.yml +144 -0
  9. django_stateless_mcp-0.1.0/.github/workflows/codeql.yml +34 -0
  10. django_stateless_mcp-0.1.0/.github/workflows/conformance.yml +47 -0
  11. django_stateless_mcp-0.1.0/.github/workflows/docs.yml +37 -0
  12. django_stateless_mcp-0.1.0/.github/workflows/publish.yml +62 -0
  13. django_stateless_mcp-0.1.0/.github/workflows/zizmor.yml +36 -0
  14. django_stateless_mcp-0.1.0/.gitignore +60 -0
  15. django_stateless_mcp-0.1.0/.mcp.json +8 -0
  16. django_stateless_mcp-0.1.0/.pre-commit-config.yaml +54 -0
  17. django_stateless_mcp-0.1.0/.readthedocs.yaml +19 -0
  18. django_stateless_mcp-0.1.0/CHANGELOG/0.1.0.md +40 -0
  19. django_stateless_mcp-0.1.0/CODE_OF_CONDUCT.md +89 -0
  20. django_stateless_mcp-0.1.0/CONTRIBUTING.md +137 -0
  21. django_stateless_mcp-0.1.0/LICENSE +21 -0
  22. django_stateless_mcp-0.1.0/PKG-INFO +141 -0
  23. django_stateless_mcp-0.1.0/README.md +109 -0
  24. django_stateless_mcp-0.1.0/SECURITY.md +32 -0
  25. django_stateless_mcp-0.1.0/docs/adr/0001-mypy-strict-over-ty.md +99 -0
  26. django_stateless_mcp-0.1.0/docs/adr/0002-docs-on-read-the-docs.md +111 -0
  27. django_stateless_mcp-0.1.0/docs/adr/0003-real-dependencies-drop-scaffold.md +74 -0
  28. django_stateless_mcp-0.1.0/docs/adr/0004-pre-commit.md +58 -0
  29. django_stateless_mcp-0.1.0/docs/adr/0005-temporary-exclude-newer-exemption.md +91 -0
  30. django_stateless_mcp-0.1.0/docs/adr/0006-test-matrix.md +108 -0
  31. django_stateless_mcp-0.1.0/docs/adr/0007-stateless-view-bridge.md +114 -0
  32. django_stateless_mcp-0.1.0/docs/adr/0008-conformance-suite.md +83 -0
  33. django_stateless_mcp-0.1.0/docs/adr/0009-mcp-autodiscovery.md +44 -0
  34. django_stateless_mcp-0.1.0/docs/adr/0010-request-context.md +67 -0
  35. django_stateless_mcp-0.1.0/docs/adr/0011-bearer-auth.md +66 -0
  36. django_stateless_mcp-0.1.0/docs/adr/0012-request-state-security.md +80 -0
  37. django_stateless_mcp-0.1.0/docs/adr/0013-observability-middleware.md +53 -0
  38. django_stateless_mcp-0.1.0/docs/adr/0014-user-and-tool-permissions.md +82 -0
  39. django_stateless_mcp-0.1.0/docs/adr/0015-runnable-example-project.md +58 -0
  40. django_stateless_mcp-0.1.0/docs/adr/index.md +27 -0
  41. django_stateless_mcp-0.1.0/docs/example.md +27 -0
  42. django_stateless_mcp-0.1.0/docs/index.md +29 -0
  43. django_stateless_mcp-0.1.0/docs/installation.md +38 -0
  44. django_stateless_mcp-0.1.0/docs/recipes/oauth-and-permissions.md +144 -0
  45. django_stateless_mcp-0.1.0/docs/reference.md +3 -0
  46. django_stateless_mcp-0.1.0/docs/usage.md +257 -0
  47. django_stateless_mcp-0.1.0/docs/why-stateless.md +94 -0
  48. django_stateless_mcp-0.1.0/example/README.md +117 -0
  49. django_stateless_mcp-0.1.0/example/__init__.py +5 -0
  50. django_stateless_mcp-0.1.0/example/asgi.py +11 -0
  51. django_stateless_mcp-0.1.0/example/management/__init__.py +0 -0
  52. django_stateless_mcp-0.1.0/example/management/commands/__init__.py +0 -0
  53. django_stateless_mcp-0.1.0/example/management/commands/seed.py +40 -0
  54. django_stateless_mcp-0.1.0/example/mcp.py +282 -0
  55. django_stateless_mcp-0.1.0/example/mcp_server.py +148 -0
  56. django_stateless_mcp-0.1.0/example/settings.py +44 -0
  57. django_stateless_mcp-0.1.0/example/urls.py +68 -0
  58. django_stateless_mcp-0.1.0/example/wsgi.py +11 -0
  59. django_stateless_mcp-0.1.0/justfile +121 -0
  60. django_stateless_mcp-0.1.0/manage.py +19 -0
  61. django_stateless_mcp-0.1.0/mkdocs.yml +68 -0
  62. django_stateless_mcp-0.1.0/pyproject.toml +134 -0
  63. django_stateless_mcp-0.1.0/scripts/release.py +48 -0
  64. django_stateless_mcp-0.1.0/scripts/run_conformance.sh +50 -0
  65. django_stateless_mcp-0.1.0/src/django_stateless_mcp/__init__.py +23 -0
  66. django_stateless_mcp-0.1.0/src/django_stateless_mcp/apps.py +25 -0
  67. django_stateless_mcp-0.1.0/src/django_stateless_mcp/auth.py +133 -0
  68. django_stateless_mcp-0.1.0/src/django_stateless_mcp/context.py +40 -0
  69. django_stateless_mcp-0.1.0/src/django_stateless_mcp/logging.py +98 -0
  70. django_stateless_mcp-0.1.0/src/django_stateless_mcp/permissions.py +85 -0
  71. django_stateless_mcp-0.1.0/src/django_stateless_mcp/py.typed +1 -0
  72. django_stateless_mcp-0.1.0/src/django_stateless_mcp/security.py +35 -0
  73. django_stateless_mcp-0.1.0/src/django_stateless_mcp/views.py +193 -0
  74. django_stateless_mcp-0.1.0/tests/__init__.py +0 -0
  75. django_stateless_mcp-0.1.0/tests/broken_mcp_app/__init__.py +0 -0
  76. django_stateless_mcp-0.1.0/tests/broken_mcp_app/mcp.py +8 -0
  77. django_stateless_mcp-0.1.0/tests/settings.py +17 -0
  78. django_stateless_mcp-0.1.0/tests/test_django_stateless_mcp.py +23 -0
  79. django_stateless_mcp-0.1.0/tests/test_example_project.py +63 -0
  80. django_stateless_mcp-0.1.0/tests/test_views.py +534 -0
  81. django_stateless_mcp-0.1.0/tox.ini +24 -0
  82. django_stateless_mcp-0.1.0/uv.lock +1709 -0
@@ -0,0 +1,37 @@
1
+ # https://editorconfig.org
2
+ root = true
3
+
4
+ [*]
5
+ charset = utf-8
6
+ end_of_line = lf
7
+ indent_style = space
8
+ indent_size = 4
9
+ trim_trailing_whitespace = true
10
+ insert_final_newline = true
11
+
12
+ [*.{html,css,js,json,sh,yml,yaml}]
13
+ indent_size = 2
14
+
15
+ [*.bat]
16
+ indent_style = tab
17
+ end_of_line = crlf
18
+
19
+ [LICENSE]
20
+ insert_final_newline = false
21
+
22
+ [justfile]
23
+ indent_style = space
24
+ indent_size = 4
25
+
26
+ # Ignore binary or generated files
27
+ [*.{png,jpg,gif,ico,woff,woff2,ttf,eot,svg,pdf}]
28
+ charset = unset
29
+ end_of_line = unset
30
+ indent_style = unset
31
+ indent_size = unset
32
+ trim_trailing_whitespace = unset
33
+ insert_final_newline = unset
34
+ max_line_length = unset
35
+
36
+ [*.{diff,patch}]
37
+ trim_trailing_whitespace = false
@@ -0,0 +1,61 @@
1
+ name: Bug Report
2
+ description: Something isn't working as expected.
3
+ title: "BUG: "
4
+ labels: [bug]
5
+ body:
6
+ - type: textarea
7
+ id: description
8
+ attributes:
9
+ label: Describe the bug
10
+ description: What happened? What did you expect to happen?
11
+ validations:
12
+ required: true
13
+ - type: textarea
14
+ id: steps
15
+ attributes:
16
+ label: Steps to reproduce
17
+ description: Minimal steps to trigger the bug.
18
+ placeholder: |
19
+ 1. Install with `uv pip install django-stateless-mcp`
20
+ 2. Run `...`
21
+ 3. See error
22
+ validations:
23
+ required: true
24
+ - type: textarea
25
+ id: expected
26
+ attributes:
27
+ label: Expected behavior
28
+ validations:
29
+ required: true
30
+ - type: input
31
+ id: version
32
+ attributes:
33
+ label: "django-stateless-mcp version"
34
+ placeholder: "0.1.0"
35
+ validations:
36
+ required: true
37
+ - type: input
38
+ id: python-version
39
+ attributes:
40
+ label: Python version
41
+ placeholder: "3.13"
42
+ validations:
43
+ required: true
44
+ - type: dropdown
45
+ id: os
46
+ attributes:
47
+ label: Operating system
48
+ options:
49
+ - macOS
50
+ - Linux
51
+ - Windows
52
+ - Other
53
+ validations:
54
+ required: true
55
+ - type: textarea
56
+ id: context
57
+ attributes:
58
+ label: Additional context
59
+ description: Logs, tracebacks, screenshots, or anything else that helps.
60
+ validations:
61
+ required: false
@@ -0,0 +1 @@
1
+ blank_issues_enabled: true
@@ -0,0 +1,30 @@
1
+ name: Feature Request
2
+ description: Suggest something new.
3
+ title: "FEAT: "
4
+ labels: [enhancement]
5
+ body:
6
+ - type: textarea
7
+ id: description
8
+ attributes:
9
+ label: Describe the feature
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: motivation
14
+ attributes:
15
+ label: Motivation
16
+ description: What problem does this solve? What's the use case?
17
+ validations:
18
+ required: true
19
+ - type: textarea
20
+ id: alternatives
21
+ attributes:
22
+ label: Alternatives considered
23
+ validations:
24
+ required: false
25
+ - type: textarea
26
+ id: context
27
+ attributes:
28
+ label: Additional context
29
+ validations:
30
+ required: false
@@ -0,0 +1,26 @@
1
+ # Known-failure baseline; the runner fails on stale entries, so it burns down. See ADR-0008.
2
+ client: []
3
+
4
+ server:
5
+ # Deliberate deviation: Django's ALLOWED_HOSTS owns host validation (ADR-0007).
6
+ - dns-rebinding-protection
7
+
8
+ # Deferred feature: subscriptions/listen needs SSE streaming (ADR-0007, ADR-0008).
9
+ - server-stateless
10
+
11
+ # Fixture gaps: tests/mcp_server.py lacks the scenario's test_* tools; close per phase.
12
+ - completion-complete
13
+ - tools-call-image
14
+ - tools-call-audio
15
+ - tools-call-embedded-resource
16
+ - tools-call-mixed-content
17
+ - tools-call-with-progress
18
+ - json-schema-2020-12
19
+ - resources-read-text
20
+ - resources-read-binary
21
+ - resources-templates-read
22
+ - prompts-get-simple
23
+ - prompts-get-with-args
24
+ - prompts-get-embedded-resource
25
+ - prompts-get-with-image
26
+ - http-custom-header-server-validation
@@ -0,0 +1,24 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: github-actions
4
+ directory: /
5
+ schedule:
6
+ interval: weekly
7
+ day: monday
8
+ time: "07:00"
9
+ timezone: Europe/London
10
+ cooldown:
11
+ default-days: 7
12
+ open-pull-requests-limit: 5
13
+
14
+ # Cooldown matches exclude-newer in pyproject.toml, so uv can always lock it.
15
+ - package-ecosystem: uv
16
+ directory: /
17
+ schedule:
18
+ interval: weekly
19
+ day: monday
20
+ time: "07:00"
21
+ timezone: Europe/London
22
+ cooldown:
23
+ default-days: 7
24
+ open-pull-requests-limit: 5
@@ -0,0 +1,17 @@
1
+ ## What
2
+
3
+ <!-- 1-3 sentences. Link the issue if there is one. -->
4
+
5
+ ## AI Provenance
6
+
7
+ <!-- Remove this section for human-authored PRs. -->
8
+
9
+ - **Tool:** <!-- Claude Code, Cursor, Copilot, Codex, etc. -->
10
+ - **Model:** <!-- Claude Opus 4.6, GPT-4o, etc. -->
11
+ - **Prompt/thread:** <!-- Paste your prompt or a link to the thread. -->
12
+
13
+ ## Checklist
14
+
15
+ - [ ] Addresses exactly one issue or feature
16
+ - [ ] New or changed behavior has test coverage
17
+ - [ ] Diff contains only changes for this task
@@ -0,0 +1,144 @@
1
+ name: CI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches:
7
+ - main
8
+ pull_request:
9
+ types:
10
+ - opened
11
+ - synchronize
12
+ - reopened
13
+ - ready_for_review
14
+
15
+ permissions: {}
16
+
17
+ concurrency:
18
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
19
+ cancel-in-progress: true
20
+
21
+ jobs:
22
+ lint:
23
+ name: Lint
24
+ runs-on: ubuntu-latest
25
+ permissions:
26
+ contents: read
27
+ steps:
28
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
29
+ with:
30
+ persist-credentials: false
31
+
32
+ - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
33
+
34
+ - name: Ruff format check
35
+ run: uv run ruff format --check .
36
+
37
+ - name: Ruff lint
38
+ run: uv run ruff check .
39
+
40
+ type-check:
41
+ name: Type check
42
+ runs-on: ubuntu-latest
43
+ permissions:
44
+ contents: read
45
+ steps:
46
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
47
+ with:
48
+ persist-credentials: false
49
+
50
+ - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
51
+
52
+ - name: Type check with mypy
53
+ run: uv run mypy src/ tests/ example/ manage.py
54
+
55
+ test:
56
+ name: Test (Python ${{ matrix.python-version }})
57
+ runs-on: ubuntu-latest
58
+ strategy:
59
+ fail-fast: false
60
+ matrix:
61
+ python-version: ["3.12", "3.13", "3.14"]
62
+ permissions:
63
+ contents: read
64
+ steps:
65
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
66
+ with:
67
+ persist-credentials: false
68
+
69
+ - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
70
+
71
+ - name: Run tox envs for Python ${{ matrix.python-version }}
72
+ run: >
73
+ uvx --with tox-uv tox run
74
+ -f py$(echo ${{ matrix.python-version }} | tr -d .) mcp-release
75
+
76
+ - name: Upload coverage data
77
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
78
+ with:
79
+ name: coverage-${{ matrix.python-version }}
80
+ path: .coverage.*
81
+ include-hidden-files: true
82
+
83
+ # Advisory: SDK git main can break through no fault of ours. See ADR-0006.
84
+ test-mcp-main:
85
+ name: Test against mcp git main (advisory)
86
+ runs-on: ubuntu-latest
87
+ continue-on-error: true
88
+ strategy:
89
+ fail-fast: false
90
+ matrix:
91
+ python-version: ["3.12", "3.13", "3.14"]
92
+ permissions:
93
+ contents: read
94
+ steps:
95
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
96
+ with:
97
+ persist-credentials: false
98
+
99
+ - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
100
+
101
+ - name: Run tox envs for Python ${{ matrix.python-version }}
102
+ run: >
103
+ uvx --with tox-uv tox run
104
+ -f py$(echo ${{ matrix.python-version }} | tr -d .) mcp-latest
105
+
106
+ coverage:
107
+ name: Coverage
108
+ needs: test
109
+ runs-on: ubuntu-latest
110
+ permissions:
111
+ contents: read
112
+ steps:
113
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
114
+ with:
115
+ persist-credentials: false
116
+
117
+ - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
118
+
119
+ - name: Download coverage data
120
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
121
+ with:
122
+ pattern: coverage-*
123
+ merge-multiple: true
124
+
125
+ - name: Combine coverage
126
+ run: uv run coverage combine
127
+
128
+ - name: Coverage report
129
+ run: |
130
+ echo '## Coverage Report' >> $GITHUB_STEP_SUMMARY
131
+ echo '```' >> $GITHUB_STEP_SUMMARY
132
+ uv run coverage report | tee -a $GITHUB_STEP_SUMMARY
133
+ echo '```' >> $GITHUB_STEP_SUMMARY
134
+
135
+ all-checks-pass:
136
+ name: All checks pass
137
+ if: always()
138
+ needs: [lint, type-check, test, coverage]
139
+ runs-on: ubuntu-latest
140
+ steps:
141
+ - name: Check job results
142
+ uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2
143
+ with:
144
+ jobs: ${{ toJSON(needs) }}
@@ -0,0 +1,34 @@
1
+ name: CodeQL
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ schedule:
9
+ - cron: '0 6 * * 1'
10
+
11
+ permissions: {}
12
+
13
+ jobs:
14
+ analyze:
15
+ name: Analyze
16
+ runs-on: ubuntu-latest
17
+ permissions:
18
+ contents: read
19
+ packages: read
20
+ security-events: write
21
+ steps:
22
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
23
+ with:
24
+ persist-credentials: false
25
+
26
+ - name: Initialize CodeQL
27
+ uses: github/codeql-action/init@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3
28
+ with:
29
+ languages: python # Add c-cpp, go, java-kotlin, or swift if needed
30
+ build-mode: none # Switch to autobuild for compiled languages
31
+ queries: security-extended
32
+
33
+ - name: Perform CodeQL Analysis
34
+ uses: github/codeql-action/analyze@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3
@@ -0,0 +1,47 @@
1
+ name: Conformance
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches:
7
+ - main
8
+ pull_request:
9
+ types:
10
+ - opened
11
+ - synchronize
12
+ - reopened
13
+ - ready_for_review
14
+
15
+ permissions: {}
16
+
17
+ concurrency:
18
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
19
+ cancel-in-progress: true
20
+
21
+ env:
22
+ # Bump deliberately, reconciling expected-failures*.yml in the same change. See ADR-0008.
23
+ CONFORMANCE_PKG: "@modelcontextprotocol/conformance@0.2.0-alpha.10"
24
+
25
+ jobs:
26
+ server-conformance:
27
+ name: Server conformance (2026-07-28)
28
+ runs-on: ubuntu-latest
29
+ permissions:
30
+ contents: read
31
+ steps:
32
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
33
+ with:
34
+ persist-credentials: false
35
+
36
+ - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
37
+
38
+ - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
39
+ with:
40
+ node-version: 22
41
+
42
+ - name: Run server conformance
43
+ run: >-
44
+ ./scripts/run_conformance.sh
45
+ --suite all
46
+ --spec-version 2026-07-28
47
+ --expected-failures .github/conformance/expected-failures.2026-07-28.yml
@@ -0,0 +1,37 @@
1
+ name: Documentation
2
+
3
+ # RTD hosts the site; this only checks the build. See ADR-0002.
4
+
5
+ on:
6
+ workflow_dispatch:
7
+ push:
8
+ branches:
9
+ - main
10
+ pull_request:
11
+ types:
12
+ - opened
13
+ - synchronize
14
+ - reopened
15
+ - ready_for_review
16
+
17
+ permissions: {}
18
+
19
+ concurrency:
20
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
21
+ cancel-in-progress: true
22
+
23
+ jobs:
24
+ build:
25
+ name: Build
26
+ runs-on: ubuntu-latest
27
+ permissions:
28
+ contents: read
29
+ steps:
30
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
31
+ with:
32
+ persist-credentials: false
33
+
34
+ - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
35
+
36
+ - name: Build docs
37
+ run: uv run --group docs mkdocs build --strict
@@ -0,0 +1,62 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions: {}
9
+
10
+ concurrency:
11
+ group: publish
12
+
13
+ jobs:
14
+ build:
15
+ name: Build distribution
16
+ runs-on: ubuntu-latest
17
+ permissions:
18
+ contents: read
19
+ steps:
20
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
21
+ with:
22
+ persist-credentials: false
23
+
24
+ # Cache disabled to prevent cache-poisoning attacks on release artifacts.
25
+ - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
26
+ with:
27
+ enable-cache: false
28
+
29
+ - name: Build
30
+ run: uv build
31
+
32
+ - name: Upload distribution
33
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
34
+ with:
35
+ name: dist
36
+ path: dist/
37
+
38
+ publish:
39
+ name: Publish to PyPI
40
+ needs: build
41
+ runs-on: ubuntu-latest
42
+ permissions:
43
+ id-token: write
44
+ attestations: write
45
+ # Needs Settings > Environments > pypi: reviewers + v* tag restriction.
46
+ environment:
47
+ name: pypi
48
+ url: https://pypi.org/p/django-stateless-mcp
49
+ steps:
50
+ - name: Download distribution
51
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
52
+ with:
53
+ name: dist
54
+ path: dist/
55
+
56
+ - name: Attest build provenance
57
+ uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1
58
+ with:
59
+ subject-path: "dist/*"
60
+
61
+ - name: Publish to PyPI
62
+ uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # v1.14.1
@@ -0,0 +1,36 @@
1
+ name: Workflow security analysis
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - ".github/workflows/**"
9
+ pull_request:
10
+ types:
11
+ - opened
12
+ - synchronize
13
+ - reopened
14
+ - ready_for_review
15
+ paths:
16
+ - ".github/workflows/**"
17
+
18
+ permissions: {}
19
+
20
+ jobs:
21
+ zizmor:
22
+ name: Run zizmor
23
+ runs-on: ubuntu-latest
24
+ permissions:
25
+ contents: read
26
+ actions: read
27
+ security-events: write
28
+ steps:
29
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
30
+ with:
31
+ persist-credentials: false
32
+
33
+ - name: Run zizmor
34
+ uses: zizmorcore/zizmor-action@6fc4b006235f201fdab3722e17240ab420d580e5 # v0.6.1
35
+ with:
36
+ inputs: ./.github/
@@ -0,0 +1,60 @@
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
+ build/
11
+ dist/
12
+ eggs/
13
+ .eggs/
14
+ *.egg-info/
15
+ *.egg
16
+ MANIFEST
17
+
18
+ # Unit test / coverage reports
19
+ htmlcov/
20
+ .tox/
21
+ .nox/
22
+ .coverage
23
+ .coverage.*
24
+ coverage.xml
25
+ .hypothesis/
26
+ .pytest_cache/
27
+
28
+ # Environments
29
+ .env
30
+ .envrc
31
+ .venv
32
+
33
+ # uv
34
+ # Generally recommended to include uv.lock in version control for
35
+ # reproducibility. Uncomment for libraries where you want consumers
36
+ # to resolve their own dependencies.
37
+ # uv.lock
38
+
39
+ # Ruff
40
+ .ruff_cache/
41
+
42
+ # Type checkers
43
+ .mypy_cache/
44
+ .dmypy.json
45
+ dmypy.json
46
+ .pyre/
47
+ .pytype/
48
+
49
+ # Example project local database
50
+ example/db.sqlite3
51
+
52
+ # Documentation build output
53
+ site/
54
+
55
+ # IDE files
56
+ # .idea/
57
+ # .vscode/
58
+
59
+ # Local agent guidance (not a committed team convention)
60
+ CLAUDE.md
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "django-stateless-mcp-example": {
4
+ "type": "http",
5
+ "url": "http://127.0.0.1:8000/mcp/"
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,54 @@
1
+ ci:
2
+ autoupdate_schedule: monthly
3
+
4
+ default_language_version:
5
+ python: python3.13
6
+
7
+ repos:
8
+ - repo: https://github.com/pre-commit/pre-commit-hooks
9
+ rev: v6.0.0
10
+ hooks:
11
+ - id: check-added-large-files
12
+ - id: check-case-conflict
13
+ - id: check-merge-conflict
14
+ - id: check-symlinks
15
+ - id: check-toml
16
+ - id: check-yaml
17
+ - id: end-of-file-fixer
18
+ - id: trailing-whitespace
19
+
20
+ - repo: https://github.com/tox-dev/pyproject-fmt
21
+ rev: v2.23.0
22
+ hooks:
23
+ - id: pyproject-fmt
24
+
25
+ - repo: https://github.com/astral-sh/ruff-pre-commit
26
+ rev: v0.15.15
27
+ hooks:
28
+ - id: ruff-check
29
+ args: [--fix]
30
+ - id: ruff-format
31
+
32
+ - repo: https://github.com/adamchainz/blacken-docs
33
+ rev: 1.20.0
34
+ hooks:
35
+ - id: blacken-docs
36
+ additional_dependencies:
37
+ - black==25.1.0
38
+
39
+ - repo: https://github.com/adamchainz/django-upgrade
40
+ rev: 1.30.0
41
+ hooks:
42
+ - id: django-upgrade
43
+ args: [--target-version, "5.2"]
44
+
45
+ - repo: local
46
+ hooks:
47
+ # Runs in the project env so django/mcp resolve. See ADR-0004.
48
+ - id: mypy
49
+ name: mypy
50
+ entry: uv run mypy
51
+ language: system
52
+ types: [python]
53
+ pass_filenames: false
54
+ args: [src/, tests/]