tracehub-mcp 0.2.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 (118) hide show
  1. tracehub_mcp-0.2.0/.cz.toml +18 -0
  2. tracehub_mcp-0.2.0/.dockerignore +56 -0
  3. tracehub_mcp-0.2.0/.env.example +43 -0
  4. tracehub_mcp-0.2.0/.github/dependabot.yml +30 -0
  5. tracehub_mcp-0.2.0/.github/workflows/ci.yml +154 -0
  6. tracehub_mcp-0.2.0/.github/workflows/release.yml +109 -0
  7. tracehub_mcp-0.2.0/.github/workflows/security.yml +126 -0
  8. tracehub_mcp-0.2.0/.gitignore +211 -0
  9. tracehub_mcp-0.2.0/.python-version +1 -0
  10. tracehub_mcp-0.2.0/CHANGELOG.md +42 -0
  11. tracehub_mcp-0.2.0/CLAUDE.md +637 -0
  12. tracehub_mcp-0.2.0/Dockerfile +74 -0
  13. tracehub_mcp-0.2.0/LICENSE +201 -0
  14. tracehub_mcp-0.2.0/NOTICE +11 -0
  15. tracehub_mcp-0.2.0/PKG-INFO +798 -0
  16. tracehub_mcp-0.2.0/README.md +763 -0
  17. tracehub_mcp-0.2.0/pyproject.toml +110 -0
  18. tracehub_mcp-0.2.0/src/opentelemetry_mcp/__init__.py +3 -0
  19. tracehub_mcp-0.2.0/src/opentelemetry_mcp/attributes.py +174 -0
  20. tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/__init__.py +5 -0
  21. tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/base.py +160 -0
  22. tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/datadog.py +845 -0
  23. tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/filter_engine.py +284 -0
  24. tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/jaeger.py +474 -0
  25. tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/sentry.py +1188 -0
  26. tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/tempo.py +700 -0
  27. tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/traceloop.py +729 -0
  28. tracehub_mcp-0.2.0/src/opentelemetry_mcp/config.py +148 -0
  29. tracehub_mcp-0.2.0/src/opentelemetry_mcp/constants.py +196 -0
  30. tracehub_mcp-0.2.0/src/opentelemetry_mcp/models.py +685 -0
  31. tracehub_mcp-0.2.0/src/opentelemetry_mcp/server.py +747 -0
  32. tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/__init__.py +3 -0
  33. tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/errors.py +123 -0
  34. tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/expensive_traces.py +126 -0
  35. tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/list_llm_tools.py +137 -0
  36. tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/list_models.py +106 -0
  37. tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/model_stats.py +168 -0
  38. tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/search.py +117 -0
  39. tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/search_spans.py +119 -0
  40. tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/services.py +52 -0
  41. tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/slow_traces.py +114 -0
  42. tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/trace.py +80 -0
  43. tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/usage.py +114 -0
  44. tracehub_mcp-0.2.0/src/opentelemetry_mcp/utils.py +23 -0
  45. tracehub_mcp-0.2.0/start_locally.sh +54 -0
  46. tracehub_mcp-0.2.0/tests/__init__.py +1 -0
  47. tracehub_mcp-0.2.0/tests/conftest.py +122 -0
  48. tracehub_mcp-0.2.0/tests/integration/__init__.py +1 -0
  49. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerBackendHealth.test_health_check_healthy.yaml +32 -0
  50. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerGetTrace.test_get_trace_by_id.yaml +92 -0
  51. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerGetTrace.test_get_trace_invalid_id.yaml +37 -0
  52. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerLLMSpans.test_search_llm_spans.yaml +62 -0
  53. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerLLMSpans.test_search_traces_with_llm_model_filter.yaml +152 -0
  54. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerListServices.test_list_services.yaml +32 -0
  55. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchSpans.test_search_spans_basic.yaml +62 -0
  56. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchSpans.test_search_spans_with_generic_filter.yaml +62 -0
  57. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchSpans.test_search_spans_with_limit.yaml +98 -0
  58. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchSpans.test_search_spans_with_operation.yaml +93 -0
  59. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchTraces.test_search_traces_basic.yaml +78 -0
  60. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchTraces.test_search_traces_with_duration_filter.yaml +64 -0
  61. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchTraces.test_search_traces_with_error_filter.yaml +78 -0
  62. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchTraces.test_search_traces_with_generic_filter.yaml +62 -0
  63. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchTraces.test_search_traces_with_limit.yaml +68 -0
  64. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchTraces.test_search_traces_with_operation.yaml +112 -0
  65. tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerServiceOperations.test_get_service_operations.yaml +62 -0
  66. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoBackendHealth.test_health_check_healthy.yaml +33 -0
  67. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoGetTrace.test_get_trace_by_id.yaml +239 -0
  68. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoGetTrace.test_get_trace_invalid_id.yaml +30 -0
  69. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoLLMSpans.test_search_llm_spans.yaml +5248 -0
  70. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoLLMSpans.test_search_traces_with_llm_model_filter.yaml +122 -0
  71. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoListServices.test_list_services.yaml +39 -0
  72. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchSpans.test_search_spans_basic.yaml +5248 -0
  73. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchSpans.test_search_spans_with_generic_filter.yaml +32 -0
  74. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchSpans.test_search_spans_with_limit.yaml +5248 -0
  75. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchSpans.test_search_spans_with_operation.yaml +69 -0
  76. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchSpans.test_search_spans_with_service_filter.yaml +2707 -0
  77. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_basic.yaml +5248 -0
  78. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_with_attribute_filter.yaml +5248 -0
  79. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_with_duration_filter.yaml +5248 -0
  80. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_with_error_filter.yaml +32 -0
  81. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_with_generic_filter.yaml +32 -0
  82. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_with_limit.yaml +3384 -0
  83. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_with_operation.yaml +69 -0
  84. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_with_service_filter.yaml +2707 -0
  85. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoServiceOperations.test_get_service_operations.yaml +69 -0
  86. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoTraceQL.test_search_with_contains_filter.yaml +5285 -0
  87. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoTraceQL.test_search_with_in_filter.yaml +5285 -0
  88. tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoTraceQL.test_search_with_multiple_filters.yaml +69 -0
  89. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopBackendHealth.test_health_check_healthy.yaml +864 -0
  90. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopFilters.test_search_with_comparison_operators.yaml +40 -0
  91. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopFilters.test_search_with_multiple_filters.yaml +846 -0
  92. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopGetTrace.test_get_trace_by_id.yaml +943 -0
  93. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopGetTrace.test_get_trace_invalid_id.yaml +32 -0
  94. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopLLMSpans.test_search_llm_spans.yaml +1036 -0
  95. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopLLMSpans.test_search_spans_by_llm_system.yaml +2044 -0
  96. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopListServices.test_list_services.yaml +814 -0
  97. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchSpans.test_search_spans_basic.yaml +1036 -0
  98. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchSpans.test_search_spans_with_generic_filter.yaml +1036 -0
  99. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchSpans.test_search_spans_with_limit.yaml +754 -0
  100. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchSpans.test_search_spans_with_operation.yaml +876 -0
  101. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchSpans.test_search_spans_with_service_filter.yaml +846 -0
  102. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchTraces.test_search_spans_with_llm_model_filter.yaml +394 -0
  103. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchTraces.test_search_traces_basic.yaml +40 -0
  104. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchTraces.test_search_traces_with_duration_filter.yaml +40 -0
  105. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchTraces.test_search_traces_with_error_filter.yaml +40 -0
  106. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchTraces.test_search_traces_with_generic_filter.yaml +40 -0
  107. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchTraces.test_search_traces_with_limit.yaml +40 -0
  108. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchTraces.test_search_traces_with_service_filter.yaml +846 -0
  109. tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopServiceOperations.test_get_service_operations.yaml +844 -0
  110. tracehub_mcp-0.2.0/tests/integration/conftest.py +288 -0
  111. tracehub_mcp-0.2.0/tests/integration/test_jaeger_integration.py +361 -0
  112. tracehub_mcp-0.2.0/tests/integration/test_tempo_integration.py +439 -0
  113. tracehub_mcp-0.2.0/tests/integration/test_traceloop_integration.py +469 -0
  114. tracehub_mcp-0.2.0/tests/test_datadog.py +781 -0
  115. tracehub_mcp-0.2.0/tests/test_models.py +128 -0
  116. tracehub_mcp-0.2.0/tests/test_sentry.py +1117 -0
  117. tracehub_mcp-0.2.0/tests/test_traceloop.py +231 -0
  118. tracehub_mcp-0.2.0/uv.lock +1965 -0
@@ -0,0 +1,18 @@
1
+ [tool.commitizen]
2
+ name = "cz_conventional_commits"
3
+ version = "0.2.0"
4
+ tag_format = "v$version"
5
+ update_changelog_on_bump = true
6
+ major_version_zero = true
7
+ version_scheme = "pep440"
8
+
9
+ # Files where Commitizen will update the version
10
+ version_files = [
11
+ "pyproject.toml:version",
12
+ "src/opentelemetry_mcp/__init__.py:__version__"
13
+ ]
14
+
15
+ # Changelog configuration
16
+ [tool.commitizen.changelog]
17
+ # Categorize commits by type
18
+ file = "CHANGELOG.md"
@@ -0,0 +1,56 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ *.egg-info/
8
+ dist/
9
+ build/
10
+ *.egg
11
+
12
+ # Virtual environments
13
+ .venv/
14
+ venv/
15
+ ENV/
16
+ env/
17
+
18
+ # Testing
19
+ .pytest_cache/
20
+ .coverage
21
+ htmlcov/
22
+ .mypy_cache/
23
+ .ruff_cache/
24
+
25
+ # IDE
26
+ .vscode/
27
+ .idea/
28
+ *.swp
29
+ *.swo
30
+ *~
31
+
32
+ # Git
33
+ .git/
34
+ .gitignore
35
+
36
+ # Documentation
37
+ *.md
38
+ !README.md
39
+ docs/
40
+
41
+ # CI/CD
42
+ .github/
43
+
44
+ # Environment files (include these at runtime instead)
45
+ .env
46
+ .env.local
47
+ .env.*.local
48
+
49
+ # UV cache
50
+ .uv/
51
+
52
+ # macOS
53
+ .DS_Store
54
+
55
+ # Tests
56
+ tests/
@@ -0,0 +1,43 @@
1
+ # Backend Configuration
2
+ # Supported backends: jaeger, tempo, traceloop, datadog, sentry
3
+ BACKEND_TYPE=jaeger
4
+
5
+ # Backend URL (required)
6
+ # Examples:
7
+ # Jaeger: http://localhost:16686
8
+ # Tempo: http://localhost:3200
9
+ # Traceloop: https://api.traceloop.com/v2
10
+ # Datadog (US): https://api.datadoghq.com
11
+ # Datadog (EU): https://api.datadoghq.eu
12
+ # Sentry (SaaS): https://sentry.io
13
+ # Sentry (self-hosted): https://sentry.your-company.com
14
+ BACKEND_URL=http://localhost:16686
15
+
16
+ # Optional: API key for authenticated backends (mainly for Traceloop, required
17
+ # for Datadog and Sentry - for Sentry this is an auth token with trace/event
18
+ # read permissions)
19
+ BACKEND_API_KEY=
20
+
21
+ # Required for Datadog backend only: Application key, in addition to BACKEND_API_KEY
22
+ BACKEND_APP_KEY=
23
+
24
+ # Required for Sentry backend only: organization slug (every Sentry API
25
+ # endpoint this backend uses is organization-scoped).
26
+ BACKEND_SENTRY_ORG=
27
+
28
+ # Optional for Sentry backend: project slug to narrow queries to. When
29
+ # omitted, queries span every project the auth token can access.
30
+ BACKEND_SENTRY_PROJECT=
31
+
32
+ # Optional: Comma-separated list of environments for Traceloop backend (default: production)
33
+ # Only used when BACKEND_TYPE=traceloop
34
+ BACKEND_ENVIRONMENTS=production
35
+
36
+ # Optional: Request timeout in seconds (default: 30)
37
+ BACKEND_TIMEOUT=30
38
+
39
+ # Optional: Logging level (DEBUG, INFO, WARNING, ERROR)
40
+ LOG_LEVEL=INFO
41
+
42
+ # Optional: Maximum traces per query (default: 100, max: 1000)
43
+ MAX_TRACES_PER_QUERY=100
@@ -0,0 +1,30 @@
1
+ # Dependabot configuration
2
+ # https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
3
+
4
+ version: 2
5
+ updates:
6
+ # Python dependencies (pyproject.toml)
7
+ - package-ecosystem: "pip"
8
+ directory: "/"
9
+ schedule:
10
+ interval: "weekly"
11
+ day: "monday"
12
+ commit-message:
13
+ prefix: "chore(deps)"
14
+ labels:
15
+ - "dependencies"
16
+ - "python"
17
+ open-pull-requests-limit: 10
18
+
19
+ # GitHub Actions
20
+ - package-ecosystem: "github-actions"
21
+ directory: "/"
22
+ schedule:
23
+ interval: "weekly"
24
+ day: "monday"
25
+ commit-message:
26
+ prefix: "chore(deps)"
27
+ labels:
28
+ - "dependencies"
29
+ - "github-actions"
30
+ open-pull-requests-limit: 5
@@ -0,0 +1,154 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ pull_request:
7
+ types: [opened, synchronize]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ lint:
14
+ name: Lint
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v6
18
+ - name: Setup UV
19
+ uses: astral-sh/setup-uv@v7
20
+ with:
21
+ version: "latest"
22
+ enable-cache: true
23
+ - name: Setup Python
24
+ uses: actions/setup-python@v6
25
+ with:
26
+ python-version: "3.13"
27
+ - name: Install dependencies
28
+ run: uv sync --dev
29
+ - name: Lint with Ruff
30
+ run: uv run ruff check --output-format=github
31
+ - name: Lint with Mypy
32
+ run: uv run mypy .
33
+ test:
34
+ name: Test
35
+ runs-on: ubuntu-latest
36
+ steps:
37
+ - uses: actions/checkout@v6
38
+ - name: Setup UV
39
+ uses: astral-sh/setup-uv@v7
40
+ with:
41
+ version: "latest"
42
+ enable-cache: true
43
+ - name: Setup Python
44
+ uses: actions/setup-python@v6
45
+ with:
46
+ python-version: "3.13"
47
+ - name: Install dependencies
48
+ run: uv sync --dev
49
+ - name: Test with pytest
50
+ run: uv run pytest
51
+ build-test:
52
+ needs: test
53
+ runs-on: ubuntu-latest
54
+ permissions:
55
+ contents: read
56
+ actions: read
57
+ pull-requests: write
58
+ security-events: write
59
+ strategy:
60
+ matrix:
61
+ platform: [amd64, arm64]
62
+ include:
63
+ - platform: amd64
64
+ runs-on: ubuntu-latest
65
+ docker-platform: linux/amd64
66
+ - platform: arm64
67
+ runs-on: ubuntu-24.04-arm
68
+ docker-platform: linux/arm64
69
+ steps:
70
+ - uses: actions/checkout@v6
71
+
72
+ - name: Set up Docker Buildx
73
+ uses: docker/setup-buildx-action@v3
74
+
75
+ - name: Docker Build
76
+ uses: docker/build-push-action@v6
77
+ with:
78
+ platforms: ${{ matrix.docker-platform }}
79
+ context: .
80
+ load: true
81
+ push: false
82
+ tags: tracehub-mcp-server:${{ github.sha }}-${{ matrix.platform }}
83
+ - name: Cache Trivy
84
+ uses: actions/cache@v4
85
+ with:
86
+ path: ~/.cache/trivy
87
+ key: trivy-${{ runner.os }}-${{ matrix.platform }}
88
+ restore-keys: |
89
+ trivy-${{ runner.os }}-
90
+ - name: Trivy scan (JSON)
91
+ uses: aquasecurity/trivy-action@v0.35.0
92
+ with:
93
+ image-ref: tracehub-mcp-server:${{ github.sha }}-${{ matrix.platform }}
94
+ scanners: secret,vuln
95
+ exit-code: "0"
96
+ severity: CRITICAL,HIGH
97
+ format: json
98
+ output: trivy-results-${{ matrix.platform }}.json
99
+ - name: Convert to table
100
+ run: trivy convert --format table --output trivy-results-${{ matrix.platform }}.txt trivy-results-${{ matrix.platform }}.json
101
+ - name: Convert to SARIF
102
+ if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
103
+ run: trivy convert --format sarif --output trivy-results-${{ matrix.platform }}.sarif trivy-results-${{ matrix.platform }}.json
104
+ - name: Upload SARIF to GitHub Security
105
+ if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
106
+ uses: github/codeql-action/upload-sarif@v4
107
+ with:
108
+ sarif_file: trivy-results-${{ matrix.platform }}.sarif
109
+ category: container-security-tracehub-mcp-server-${{ matrix.platform }}
110
+ - name: Log Trivy results
111
+ run: |
112
+ echo "::group::Trivy Scan Results (tracehub-mcp-server-${{ matrix.platform }})"
113
+ if [ -s "trivy-results-${{ matrix.platform }}.txt" ]; then
114
+ cat "trivy-results-${{ matrix.platform }}.txt"
115
+ else
116
+ echo "No issues found!"
117
+ fi
118
+ echo "::endgroup::"
119
+ - name: Prepare PR comment
120
+ if: github.event_name == 'pull_request'
121
+ run: |
122
+ MAX_CHARS=60000
123
+ RESULTS_FILE="trivy-results-${{ matrix.platform }}.txt"
124
+ COMMENT_FILE="trivy-comment-${{ matrix.platform }}.md"
125
+ FILE_SIZE=$(wc -c < "$RESULTS_FILE" || echo "0")
126
+ {
127
+ echo "## Container Security Scan (tracehub-mcp-server-${{ matrix.platform }})"
128
+ echo ""
129
+ if [ ! -s "$RESULTS_FILE" ]; then
130
+ echo "**No vulnerabilities found!**"
131
+ else
132
+ echo "<details>"
133
+ echo "<summary>Click to expand results</summary>"
134
+ echo ""
135
+ echo '```'
136
+ if [ "$FILE_SIZE" -gt "$MAX_CHARS" ]; then
137
+ head -c "$MAX_CHARS" "$RESULTS_FILE"
138
+ echo ""
139
+ echo "... (output truncated - exceeded ${MAX_CHARS} characters)"
140
+ echo "See full results in workflow logs"
141
+ else
142
+ cat "$RESULTS_FILE"
143
+ fi
144
+ echo '```'
145
+ echo ""
146
+ echo "</details>"
147
+ fi
148
+ } > "$COMMENT_FILE"
149
+ - name: Post PR comment
150
+ if: github.event_name == 'pull_request'
151
+ uses: marocchino/sticky-pull-request-comment@v2
152
+ with:
153
+ header: trivy-scan-tracehub-mcp-server-${{ matrix.platform }}
154
+ path: trivy-comment-${{ matrix.platform }}.md
@@ -0,0 +1,109 @@
1
+ name: Release
2
+
3
+ on:
4
+ workflow_dispatch: # Manual trigger via GitHub Actions UI
5
+
6
+ permissions:
7
+ contents: write # Required for pushing commits, tags, and creating releases
8
+ id-token: write # Required for PyPI OIDC (Trusted Publishing)
9
+
10
+ jobs:
11
+ bump-version:
12
+ name: Bump Version & Create Release
13
+ runs-on: ubuntu-latest
14
+ outputs:
15
+ new_version: ${{ steps.cz.outputs.version }}
16
+ steps:
17
+ - name: Checkout code
18
+ uses: actions/checkout@v6
19
+ with:
20
+ fetch-depth: 0 # Full history required for Commitizen
21
+ token: ${{ secrets.GITHUB_TOKEN }}
22
+
23
+ - name: Setup Python
24
+ uses: actions/setup-python@v6
25
+ with:
26
+ python-version: "3.13"
27
+
28
+ - name: Install Commitizen
29
+ run: pip install commitizen
30
+
31
+ - name: Bump version
32
+ id: cz
33
+ uses: commitizen-tools/commitizen-action@master
34
+ with:
35
+ github_token: ${{ secrets.GITHUB_TOKEN }}
36
+ changelog_increment_filename: body.md
37
+ # The action's own entrypoint runs `git config --local user.name/email`
38
+ # unconditionally using these inputs (default: github-actions[bot]) --
39
+ # a standalone `git config` step earlier in this job has no effect,
40
+ # since this overwrites it right before the bump commit is made.
41
+ git_name: "sairam0424"
42
+ git_email: "uggesairam0000@gmail.com"
43
+
44
+ - name: Print version info
45
+ run: |
46
+ echo "New version: ${{ steps.cz.outputs.version }}"
47
+ echo "Version bump: ${{ steps.cz.outputs.version }}"
48
+
49
+ - name: Create GitHub Release
50
+ env:
51
+ GH_TOKEN: ${{ github.token }}
52
+ run: |
53
+ gh release create "${{ steps.cz.outputs.version }}" \
54
+ --title "Release ${{ steps.cz.outputs.version }}" \
55
+ --notes-file "body.md"
56
+
57
+ build-and-publish:
58
+ name: Build and Publish to PyPI
59
+ needs: bump-version
60
+ runs-on: ubuntu-latest
61
+ permissions:
62
+ id-token: write # Required for PyPI OIDC
63
+ steps:
64
+ - name: Checkout code (with new version)
65
+ uses: actions/checkout@v6
66
+ with:
67
+ ref: main # Get the version-bumped code
68
+
69
+ - name: Setup UV
70
+ uses: astral-sh/setup-uv@v7
71
+ with:
72
+ version: "latest"
73
+ enable-cache: true
74
+
75
+ - name: Setup Python
76
+ uses: actions/setup-python@v6
77
+ with:
78
+ python-version: "3.13"
79
+
80
+ - name: Build package
81
+ run: |
82
+ uv build --wheel --sdist
83
+ ls -lh dist/
84
+
85
+ - name: Publish to PyPI
86
+ uses: pypa/gh-action-pypi-publish@release/v1
87
+ # No credentials needed - uses OIDC/Trusted Publishing!
88
+
89
+ test-installation:
90
+ name: Test PyPI Installation
91
+ needs: [bump-version, build-and-publish]
92
+ runs-on: ubuntu-latest
93
+ steps:
94
+ - name: Setup Python
95
+ uses: actions/setup-python@v6
96
+ with:
97
+ python-version: "3.13"
98
+
99
+ - name: Wait for package availability
100
+ run: sleep 60 # Wait for PyPI to index the package
101
+
102
+ - name: Test installation from PyPI
103
+ run: |
104
+ pip install tracehub-mcp==${{ needs.bump-version.outputs.new_version }}
105
+ python -c "import opentelemetry_mcp; print(f'Installed version: {opentelemetry_mcp.__version__}')"
106
+ tracehub-mcp --help
107
+
108
+ - name: Installation successful
109
+ run: echo "✅ Package successfully published and verified on PyPI!"
@@ -0,0 +1,126 @@
1
+ name: Security Scan
2
+
3
+ on:
4
+ workflow_dispatch: # Manual trigger
5
+ schedule:
6
+ - cron: "0 10 * * *" # Daily at 10 AM UTC
7
+
8
+ permissions:
9
+ contents: read
10
+ actions: read
11
+ security-events: write
12
+ pull-requests: write
13
+
14
+ jobs:
15
+ image-scan:
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ platform: [amd64, arm64]
20
+ include:
21
+ - platform: amd64
22
+ runs-on: ubuntu-latest
23
+ docker-platform: linux/amd64
24
+ - platform: arm64
25
+ runs-on: ubuntu-24.04-arm
26
+ docker-platform: linux/arm64
27
+ runs-on: ${{ matrix.runs-on }}
28
+ steps:
29
+ - uses: actions/checkout@v6
30
+
31
+ - name: Cache Trivy
32
+ uses: actions/cache@v4
33
+ with:
34
+ path: ~/.cache/trivy
35
+ key: trivy-${{ runner.os }}-${{ matrix.platform }}
36
+ restore-keys: |
37
+ trivy-${{ runner.os }}-
38
+
39
+ - name: Set up Docker Buildx
40
+ uses: docker/setup-buildx-action@v3
41
+
42
+ - name: Build image
43
+ run: |
44
+ docker buildx build \
45
+ --load \
46
+ --platform "${{ matrix.docker-platform }}" \
47
+ -t "tracehub-mcp-server:${{ github.sha }}-${{ matrix.platform }}" \
48
+ .
49
+
50
+ - name: Trivy scan (JSON)
51
+ uses: aquasecurity/trivy-action@v0.35.0
52
+ with:
53
+ image-ref: tracehub-mcp-server:${{ github.sha }}-${{ matrix.platform }}
54
+ format: json
55
+ output: trivy-results-${{ matrix.platform }}.json
56
+ scanners: vuln,secret,license
57
+ vuln-type: os,library
58
+ severity: CRITICAL,HIGH,MEDIUM,LOW
59
+
60
+ - name: Convert Trivy results
61
+ run: |
62
+ set -euo pipefail
63
+ PREFIX="trivy-results-${{ matrix.platform }}"
64
+
65
+ trivy convert --format table --output "${PREFIX}.txt" "${PREFIX}.json"
66
+
67
+ if [[ "${{ github.event_name }}" != "pull_request" && "${{ github.ref }}" == "refs/heads/main" ]]; then
68
+ trivy convert --format sarif --output "${PREFIX}.sarif" "${PREFIX}.json"
69
+ fi
70
+
71
+ - name: Upload SARIF to GitHub Security
72
+ if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
73
+ uses: github/codeql-action/upload-sarif@v4
74
+ with:
75
+ sarif_file: trivy-results-${{ matrix.platform }}.sarif
76
+ category: container-security-tracehub-mcp-server-${{ matrix.platform }}
77
+
78
+ - name: Log full Trivy results
79
+ run: |
80
+ echo "::group::Full Trivy Scan Results (tracehub-mcp-server - ${{ matrix.platform }})"
81
+ RESULTS_FILE="trivy-results-${{ matrix.platform }}.txt"
82
+ if [ -s "$RESULTS_FILE" ]; then
83
+ cat "$RESULTS_FILE"
84
+ else
85
+ echo "✅ No vulnerabilities found!"
86
+ fi
87
+ echo "::endgroup::"
88
+
89
+ - name: Prepare PR comment
90
+ if: github.event_name == 'pull_request'
91
+ run: |
92
+ RESULTS_FILE="trivy-results-${{ matrix.platform }}.txt"
93
+ COMMENT_FILE="trivy-comment-${{ matrix.platform }}.md"
94
+ MAX_CHARS=60000
95
+ FILE_SIZE=$(wc -c < "$RESULTS_FILE")
96
+
97
+ {
98
+ echo "## 🔒 Container Vulnerability Scan (tracehub-mcp-server - ${{ matrix.platform }})"
99
+ echo ""
100
+ if [ ! -s "$RESULTS_FILE" ]; then
101
+ echo "✅ **No vulnerabilities found!**"
102
+ else
103
+ echo "<details>"
104
+ echo "<summary>Click to expand results</summary>"
105
+ echo ""
106
+ echo '```'
107
+ if [ "$FILE_SIZE" -gt "$MAX_CHARS" ]; then
108
+ head -c "$MAX_CHARS" "$RESULTS_FILE"
109
+ echo ""
110
+ echo "... (output truncated - exceeded ${MAX_CHARS} characters)"
111
+ echo "See full results in the 'Full Trivy Scan Results' step above"
112
+ else
113
+ cat "$RESULTS_FILE"
114
+ fi
115
+ echo '```'
116
+ echo ""
117
+ echo "</details>"
118
+ fi
119
+ } > "$COMMENT_FILE"
120
+
121
+ - name: Post PR comment
122
+ if: github.event_name == 'pull_request'
123
+ uses: marocchino/sticky-pull-request-comment@v2
124
+ with:
125
+ header: trivy-scan-tracehub-mcp-server-${{ matrix.platform }}
126
+ path: trivy-comment-${{ matrix.platform }}.md