GET_SYSTEM_INFO
Bounded platform metadata.
no process executionBlack Hat MEA 2026 · Arsenal
What happens when an MCP server approved by an AI host also behaves like a parent-bound C2 session?
MC2P is an open-source testbed that measures it. One executable is a local
stdio MCP server for Claude Code or VS Code and, at the same time, an
outbound MCP client to a private-lab controller. Every claim is backed by a
hash-linked evidence chain you can replay offline.
$ node release/verify-evidence-bundle.mjs \ fixtures/golden/evidence-bundle.json #0 CANARY_CREATED f4e262806be82c51 ← null #1 NODE_REGISTERED 074eeb86f8d6db01 ← f4e262806be82c51 #2 TASK_QUEUED e856decb1314b47d ← 074eeb86f8d6db01 #3 TASK_POLLED bc5476f63891402d ← e856decb1314b47d #4 TASK_COMPLETED 1642941939176737 ← bc5476f63891402d #5 RESULT_VERIFIED 8b8597ca6c4e1fd8 ← 1642941939176737 #6 SESSION_COMPLETED 79e1bcc73b0b9d0b ← 8b8597ca6c4e1fd8 ✓ chain intact · 7 events · verdict RESULT_VERIFIED bundle sha256 9b27fc12ce59253f…297f2cd1da90c8a4
The research question
Most MCP security work studies what the model sees: poisoned tool descriptions, prompt injection, malicious skills. MC2P studies the executable underneath. Once a user clicks approve, the host is allowed to:
The host starts the server and completes discovery before any tool is called.
The process lives as long as its parent IDE session keeps stdio open.
It can open network connections, subject only to host controls.
Every later approved session launches it again, with no OS persistence needed.
Architecture
MC2P is not a new wire protocol. It composes two standard MCP roles inside one visibly installed process and makes every step of that relationship measurable.
Session lifecycle
Each step emits an event into the chain, in this order.
APPROVED_MANIFESTThe operator installs an mc2p-lab-* entry and the host shows its trust prompt. MC2P never scripts that prompt.
PROCESS_STARTED → MCP_INITIALIZED → TOOLS_LISTEDDiscovery completes with zero tool calls. The model never asked for this process to run.
NODE_REGISTEREDThe one-use bootstrap is consumed and replaced by a revocable node identity in an owner-only file.
HEARTBEAT · TASK_POLL_EMPTYA fixed 3000 ms empty-poll cadence proves a live outbound transport, separate from a live IDE session.
TASK_QUEUED → TASK_POLLEDTasks are bound to a run, node, capability digest, opcode, deadline and lease.
TASK_COMPLETED → RESULT_VERIFIEDA result is promoted only when the same run, node and task chain lines up with the expected artifact digest.
PARENT_LOSTClosing the IDE ends stdin and the node exits. In the recorded run, zero node processes remained 1,299 ms later.
SESSION_RECONNECTEDThe next approved start opens a new session whose previousSessionId points at the one that ended.
Bounded by design
The public executor takes no shell text and no executable path. This is the entire task surface.
GET_SYSTEM_INFO
Bounded platform metadata.
no process executionLIST_DEMO_FILES
Lists synthetic fixture names.
confined to the lab rootREAD_CANARY
Hashes a generated synthetic canary.
digest, not file contentsWRITE_MARKER
Writes a deterministic run marker.
path containment + journalLAUNCH_CALCULATOR_DEMO
Opens Windows Calculator for a visible proof.
opt-in · zero argumentsNot in the public build
Evidence before claims
State changes and evidence are written in the same SQLite transaction. Each event carries the hash of the one before it. The verdict is recomputed independently in Node.js and in the browser with WebCrypto.
f4e262806be82c51prev null074eeb86f8d6db01prev f4e26280e856decb1314b47dprev 074eeb86bc5476f63891402dprev e856decb1642941939176737prev bc5476f68b8597ca6c4e1fd8prev 1642941979e1bcc73b0b9d0bprev 8b8597caM00 explicit enrollmentM01 task-free lifecycleM02 parent-bound shutdownM03 linked restartM04 clean-VM S00–S10Failed attempts stay in the record next to the passes. Nothing is relabeled.
MC2P Control
The dashboard keeps three states apart that C2 demos often blur together.
Scope
See it live
The live demo walks through a Claude Code approval, automatic enrollment, a fixed task round trip, parent loss, a linked reconnect, and an offline replay of the resulting evidence.
Doors open in
Try it
No controller, no VM, no network. Clone, test, and replay the golden bundle.
git clone https://github.com/Kuvvett/mc2p.git
cd mc2p
pnpm install --frozen-lockfile
pnpm build
node release/verify-evidence-bundle.mjs fixtures/golden/evidence-bundle.json