Skip to main content
Glama
tonomr

production-mcp-server

by tonomr
README.md
# Production MCP Server Lab

This repository completes the Lab 3-B MCP server and the Lab 3-C Cloud Agent CI exercise. It exposes immutable CAN signal and MISRA reference facts as resources, and exposes ticket filing as a human-gated tool.

## Setup

Use the existing Python 3.14 virtual environment. Supply secret values only through the process environment; never put them in source, `.env` files, or committed configuration.

```bash
export BOSCH_MCP_TOKEN="..."
export TRACKER_TOKEN="..."
export AUDIT_LOG_PATH="$PWD/audit.log.jsonl"
.venv/bin/python mcp_server.py --selftest
.venv/bin/python mcp_client_test.py
.venv/bin/python verify_audit.py
```

`mcp_client_test.py` prints the required `PENDING_CONFIRMATION` and `CREATED` terminal evidence. To demonstrate tampering, copy the log, edit or delete one JSONL record, then run `verify_audit.py` against the copy; it exits nonzero and identifies the first broken line.

## Resource and Tool Split

`signal://{message}/{signal}` and `misra://{rule_id}` are resources because they are stable, addressable, read-only reference data. `raise_defect` is a tool because it can create a downstream ticket, which is an external side effect; it first returns `PENDING_CONFIRMATION` and creates nothing until a human-approved second call specifies `confirm=true`.

## Security Reasoning

A stdio MCP server has no spec-defined per-call caller authentication: it inherits the trust boundary of the local process that spawned it. Streamable HTTP can layer authenticated transport and session credentials with authorization on each request, so production deployments should bind identity and scope to each tool call.

The confirmation gate is intentionally stateless. A hostile client can send `confirm=true` directly, so this exercise demonstrates human-in-the-loop workflow rather than cryptographic authorization. Production needs a durable approval record bound to authenticated actor, arguments, and expiration, or spec-native elicitation backed by authenticated transport.

The SHA-256 chain makes audit records tamper-evident, not tamper-proof. An attacker who can rewrite the entire local file can recompute a valid replacement chain. Immutable/WORM storage, signed checkpoints, and independent log shipping close that gap.

## Lethal Trifecta Note

This design gates the external-communication leg: defect filing can alter a downstream system and initiate operational work, so every such write passes through `raise_defect` confirmation. The resources contain only vetted, non-secret DBC and rule reference data. The CI handles untrusted pull-request source as data through bounded static and conversion checks; it does not let PR content define arbitrary commands.

## Lab 3-C

The initial decoder has two intentional defects recorded as xfail tests. `tools/check_standard.py` reports the missing fallback; `tools/check_conversion.py` starts this repository's MCP server over stdio and obtains DBC facts from `signal://` before checking conversion output.

After pushing the initial commit, create the issue from [docs/copilot-issue.md](docs/copilot-issue.md), assign it to Copilot coding agent, and request a Copilot review on its draft PR. `.github/workflows/agent-compliance-check.yml` posts or updates one compliance comment with BAPS, test, and conversion results.

## Submission Checklist

1. Repository URL: this GitHub repository, containing `mcp_server.py`, `verify_audit.py`, and no committed secret values.
2. Human-gate transcript: paste `mcp_client_test.py` output.
3. Audit transcript: paste intact and tampered `verify_audit.py` output.
4. Trifecta note: paste the section above.
5. Draft PR URL: paste the Copilot Agent PR showing the compliance comment and requested review.