Streamable-HTTP MCP server on POST /mcp: device.state, attack.deploy/stop/ status/deauth/capture/export_hc22000, loot.handshakes/enterprise_creds, recon.aps/isearch/devices, pineap.kick_client/set_filter tools; recon DB + bundled opencode skills resources; attack playbook prompts. Cookie or Bearer auth. Harness page shows endpoint, token, curl snippet, capability explorer and a copy-paste pi.dev prompt. scripts/harness_stdio.py for stdio-only agents.
66 lines
2.2 KiB
Python
66 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
"""stdio bridge to the Mark VIII MCP server.
|
|
|
|
Agents that only support stdio transport can run:
|
|
|
|
MCP_URL=http://172.16.52.1:8080/mcp \
|
|
MCP_TOKEN=<device session token> \
|
|
python3 scripts/harness_stdio.py
|
|
|
|
JSON-RPC messages are read line-by-line from stdin (one JSON object per
|
|
line, no embedded newlines) and forwarded to the Mark VIII Streamable-HTTP
|
|
MCP endpoint. Responses are printed back on stdout as single-line JSON.
|
|
|
|
Get a token from the Mark VIII Harness page, or fetch one:
|
|
|
|
curl -s -X POST http://172.16.52.1:8080/api/login \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"username":"root","password":"<device password>"}' \
|
|
-c cookies.txt
|
|
"""
|
|
import json
|
|
import os
|
|
import sys
|
|
import urllib.request
|
|
|
|
URL = os.environ.get('MCP_URL', 'http://172.16.52.1:8080/mcp')
|
|
TOKEN = os.environ.get('MCP_TOKEN', '')
|
|
|
|
|
|
def forward(msg):
|
|
data = json.dumps(msg).encode()
|
|
req = urllib.request.Request(URL, data=data, method='POST')
|
|
req.add_header('Content-Type', 'application/json')
|
|
req.add_header('Accept', 'application/json, text/event-stream')
|
|
if TOKEN:
|
|
req.add_header('Authorization', 'Bearer ' + TOKEN)
|
|
try:
|
|
with urllib.request.urlopen(req, timeout=120) as resp:
|
|
return resp.read().decode()
|
|
except urllib.error.HTTPError as exc:
|
|
return json.dumps({'jsonrpc': '2.0', 'id': msg.get('id'),
|
|
'error': {'code': exc.code, 'message': exc.read().decode()[:300]}})
|
|
except Exception as exc: # noqa: BLE001
|
|
return json.dumps({'jsonrpc': '2.0', 'id': msg.get('id'),
|
|
'error': {'code': -32000, 'message': str(exc)}})
|
|
|
|
|
|
def main():
|
|
if not TOKEN:
|
|
print('warning: MCP_TOKEN not set; server will reject calls', file=sys.stderr)
|
|
for line in sys.stdin:
|
|
line = line.strip()
|
|
if not line:
|
|
continue
|
|
try:
|
|
msg = json.loads(line)
|
|
except ValueError:
|
|
print(json.dumps({'jsonrpc': '2.0', 'id': None,
|
|
'error': {'code': -32700, 'message': 'parse error'}}))
|
|
continue
|
|
print(forward(msg), flush=True)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|