[build-system]
requires = ["hatchling", "hatch-vcs"]
build-backend = "hatchling.build"
[project]
name = "mcp-server-for-oscal"
dynamic = ["version"]
readme = "README.md"
dependencies = [
# Put your dependencies here!
"boto3>=1.42.7",
"mcp>=1.23.3",
"strands-agents>=1.19.0",
]
requires-python = ">=3.11"
description = "AI agent tools for Open Security Controls Assessment Language (OSCAL)."
license = "Apache-2.0"
license-files = ["LICENSE"]
keywords = [
"OSCAL",
"compliance-as-code",
"security-as-code",
"compliance-automation",
"continuous-compliance",
"security-assurance",
"mcp-server",
"strands-agents",
]
classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
]
[project.scripts]
server = "mcp_server_for_oscal.main:main"
[project.urls]
GitHub = "https://github.com/awslabs/mcp-server-for-oscal/"
PyPI = "https://pypi.org/project/mcp-server-for-oscal/"
[tool.hatch.version]
source = "vcs"
[tool.hatch.version.raw-options]
version_scheme = "no-guess-dev"
# see also: tool.hatch.build.hooks.vcs below
[tool.hatch.build.hooks.vcs]
version-file = "_version.py"
[tool.hatch.envs.default]
# This controls what version of Python you want to be the default
# when running any scripts or tools to do things like debug test failures
# or do general development.
python = "3.12"
dependencies = ["pytest", "mypy", "boto3-stubs", "bandit", "pytest-asyncio"]
[tool.pytest.ini_options]
addopts = ["--durations=5", "--color=yes"]
testpaths = ["tests"]
filterwarnings = []
[tool.coverage.run]
source_pkgs = ["mcp_server_for_oscal"]
branch = true
parallel = true
[tool.coverage.paths]
"mcp_server_for_oscal" = [
"src/mcp_server_for_oscal",
"**/site-packages/mcp_server_for_oscal",
]
[tool.coverage.report]
exclude_lines = ["no cov", "if __name__ == .__main__.:", "if TYPE_CHECKING:"]
show_missing = true
# fail_under = 99
[tool.coverage.xml]
output = "private/docs/coverage/coverage.xml"
[tool.coverage.html]
directory = "private/docs/coverage/"
[tool.ruff]
line-length = 88
target-version = "py311"
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
[tool.ruff.lint]
isort.known-first-party = ["mcp_server_for_oscal"]
exclude = ["./build", ".hatch", "private"]
[tool.ruff.lint.per-file-ignores]
# Tests can use magic values, assertions, and relative imports
"tests/**/*" = ["PLR2004", "S101", "TID252", "PLC0415"]
[tool.hatch.build]
directory = "./build"
[tool.hatch.env]
python = "3.12"
[tool.hatch.envs.default.scripts]
# These are scripts you can run using `hatch run <script-name>`
typing = [
# Type checking using mypy
"mkdir -p .mypy_cache",
"mypy --install-types --non-interactive src/mcp_server_for_oscal tests",
]
update = [
# Update project dependencies in this file, then compile to requirements.txt
# to ensure deterministic/reproducible builds.
"uv pip install -U -r pyproject.toml",
"uv pip compile pyproject.toml -o requirements.txt",
]
bandito = [
# Run bandit security scanner against src, then tests. This cannot be
# named `bandit` because it creates a circular reference that hatch can't resolve.
"mkdir -p private/docs/bandit",
"bandit -r src/mcp_server_for_oscal | tee private/docs/bandit/src.txt",
"bandit -s B101 -r tests | tee private/docs/bandit/tests.txt",
]
tests = ["typing", "hatch test --all --cover", "hatch run bandito"]
release = [
"typing",
"hatch run bandito",
"hatch test --all --cover --junitxml private/docs/pytest.xml",
"hatch build",
]
rehash = [
# Regenerate hash files for bundled content
"hatch run bin/update_hashes.py src/mcp_server_for_oscal/oscal_schemas",
"git add src/mcp_server_for_oscal/oscal_schemas/hashes.json",
"hatch run bin/update_hashes.py src/mcp_server_for_oscal/oscal_docs",
"git add src/mcp_server_for_oscal/oscal_docs/hashes.json",
]
# TODO: monitor OSCAL GitHub project for changes and trigger PRs in our project
# Updates contents of `src/mcp_server_for_oscal/oscal_schemas`, overwriting existing files
update-oscal-schemas = ["bin/update-oscal-schemas.sh"]
# TODO: monitor Awesome OSCAL GitHub project for changes and trigger PRs in our project
# https://github.com/awslabs/mcp-server-for-oscal/issues/20
update-awesome-oscal = [
'''curl -L -o src/mcp_server_for_oscal/oscal_docs/awesome-oscal.md \
https://raw.githubusercontent.com/oscal-club/awesome-oscal/refs/heads/main/README.md''',
]
# Start the MCP server for remote testing/development
http-server = [
"python -m mcp_server_for_oscal.main --transport streamable-http",
]
[tool.hatch.envs.hatch-test.scripts]
run = "pytest{env:HATCH_TEST_ARGS:} {args}"
run-cov = "coverage run -m pytest{env:HATCH_TEST_ARGS:} {args}"
cov-combine = "coverage combine"
cov-report = ["coverage report", "coverage html", "coverage xml"]
[[tool.hatch.envs.hatch-test.matrix]]
python = ["3.11", "3.12"]
# This is necessary to use 'uv' as the resolver if this is the top-level package
# in a monorepo (which is usually the case). Remove this if copying the
# package into a monorepo
[tool.uv.workspace]