Skip to content

feat(mcp): add WS-MCP-001 contributor server foundation#149

Open
ChuloWay wants to merge 57 commits into
Flow-Research:mainfrom
ChuloWay:oxvictor/ws-mcp-001-01-contributor-mcp-foundation
Open

feat(mcp): add WS-MCP-001 contributor server foundation#149
ChuloWay wants to merge 57 commits into
Flow-Research:mainfrom
ChuloWay:oxvictor/ws-mcp-001-01-contributor-mcp-foundation

Conversation

@ChuloWay

@ChuloWay ChuloWay commented Jul 18, 2026

Copy link
Copy Markdown

Workstream PR Trust Bundle

This PR body follows .github/pull_request_template.md and
.agent-loop/templates/PR_TRUST_BUNDLE.md.

Chunk

WS-MCP-001-01 - Contributor MCP Foundation

Merge intent: .agent-loop/merge-intents/WS-MCP-001-01.json

Goal

Add the WS-MCP-001 contributor MCP foundation without duplicating Workstream
authority or exposing backend lifecycle endpoints with incompatible contributor
semantics. This PR does not claim that the complete Sections 18 and 20 gate is
closed.

Human-Approved Intent

Link the initiative and chunk contract:

  • Intent: .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/INTENT.md
  • Chunk contract: .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/chunks/WS-MCP-001-01-contributor-mcp-foundation.md

What Changed

  • Added seven WS-MCP-001 resource types, seven tools, and zero prompts.
  • Restricted the production HTTP gateway to semantically compatible backend APIs.
  • Made contributor claim_task, release_task, and submit_task fail closed until atomic claim-to-work, contributor release, and durable idempotency APIs exist.
  • Kept the bounded temporary scenario gateway test-injected only; it is not selectable by runtime configuration.
  • Enforced UUID request IDs and strict submission/review input shapes.
  • Added safe upstream JSON/error handling, bearer-safe observability, and Streamable HTTP transport security. SSE is not supported.
  • Added authoritative /api/v1/auth/me validation before unavailable production surfaces, stable-reference/path hardening, and safe backend error-code preservation.
  • Scoped temporary idempotency and leases to the actor and completed the temporary resource representations needed for foundation testing.
  • Added a real MCP SDK client test for the Submitter and Reviewer journeys and proved no subscriptions or event-like capability is advertised.
  • Published MCP tool annotations that distinguish the read-only pre-submit check from the six state-changing lifecycle tools.
  • Addressed CodeRabbit's eleven findings with least-privilege CI, strict 90 percent coverage, complete redaction, revision/replay fixes, secure HTTP auth configuration, bounded inputs, and constant-space ASGI request replay.
  • Made Streamable HTTP verify tokens through existing Workstream Auth, isolated HTTP from the STDIO token, disabled bearer proxy inheritance, rejected anonymous streams before body buffering, and capped authenticated bodies by bytes, frames, and receive time.
  • Preserved the real ASGI receiver after bounded replay and added a real MCP SDK Streamable HTTP SSE journey.
  • Added an MCP operator README and completed the test-only revision-to-review loop with reviewed-submission references.
  • Published complete agent-facing descriptions, parameter metadata, examples, constraints, and typed output schemas for all seven tools.
  • Added direct sse-starlette test dependency ownership and strict MCP error signaling at the official SDK boundary.
  • Required strict coherent checker responses and exact validated Review Context references before publishing successful outcomes.
  • Kept malformed output-schema failures on the server-error path and aligned their operation telemetry with the client-visible infrastructure error.
  • Closed overlapping compact-UUID redaction, Auth-outage classification, locked-context error mapping, and local HTTP operator-documentation gaps found during final review.

Why It Changed

The original adapter could use backend endpoints whose lifecycle and authority
semantics did not match the contributor MCP specification. Failing closed is
the only correct MCP-side behavior until Workstream supplies compatible APIs.

Design Chosen

The MCP is a thin contributor protocol adapter. It forwards the issuer token to
Workstream, validates stable inputs, redacts outputs, logs only safe operation
metadata, verifies HTTP identity through existing Workstream Auth, and holds no workflow or business state. The scenario fixture exists
only for tests that exercise the public MCP contract while backend APIs are
unavailable or incompatible.

Alternatives Rejected

  • Direct database access, because it would bypass Workstream authority.
  • A generic API-call tool, because the v0.1 catalogue is closed.
  • Mapping contributor tools to backend routes with incompatible actor,
    lifecycle, or idempotency semantics.
  • Runtime scenario configuration, because temporary data must never become
    production truth.

Scope Control

Allowed Files Changed

  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/**
  • .agent-loop/merge-intents/WS-MCP-001-01.json
  • .github/workflows/backend.yml
  • mcp_server/**
  • scripts/check_internal_review_evidence.py
  • scripts/test_agent_gates.py

Files Outside Contract

  • None

Product Behavior

  • No Workstream product behavior changed.
  • Product behavior changed and is explained here: the MCP advertises the approved catalogue but truthfully returns workstream_temporarily_unavailable for surfaces that current backend APIs cannot safely implement.

Evidence

Commands Run

(cd mcp_server && /tmp/workstream-mcp-validation/bin/python -m ruff check .)
(cd mcp_server && /tmp/workstream-mcp-validation/bin/python -m pytest -q --cov=workstream_mcp --cov-report=term-missing --cov-fail-under=90 --cov-precision=2)
/tmp/workstream-backend-validation/bin/python scripts/check_stale_workstream_wording.py
/tmp/workstream-backend-validation/bin/python scripts/check_markdown_links.py
/tmp/workstream-backend-validation/bin/python scripts/check_stale_authorization_docs.py
/tmp/workstream-backend-validation/bin/python scripts/check_stale_artifact_contracts.py
/tmp/workstream-backend-validation/bin/python scripts/test_agent_gates.py
/tmp/workstream-backend-validation/bin/python scripts/check_internal_review_evidence.py
git diff --check
(cd backend && /tmp/workstream-backend-validation/bin/python -m ruff check app tests scripts)
(cd backend && /tmp/workstream-backend-validation/bin/python -m pytest -q tests/test_api_contract_e2e.py)

Result Summary

MCP tests: 112 passed at 95.25 percent statement coverage.
MCP ruff: passed.
Stale wording, Markdown, authorization, and artifact-contract checks: passed.
Agent gate regression: 88 passed.
Backend ruff: passed.
Focused backend API contract: 15 passed.
git diff --check: passed.

Acceptance Criteria Proof

The checked items below prove the foundation chunk criteria, not complete
WS-MCP-001 Sections 18 and 20 acceptance.

  • Seven resource types, seven tools, zero prompts: mcp_server/tests/test_catalogue.py.
  • Tokens stay transport/session scoped and are redacted from results and logs: test_auth.py, test_http_gateway.py, and test_runtime_safety.py.
  • Only compatible backend paths are called; incompatible lifecycle routes fail closed: test_http_gateway.py.
  • UUID request IDs and strict schemas are exposed at FastMCP runtime: test_catalogue.py.
  • Temporary lifecycle/review behavior is replay-safe only under explicit test injection: test_scenario_gateway.py.
  • Temporary replay and task/review leases are actor-scoped: test_scenario_gateway.py.
  • One temporary happy path for each journey works through a real MCP client session: test_protocol_journeys.py.
  • No resource subscriptions, list-change events, experimental channels, or MCP tasks are advertised: test_catalogue.py.
  • Tool annotations identify run_pre_submit_check as read-only and the six lifecycle tools as state-changing: test_catalogue.py.
  • Streamable HTTP tokens are verified through existing Workstream Auth and cannot fall back to STDIO credentials: test_auth.py, test_runtime_safety.py.
  • Submission, review, metadata, and authenticated HTTP body bytes, frames, and receive time are bounded before gateway work; anonymous streams reach immediate 401: test_catalogue.py, test_runtime_safety.py.
  • Bounded request replay preserves real ASGI disconnect delivery and an official SDK client completes Streamable HTTP initialization and tools/list: test_runtime_safety.py, test_protocol_journeys.py.
  • needs_revision persists findings and reviewed submission version, permits resubmission, and requeues review: test_scenario_gateway.py.
  • Checker failure remains a valid structured outcome: test_http_gateway.py.
  • All seven tool contracts publish complete agent guidance and typed input/output schemas through tools/list: test_catalogue.py and test_protocol_journeys.py.
  • SDK validation errors cannot echo bearer material into MCP responses or logs: test_protocol_journeys.py.
  • Malformed checker and review-claim gateway responses fail closed as MCP errors: test_protocol_journeys.py.
  • Output-schema failures remain server errors and log matching infrastructure-error telemetry: test_protocol_journeys.py.
  • Exactly one schema-v2 merge intent exists: .agent-loop/merge-intents/WS-MCP-001-01.json.

WS-MCP-001 Sections 18 And 20

This foundation does not yet prove complete v0.1 conformance or acceptance.
Authoritative production APIs are still required for project/task lists,
contributions, contributor claim/release/submission, and review operations.
Role/revocation coverage, revision and status outcomes, authoritative
concurrency/retry behavior, end-to-end transport equivalence, and the required
Inspector/client capture remain follow-up evidence.

Test Delta

Tests Added

  • mcp_server/tests/test_auth.py
  • mcp_server/tests/test_catalogue.py
  • mcp_server/tests/test_http_gateway.py
  • mcp_server/tests/test_protocol_journeys.py
  • mcp_server/tests/test_runtime_safety.py
  • mcp_server/tests/test_scenario_gateway.py

Tests Modified

  • scripts/test_agent_gates.py

Tests Removed Or Skipped

  • None

Internal Reviewer Results

Reviewed code SHA: 785336e

Reviewed at: 2026-07-20T07:10:23Z

Reviewer run IDs: 019f7cca-7065-7fc3-a102-100773738da9, 019f7cca-7137-7471-a6c9-87703eb97476, 019f7cca-71c0-7301-8f89-f54e37ae8f96, 019f7cca-72d3-7da0-9447-f01a0a08b2f8, 019f7cca-73d2-74e0-ada5-91b8f8c75fc3, 019f7cca-758c-7871-9c3f-8a5a1d28fa83, 019f7ccc-9823-7552-9941-0e5747ba8640, 019f7ccc-98e7-7021-9da3-a5cb3d343db8, 019f7ccc-998c-7420-bed8-92bee8378219

Reviewer Result Blocking Findings Notes
Senior engineering PASS WITH LOW RISKS none No actionable exact-head engineering findings; unavailable authoritative APIs remain explicit follow-up work.
QA/test PASS WITH LOW RISKS none 112 tests pass at 95.25 percent coverage, including agent-facing catalogue, distinct input/output error boundaries, and real SDK HTTP journeys.
Security/auth PASS WITH LOW RISKS none Existing Auth verification, exact bearer-equivalent redaction, actor isolation, and retryable Auth outage handling are covered.
Product/ops PASS AFTER FIXES none Revision context and requeue are complete in the fixture; unavailable production outcomes remain truthful.
Architecture PASS WITH LOW RISKS none No backend, persistence, or session ownership moved into MCP.
CI integrity PASS WITH LOW RISKS none Least privilege and a two-decimal 90 percent coverage gate are enforced; current main at 42a89b2 is integrated without changing MCP files.
Docs PASS WITH LOW RISKS none Initiative and operator docs are accurate; composed task reads await an authoritative aggregate API for snapshot consistency.
Reuse/dedup PASS none Boundary validation, mapping, replay, and observability remain centralized.
Test delta PASS WITH LOW RISKS none The remediation set is covered; direct 429/5xx verifier branch cases remain a low test risk.

External Review

External review response file:

  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-external-review-response.md
Source Status Notes
Maintainer Findings addressed locally; confirmation pending Complete agent-facing tool contracts are implemented and protocol-tested through reconciled head 785336e.
CodeRabbit Findings addressed locally; re-review pending Original findings remain addressed through reconciled head 785336e; rerun after push.
GitHub checks Pending Checks must run against the final branch head after push.

CI And Gate Integrity

  • No workflow weakening.
  • No lint/test/docstring gate weakening.
  • No coverage threshold weakening.
  • No package script weakening.
  • No unpinned new GitHub Action.
  • Checkout credential persistence disabled where checkout is used.

Remaining Risks

  • Review, contribution, contributor-list, atomic contributor claim/release, and durable submission-idempotency APIs are still missing.
  • This MCP chunk cannot provide those actions in production until compatible backend contracts land.
  • Full backend database tests require CI or a configured WORKSTREAM_TEST_DATABASE_URL; local focused backend contract tests pass.
  • Full WS-MCP-001 acceptance remains open for the authoritative and transport evidence listed above.
  • Composed task resources cannot guarantee a cross-request snapshot until an authoritative aggregate API exists.
  • Auth network-outage and protocol-level 503 behavior are covered; direct 429/5xx verifier branch cases remain a low test risk.

Follow-Up Work

Replace every test-only scenario method with real HTTP gateway calls when the
required contributor-list, lifecycle, contribution, and review API contracts
land, then close the remaining Sections 18 and 20 evidence.

Human Review Focus

Please inspect:

  • fail-closed lifecycle boundaries;
  • token propagation and redaction behavior;
  • stable-reference and actor-lease isolation;
  • Streamable HTTP host/origin allowlists;
  • the distinction between the production gateway and test-only scenario fixture;
  • the explicit boundary between foundation readiness and full v0.1 acceptance.

Human Merge Ownership

  • I can explain what changed.
  • I can explain why it changed.
  • I know what could break.
  • I accept the remaining risks.
  • The user explicitly approved this specific PR for merge.

Summary by CodeRabbit

  • New Features
    • Added a contributor-facing MCP server with resources for projects, contributions, tasks, task status, and reviews.
    • Added tools for task and review claiming, releasing, submissions, decisions, and pre-submission checks.
    • Added STDIO and Streamable HTTP transport support with authenticated requests.
  • Security
    • Added strict token validation, secret redaction, bounded inputs, secure transport configuration, and safe error responses.
  • Documentation
    • Added setup, configuration, usage, and production capability guidance.
  • Tests
    • Added comprehensive coverage for workflows, authentication, transport behavior, retries, and failure handling.

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds the WS-MCP-001 contributor-facing MCP server with a closed v0.1 catalogue, authenticated HTTP forwarding, fail-closed unavailable surfaces, deterministic temporary fixtures, secret redaction, runtime safety controls, comprehensive test coverage, and CI/review evidence integration.

Changes

Contributor MCP foundation

Layer / File(s) Summary
Initiative contract and acceptance evidence
.agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/*, .agent-loop/merge-intents/WS-MCP-001-01.json
Defines initiative scope, chunk sequencing, acceptance boundaries, risks, discovery findings, status, internal/external review evidence, and PR trust-bundle documentation.
MCP contracts, config, auth, and errors
mcp_server/pyproject.toml, mcp_server/workstream_mcp/__init__.py, mcp_server/workstream_mcp/__main__.py, mcp_server/workstream_mcp/config.py, mcp_server/workstream_mcp/auth.py, mcp_server/workstream_mcp/errors.py, mcp_server/workstream_mcp/gateway.py, mcp_server/workstream_mcp/schemas.py
Defines package metadata and entry points, closed catalogues and schema constraints, authentication contexts with token verification and bearer redaction, configuration validation with auth issuer security requirements, and safe MCP error mapping.
HTTP gateway, resources, and tools
mcp_server/workstream_mcp/http_gateway.py, mcp_server/workstream_mcp/resources.py, mcp_server/workstream_mcp/tools.py
Routes operations through authenticated HTTP gateways or explicit unavailable responses, implements resource/tool handlers with input validation and redaction, maps upstream errors to stable MCP error codes.
Observability and FastMCP server runtime
mcp_server/workstream_mcp/observability.py, mcp_server/workstream_mcp/server.py
Implements secret-safe operation logging, request-size limiting ASGI middleware, FastMCP transport selection and authentication wiring, and tool handler registration with input validation sanitization.
Deterministic temporary lifecycle gateway
mcp_server/workstream_mcp/scenario_gateway.py
Implements in-memory fixture state for projects, tasks, contributions, and reviews with actor-scoped leases, state transitions, idempotency conflict detection, and fail-closed validation.
Authentication, catalogue, and validation tests
mcp_server/tests/test_auth.py, mcp_server/tests/test_catalogue.py
Comprehensive tests for bearer-token handling, UUID-equivalent secret detection and redaction, context creation, auth verifier behavior, catalogue closure enforcement, input bounds, and stable reference validation.
HTTP gateway, protocol journey, and scenario gateway tests
mcp_server/tests/test_http_gateway.py, mcp_server/tests/test_protocol_journeys.py, mcp_server/tests/test_scenario_gateway.py
Exercises HTTP gateway fail-closed behavior, pre-submit checks, error mapping, bearer redaction, and resource composition; validates full MCP protocol flows with submitter/reviewer journeys, idempotency, and deterministic fixture lifecycle consistency.
Runtime safety, configuration, and observability tests
mcp_server/tests/test_runtime_safety.py
Validates configuration fail-closed behavior, auth issuer HTTPS enforcement, ASGI request-size middleware with frame and timeout limits, secret-safe operation logging, outcome classification, and idempotent replay telemetry.
CI workflows, documentation, and review gate integration
.github/workflows/backend.yml, mcp_server/README.md, scripts/check_internal_review_evidence.py, scripts/test_agent_gates.py
Adds GitHub Actions MCP server CI job with coverage gates, operator-facing README documenting transports and capability boundaries, and updates internal review evidence gates to recognize MCP paths and review tracks.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant FastMCP
  participant Tools
  participant Gateway
  participant WorkstreamAPI
  Client->>FastMCP: Call resource or lifecycle tool
  FastMCP->>Tools: Validate request and create RequestContext
  Tools->>Gateway: Forward authenticated operation
  Gateway->>WorkstreamAPI: Send HTTP with authorization headers
  WorkstreamAPI-->>Gateway: Return data or error response
  Gateway-->>Tools: Return structured result or mapped error
  Tools-->>Client: Return redacted MCP result with error code
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 81.43% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise, specific, and accurately reflects the main change: adding the WS-MCP-001 contributor server foundation.
Description check ✅ Passed The PR body matches the trust-bundle template and covers all required sections with substantive content.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (1)
mcp_server/workstream_mcp/schemas.py (1)

147-190: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add maximum bounds to unconstrained strings and lists.

Several fields (e.g., notes, summary, worker_attestation, artifact_hash_manifest, and evidence_items) currently accept unbounded input lengths or sizes. Bounding these inputs at the MCP adapter edge protects the server from excessive memory allocation when processing deliberately oversized payload submissions.

Consider applying safe max_length constraints to these textual strings and collections. For example:

    summary: str = Field(min_length=1, max_length=10000)
    worker_attestation: str = Field(min_length=1, max_length=20000)
    artifact_hash_manifest: list[ArtifactHashEntryInput] = Field(min_length=1, max_length=1000)
    evidence_items: list[EvidenceItemInput] = Field(default_factory=list, max_length=1000)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@mcp_server/workstream_mcp/schemas.py` around lines 147 - 190, Add explicit
maximum bounds to the unconstrained fields in ArtifactHashEntryInput,
EvidenceItemInput, and SubmissionInput: constrain notes, summary, and
worker_attestation with appropriate max_length values, and constrain
artifact_hash_manifest and evidence_items with collection max_length values.
Preserve the existing minimum bounds, defaults, and nested model validation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/backend.yml:
- Around line 10-16: Add least-privilege token permissions for the mcp-server
job by declaring contents: read at workflow or job scope near the mcp-server
definition. Preserve the existing checkout and test steps while preventing
inherited write permissions.
- Around line 32-34: Update the “MCP tests” workflow step to run pytest with
coverage measurement and enforce a minimum total coverage of 90%, while
preserving the existing quiet test execution and mcp_server working directory.

In `@mcp_server/workstream_mcp/auth.py`:
- Around line 126-135: Update redact_secrets to handle set values by recursively
redacting each member and returning a set of the transformed members, matching
the existing list and tuple behavior while preserving non-collection values
unchanged.

In `@mcp_server/workstream_mcp/scenario_gateway.py`:
- Around line 536-550: Update the submit_review flow before _store_replay to
handle a valid needs_revision decision: persist the review findings and
transition the associated task from review_pending to needs_revision. Ensure
get_task_status can report this persisted lifecycle state so the contributor can
submit a revision, while preserving the existing replay result storage.
- Around line 580-598: Update _replay to add an idempotent_replay marker to the
deep-copied result before returning it, while leaving the cached result stored
in _replays unchanged. Preserve the existing conflict validation and return
behavior for matching retries.
- Around line 347-355: Update the review retrieval logic around the state check
in the scenario gateway so any review with state "none_available" returns only
the minimal source, project_id, and state response. Ensure the completed
review’s routing reference, lease data, review reference, and context URI are
not exposed, while preserving the existing leased-to-other-actor behavior and
normal review response.
- Around line 421-434: Move the _replay call and its early return in the
claim_review flow before the project_id and review_routing_ref fixture-match
validation. This ensures reused request IDs are checked first and can return
idempotency_conflict for differing inputs, while preserving the existing
REVIEW_NOT_AVAILABLE validation for non-replayed requests.

In `@mcp_server/workstream_mcp/schemas.py`:
- Around line 267-278: Reorder the checks in normalize_stable_ref so the
normalized value is compared against "." and ".." before applying
STABLE_REF_PATTERN.fullmatch. Preserve the existing blank validation and
specific relative-path error, while leaving the regex validation unchanged for
all other values.

In `@mcp_server/workstream_mcp/server.py`:
- Around line 93-100: Update the AuthSettings configuration used by the server
setup to require WORKSTREAM_MCP_AUTH_ISSUER_URL explicitly and reject missing or
non-HTTPS values by default. Remove the implicit http://workstream.local
fallback; if a local insecure issuer is supported, gate it behind an explicit
development-only override while preserving WorkstreamForwardingTokenVerifier for
external token verification.

---

Nitpick comments:
In `@mcp_server/workstream_mcp/schemas.py`:
- Around line 147-190: Add explicit maximum bounds to the unconstrained fields
in ArtifactHashEntryInput, EvidenceItemInput, and SubmissionInput: constrain
notes, summary, and worker_attestation with appropriate max_length values, and
constrain artifact_hash_manifest and evidence_items with collection max_length
values. Preserve the existing minimum bounds, defaults, and nested model
validation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9853d225-4b01-47a5-9aa8-e20d45359b1d

📥 Commits

Reviewing files that changed from the base of the PR and between f18b620 and bb1d4df.

📒 Files selected for processing (34)
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/CHUNK_MAP.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/DISCOVERY.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/INTENT.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/PLAN.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/RISKS.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/STATUS.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/chunks/WS-MCP-001-01-contributor-mcp-foundation.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-external-review-response.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-internal-review-evidence.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-pr-trust-bundle.md
  • .agent-loop/merge-intents/WS-MCP-001-01.json
  • .github/workflows/backend.yml
  • mcp_server/pyproject.toml
  • mcp_server/tests/test_auth.py
  • mcp_server/tests/test_catalogue.py
  • mcp_server/tests/test_http_gateway.py
  • mcp_server/tests/test_protocol_journeys.py
  • mcp_server/tests/test_runtime_safety.py
  • mcp_server/tests/test_scenario_gateway.py
  • mcp_server/workstream_mcp/__init__.py
  • mcp_server/workstream_mcp/__main__.py
  • mcp_server/workstream_mcp/auth.py
  • mcp_server/workstream_mcp/config.py
  • mcp_server/workstream_mcp/errors.py
  • mcp_server/workstream_mcp/gateway.py
  • mcp_server/workstream_mcp/http_gateway.py
  • mcp_server/workstream_mcp/observability.py
  • mcp_server/workstream_mcp/resources.py
  • mcp_server/workstream_mcp/scenario_gateway.py
  • mcp_server/workstream_mcp/schemas.py
  • mcp_server/workstream_mcp/server.py
  • mcp_server/workstream_mcp/tools.py
  • scripts/check_internal_review_evidence.py
  • scripts/test_agent_gates.py

Comment thread .github/workflows/backend.yml Outdated
Comment thread .github/workflows/backend.yml Outdated
Comment thread mcp_server/workstream_mcp/auth.py
Comment thread mcp_server/workstream_mcp/scenario_gateway.py
Comment thread mcp_server/workstream_mcp/scenario_gateway.py Outdated
Comment thread mcp_server/workstream_mcp/scenario_gateway.py
Comment thread mcp_server/workstream_mcp/scenario_gateway.py Outdated
Comment thread mcp_server/workstream_mcp/schemas.py
Comment thread mcp_server/workstream_mcp/server.py Outdated
Comment on lines +93 to +100
auth=AuthSettings(
issuer_url=os.environ.get(
"WORKSTREAM_MCP_AUTH_ISSUER_URL",
"http://workstream.local",
),
resource_server_url=None,
),
token_verifier=WorkstreamForwardingTokenVerifier(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Fail closed when the external authentication issuer is missing.

Defaulting to http://workstream.local lets HTTP mode start with an implicit cleartext authentication trust configuration. Require an explicitly configured HTTPS issuer, with any local insecure override made deliberate and development-only.

As per coding guidelines, Workstream must verify external Flow authentication tokens and must not own primary authentication sessions.

🧰 Tools
🪛 ast-grep (0.44.1)

[warning] 95-95: Do not make http calls without encryption
Context: "http://workstream.local"
Note: [CWE-319] Cleartext Transmission of Sensitive Information.

(requests-http)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@mcp_server/workstream_mcp/server.py` around lines 93 - 100, Update the
AuthSettings configuration used by the server setup to require
WORKSTREAM_MCP_AUTH_ISSUER_URL explicitly and reject missing or non-HTTPS values
by default. Remove the implicit http://workstream.local fallback; if a local
insecure issuer is supported, gate it behind an explicit development-only
override while preserving WorkstreamForwardingTokenVerifier for external token
verification.

Sources: Coding guidelines, Linters/SAST tools

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@mcp_server/workstream_mcp/server.py`:
- Around line 54-72: Update the request buffering and replay logic around the
receive loop and replay_receive so memory is bounded by both body data and the
number of ASGI frames, including repeated zero-length more_body frames. Prefer
coalescing request bodies into a bounded bytearray and replaying through a
constant-time queue/deque, or enforce an explicit frame limit while retaining
all required message semantics; preserve rejection through self._reject(send)
when limits are exceeded.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a8e4e0cd-5bf3-4263-9c92-68162040dd68

📥 Commits

Reviewing files that changed from the base of the PR and between bb1d4df and 65f1d2c.

📒 Files selected for processing (19)
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/DISCOVERY.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/STATUS.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-external-review-response.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-internal-review-evidence.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-pr-trust-bundle.md
  • .github/workflows/backend.yml
  • mcp_server/README.md
  • mcp_server/pyproject.toml
  • mcp_server/tests/test_auth.py
  • mcp_server/tests/test_catalogue.py
  • mcp_server/tests/test_http_gateway.py
  • mcp_server/tests/test_runtime_safety.py
  • mcp_server/tests/test_scenario_gateway.py
  • mcp_server/workstream_mcp/auth.py
  • mcp_server/workstream_mcp/config.py
  • mcp_server/workstream_mcp/http_gateway.py
  • mcp_server/workstream_mcp/scenario_gateway.py
  • mcp_server/workstream_mcp/schemas.py
  • mcp_server/workstream_mcp/server.py
🚧 Files skipped from review as they are similar to previous changes (10)
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/STATUS.md
  • .github/workflows/backend.yml
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/DISCOVERY.md
  • mcp_server/pyproject.toml
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-internal-review-evidence.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-pr-trust-bundle.md
  • mcp_server/workstream_mcp/auth.py
  • mcp_server/workstream_mcp/schemas.py
  • mcp_server/workstream_mcp/http_gateway.py
  • mcp_server/workstream_mcp/scenario_gateway.py

Comment thread mcp_server/workstream_mcp/server.py Outdated
@Abiorh001

Copy link
Copy Markdown
Collaborator

@ChuloWay fix the conflict

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@mcp_server/tests/test_protocol_journeys.py`:
- Line 16: Declare sse-starlette as a direct test dependency in
mcp_server/pyproject.toml so the AppStatus import in test_protocol_journeys.py
does not rely on a transitive installation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4f3c2ee9-17cd-43a6-9ee3-309e8cf9e680

📥 Commits

Reviewing files that changed from the base of the PR and between 65f1d2c and 966c4e0.

📒 Files selected for processing (9)
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/STATUS.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-external-review-response.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-internal-review-evidence.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-pr-trust-bundle.md
  • mcp_server/README.md
  • mcp_server/tests/test_protocol_journeys.py
  • mcp_server/tests/test_runtime_safety.py
  • mcp_server/workstream_mcp/server.py
  • scripts/test_agent_gates.py
🚧 Files skipped from review as they are similar to previous changes (7)
  • mcp_server/README.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/STATUS.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-external-review-response.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-pr-trust-bundle.md
  • scripts/test_agent_gates.py
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-internal-review-evidence.md
  • mcp_server/workstream_mcp/server.py

Comment thread mcp_server/tests/test_protocol_journeys.py
@Abiorh001

Abiorh001 commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

@ChuloWay

Requesting changes on the MCP agent-facing contract.

The issue is that the current tools/list metadata does not give an agent enough information to use these tools reliably.

Please update all seven tools as follows:

  1. Expand each registered tool docstring into a complete agent-facing description that explains:

    • exactly what the tool does;
    • when to use it;
    • when not to use it;
    • required lifecycle state and prerequisites;
    • where identifiers must be obtained;
    • side effects;
    • successful and unsuccessful outcomes;
    • what resource should be read next.
  2. Add Annotated[..., Field(...)] metadata or equivalent reusable typed aliases to every registered parameter. Include descriptions, constraints, accepted formats, defaults, and examples.

    This must be done on the actual decorated FastMCP function signatures. The internal ClaimTaskInput, ReleaseTaskInput, and related validation models are not the schema source used by tools/list.

  3. Document request_id explicitly:

    • create a new UUID for every new logical operation;
    • reuse the same UUID only when retrying the exact same operation;
    • never reuse it for a different task, review, or action.
  4. Add descriptions and examples to all nested submission and review fields, including:

    • summary;
    • package_uri;
    • package_hash;
    • artifact_hash_manifest;
    • worker_attestation;
    • evidence_items;
    • review decisions and findings.
  5. Replace dict[str, Any] tool return annotations with structured Pydantic result models so FastMCP publishes meaningful outputSchema definitions and validates returned structured content.

  6. Do not return validation, authorization, backend, or unexpected failures as ordinary successful dictionaries. Raise ToolError or return CallToolResult(isError=True) so MCP clients and agents can correctly distinguish failed executions from valid business outcomes.

  7. Wire the existing catalogue titles and descriptions into the actual MCP registrations rather than keeping static catalogue metadata that is separate from the wire-level definitions.

  8. Extend test_catalogue.py and the protocol tests to assert:

    • exact tool descriptions;
    • parameter descriptions and examples;
    • important validation constraints;
    • tool titles;
    • meaningful output schemas;
    • isError=True for execution failures;
    • isError=False for valid negative outcomes such as a completed pre-submit check that does not pass.

The server architecture, closed catalogue, transport security, redaction, and gateway boundaries are strong. These changes are needed because the MCP schema and descriptions are the primary interface through which an agent understands and safely invokes the tools.

https://gofastmcp.com/getting-started/welcome

@ChuloWay

Copy link
Copy Markdown
Author

@ChuloWay

Requesting changes on the MCP agent-facing contract.

The issue is that the current tools/list metadata does not give an agent enough information to use these tools reliably.

Please update all seven tools as follows:

  1. Expand each registered tool docstring into a complete agent-facing description that explains:

    • exactly what the tool does;
    • when to use it;
    • when not to use it;
    • required lifecycle state and prerequisites;
    • where identifiers must be obtained;
    • side effects;
    • successful and unsuccessful outcomes;
    • what resource should be read next.
  2. Add Annotated[..., Field(...)] metadata or equivalent reusable typed aliases to every registered parameter. Include descriptions, constraints, accepted formats, defaults, and examples.
    This must be done on the actual decorated FastMCP function signatures. The internal ClaimTaskInput, ReleaseTaskInput, and related validation models are not the schema source used by tools/list.

  3. Document request_id explicitly:

    • create a new UUID for every new logical operation;
    • reuse the same UUID only when retrying the exact same operation;
    • never reuse it for a different task, review, or action.
  4. Add descriptions and examples to all nested submission and review fields, including:

    • summary;
    • package_uri;
    • package_hash;
    • artifact_hash_manifest;
    • worker_attestation;
    • evidence_items;
    • review decisions and findings.
  5. Replace dict[str, Any] tool return annotations with structured Pydantic result models so FastMCP publishes meaningful outputSchema definitions and validates returned structured content.

  6. Do not return validation, authorization, backend, or unexpected failures as ordinary successful dictionaries. Raise ToolError or return CallToolResult(isError=True) so MCP clients and agents can correctly distinguish failed executions from valid business outcomes.

  7. Wire the existing catalogue titles and descriptions into the actual MCP registrations rather than keeping static catalogue metadata that is separate from the wire-level definitions.

  8. Extend test_catalogue.py and the protocol tests to assert:

    • exact tool descriptions;
    • parameter descriptions and examples;
    • important validation constraints;
    • tool titles;
    • meaningful output schemas;
    • isError=True for execution failures;
    • isError=False for valid negative outcomes such as a completed pre-submit check that does not pass.

The server architecture, closed catalogue, transport security, redaction, and gateway boundaries are strong. These changes are needed because the MCP schema and descriptions are the primary interface through which an agent understands and safely invokes the tools.

https://gofastmcp.com/getting-started/welcome

Thanks @Abiorh001 , I’ve addressed the requested changes and updated the PR.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
mcp_server/workstream_mcp/http_gateway.py (1)

249-254: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider sharing one httpx.AsyncClient across the composed requests.

_request opens and closes a new AsyncClient on every call. For get_task_context (4 sequential calls) and get_task_status (up to 3 calls) this means repeated TCP/TLS handshakes to the same host with no connection pooling. Consider constructing the client once per gateway operation (or per gateway instance) and reusing it across the composed sub-requests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@mcp_server/workstream_mcp/http_gateway.py` around lines 249 - 254, Update the
request flow around _request, get_task_context, and get_task_status to reuse a
single httpx.AsyncClient for all sub-requests within one gateway operation
instead of creating one per call. Preserve the existing base_url, timeout,
transport, and trust_env configuration, and ensure the shared client is closed
after the composed operation completes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@mcp_server/workstream_mcp/http_gateway.py`:
- Around line 249-254: Update the request flow around _request,
get_task_context, and get_task_status to reuse a single httpx.AsyncClient for
all sub-requests within one gateway operation instead of creating one per call.
Preserve the existing base_url, timeout, transport, and trust_env configuration,
and ensure the shared client is closed after the composed operation completes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c0687e1c-e395-47e9-8b83-d789cd9a76ee

📥 Commits

Reviewing files that changed from the base of the PR and between 60057b5 and 3bc877b.

📒 Files selected for processing (22)
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/STATUS.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-external-review-response.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-internal-review-evidence.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/reviews/WS-MCP-001-01-pr-trust-bundle.md
  • .github/workflows/backend.yml
  • mcp_server/README.md
  • mcp_server/tests/test_auth.py
  • mcp_server/tests/test_catalogue.py
  • mcp_server/tests/test_http_gateway.py
  • mcp_server/tests/test_protocol_journeys.py
  • mcp_server/tests/test_scenario_gateway.py
  • mcp_server/workstream_mcp/auth.py
  • mcp_server/workstream_mcp/errors.py
  • mcp_server/workstream_mcp/gateway.py
  • mcp_server/workstream_mcp/http_gateway.py
  • mcp_server/workstream_mcp/observability.py
  • mcp_server/workstream_mcp/resources.py
  • mcp_server/workstream_mcp/scenario_gateway.py
  • mcp_server/workstream_mcp/schemas.py
  • mcp_server/workstream_mcp/server.py
  • mcp_server/workstream_mcp/tools.py
  • scripts/test_agent_gates.py
🚧 Files skipped from review as they are similar to previous changes (10)
  • mcp_server/README.md
  • .agent-loop/initiatives/WS-MCP-001-contributor-mcp-server/STATUS.md
  • .github/workflows/backend.yml
  • mcp_server/workstream_mcp/gateway.py
  • mcp_server/workstream_mcp/observability.py
  • mcp_server/workstream_mcp/resources.py
  • scripts/test_agent_gates.py
  • mcp_server/workstream_mcp/errors.py
  • mcp_server/tests/test_catalogue.py
  • mcp_server/workstream_mcp/schemas.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants