Skip to content

Commit 0eabf30

Browse files
Codebase quality, security & performance improvements (#52)
* Add plan 2: codebase quality, security & performance improvements Comprehensive plan covering URL encoding, WIQL escaping, JSON Pointer escaping, CSV formula injection mitigation, error handling improvements, input validation, performance optimizations, Docker security, CI/CD enhancements, and expanded test coverage. * Implement US1-US5: security, quality, performance, infrastructure US1: URL-encode all user-controlled path segments in Azure API client and modules; escape WIQL project/date fields; add RFC 6901 JSON Pointer escaping for patch paths. US2: Add CSV formula injection mitigation via sanitize_csv_value helper that prefixes dangerous characters (=, +, -, @) with a single quote. US3: Remove duplicate board types from models.rs; replace all unwrap() on serialization in 11 MCP tool files with map_err; add non-empty string validation to team_id, board_id, work_item_type, title, link_type. US4: Parallelize comment fetching with bounded concurrency (10); add recursion depth limits (64) to JSON processing; add HTTP connection limits (256) and timeouts (60s) with semaphore; use HashSet for board work item type deduplication. US5: Add non-root user to Docker runtime; add clippy and cargo-audit to CI; add Linux aarch64 to CD release with cleanup steps. * Implement US6-US8: comprehensive test coverage US6: Add 9 new compact_llm unit tests covering empty structures, Unicode, control characters, deeply nested objects, max depth truncation, long strings, empty string values, and mixed arrays. US7: Add 24 new error-propagation tests and ~25 content-verification tests across all 8 integration test files, covering every MCP tool's error paths and output structure. US8: Add HTTP server integration tests (connection acceptance, invalid method rejection) and 4 CLI argument parsing unit tests. * Apply cargo fmt formatting * Fix HTTP server test and add test-support constructor Add new_with_api constructor to AzureMcpServer (behind test-support feature flag) to enable HTTP server integration tests with MockAzureDevOpsApi. Fix Accept header in HTTP test and work item Type assertion. * Mark US9 final verification complete in plan All T9.1 verification checkboxes confirmed and marked complete. make all passes with zero warnings, all 134 tests green. * Update Cargo.lock for futures dependency * Fix rustfmt formatting for Rust 1.94.0 Reformat build.rs and test_tools_work_items.rs to match the latest stable rustfmt (1.94.0) line-length rules for push_str and assert!. * Remove dead code, fix SSE timeout, and correct GET test - Remove unused `BoardDetail::get_work_item_types()` and `HashSet` import - Remove 60s connection timeout that would kill SSE streams; MCP Streamable HTTP uses GET for long-lived SSE connections - Fix invalid-method test to use PUT instead of GET (GET is valid for SSE) - Add `test_http_server_accepts_get_for_sse` verifying GET is accepted
1 parent 8dd0571 commit 0eabf30

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+3196
-146
lines changed

.github/workflows/cd-tag-build-and-release.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,24 @@ jobs:
7575
- name: List downloaded files (debug)
7676
run: ls -R dist
7777

78+
- name: Prepare Linux tar.gz
79+
run: |
80+
set -eux
81+
TAG="${GITHUB_REF_NAME}"
82+
LINUX_DIR="dist/mcp-for-azure-devops-boards-ubuntu-24.04-aarch64"
83+
cp "${LINUX_DIR}/mcp-for-azure-devops-boards-ubuntu-24.04-aarch64" mcp-for-azure-devops-boards
84+
tar czf "mcp-for-azure-devops-boards-${TAG}-linux-aarch64.tar.gz" mcp-for-azure-devops-boards
85+
rm mcp-for-azure-devops-boards
86+
ls -l "mcp-for-azure-devops-boards-${TAG}-linux-aarch64.tar.gz"
87+
7888
- name: Prepare macOS tar.gz
7989
run: |
8090
set -eux
8191
TAG="${GITHUB_REF_NAME}"
82-
# artifact directory is dist/<artifact-name>/...
8392
MAC_DIR="dist/mcp-for-azure-devops-boards-macos-aarch64"
8493
cp "${MAC_DIR}/mcp-for-azure-devops-boards-macos-aarch64" mcp-for-azure-devops-boards
8594
tar czf "mcp-for-azure-devops-boards-${TAG}-macos-aarch64.tar.gz" mcp-for-azure-devops-boards
95+
rm mcp-for-azure-devops-boards
8696
ls -l "mcp-for-azure-devops-boards-${TAG}-macos-aarch64.tar.gz"
8797
8898
- name: Prepare Windows zip
@@ -105,6 +115,7 @@ jobs:
105115
name: ${{ github.ref_name }}
106116
generate_release_notes: true
107117
files: |
118+
mcp-for-azure-devops-boards-${{ github.ref_name }}-linux-aarch64.tar.gz
108119
mcp-for-azure-devops-boards-${{ github.ref_name }}-macos-aarch64.tar.gz
109120
mcp-for-azure-devops-boards-${{ github.ref_name }}-windows-x86_64.zip
110121
env:

.github/workflows/ci-pr-build-and-test.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,34 @@ jobs:
3434

3535
- name: Setup Rust
3636
uses: actions-rust-lang/setup-rust-toolchain@v1
37+
with:
38+
components: clippy
3739

3840
- name: Build
3941
run: cargo build --release --locked
4042

43+
- name: Clippy
44+
run: cargo clippy --features test-support --locked -- -D warnings
45+
4146
- name: Test
4247
run: cargo test --release --locked --all-features
4348

49+
security-audit:
50+
name: Security Audit
51+
runs-on: ubuntu-latest
52+
steps:
53+
- name: Checkout
54+
uses: actions/checkout@v5
55+
56+
- name: Setup Rust
57+
uses: actions-rust-lang/setup-rust-toolchain@v1
58+
59+
- name: Install cargo-audit
60+
run: cargo install cargo-audit --locked
61+
62+
- name: Security audit
63+
run: cargo audit
64+
4465
formatting:
4566
name: cargo fmt
4667
runs-on: ubuntu-latest

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ csv = "1.4"
4040
regex = "1.11"
4141
once_cell = "1.20"
4242
urlencoding = "2.1"
43+
futures = "0.3"
4344

4445
[dev-dependencies]
4546

Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,12 @@ LABEL maintainer="Daniele Salvatore Albano <d.albano@gmail.com>"
3333

3434
RUN apk update && apk add --no-cache ca-certificates tzdata
3535

36+
RUN adduser -D -g '' appuser
37+
3638
WORKDIR /app
3739

3840
COPY --from=builder /app/target/release/mcp-for-azure-devops-boards /usr/local/bin/mcp-for-azure-devops-boards
3941

42+
USER appuser
43+
4044
ENTRYPOINT ["mcp-for-azure-devops-boards"]

build.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,15 @@ fn generate_tool_router_code(tools: &[ToolInfo]) -> String {
171171
code.push_str(" tool_router: Self::tool_router(),\n");
172172
code.push_str(" }\n");
173173
code.push_str(" }\n\n");
174+
code.push_str(" #[cfg(feature = \"test-support\")]\n");
175+
code.push_str(
176+
" pub fn new_with_api(client: impl AzureDevOpsApi + Send + Sync + 'static) -> Self {\n",
177+
);
178+
code.push_str(" Self {\n");
179+
code.push_str(" client: Arc::new(client),\n");
180+
code.push_str(" tool_router: Self::tool_router(),\n");
181+
code.push_str(" }\n");
182+
code.push_str(" }\n\n");
174183

175184
for tool in tools {
176185
code.push_str(&format!(

0 commit comments

Comments
 (0)