agentwit 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. agentwit-0.1.0/.claude/settings.local.json +14 -0
  2. agentwit-0.1.0/.gitignore +73 -0
  3. agentwit-0.1.0/LICENSE +21 -0
  4. agentwit-0.1.0/PKG-INFO +227 -0
  5. agentwit-0.1.0/README.ja.md +193 -0
  6. agentwit-0.1.0/README.md +193 -0
  7. agentwit-0.1.0/agentwit/__init__.py +5 -0
  8. agentwit-0.1.0/agentwit/analyzer/__init__.py +5 -0
  9. agentwit-0.1.0/agentwit/analyzer/scorer.py +77 -0
  10. agentwit-0.1.0/agentwit/analyzer/timeline.py +45 -0
  11. agentwit-0.1.0/agentwit/cli.py +288 -0
  12. agentwit-0.1.0/agentwit/ingest/__init__.py +4 -0
  13. agentwit-0.1.0/agentwit/ingest/server.py +37 -0
  14. agentwit-0.1.0/agentwit/proxy/__init__.py +4 -0
  15. agentwit-0.1.0/agentwit/proxy/http_proxy.py +184 -0
  16. agentwit-0.1.0/agentwit/proxy/sse_proxy.py +37 -0
  17. agentwit-0.1.0/agentwit/proxy/stdio_proxy.py +37 -0
  18. agentwit-0.1.0/agentwit/reporter/__init__.py +6 -0
  19. agentwit-0.1.0/agentwit/reporter/html_reporter.py +51 -0
  20. agentwit-0.1.0/agentwit/reporter/json_reporter.py +115 -0
  21. agentwit-0.1.0/agentwit/reporter/markdown_reporter.py +51 -0
  22. agentwit-0.1.0/agentwit/witness/__init__.py +5 -0
  23. agentwit-0.1.0/agentwit/witness/chain.py +156 -0
  24. agentwit-0.1.0/agentwit/witness/log.py +143 -0
  25. agentwit-0.1.0/examples/demo.sh +236 -0
  26. agentwit-0.1.0/examples/dummy_mcp_server.py +138 -0
  27. agentwit-0.1.0/examples/quickstart_http.py +112 -0
  28. agentwit-0.1.0/examples/sample_witness_log.json +111 -0
  29. agentwit-0.1.0/pyproject.toml +51 -0
  30. agentwit-0.1.0/tests/__init__.py +1 -0
  31. agentwit-0.1.0/tests/test_chain.py +154 -0
  32. agentwit-0.1.0/tests/test_scorer.py +149 -0
  33. agentwit-0.1.0/tests/test_witness_log.py +159 -0
@@ -0,0 +1,14 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(python:*)",
5
+ "Bash(pip install:*)",
6
+ "Bash(git add:*)",
7
+ "Bash(git commit:*)",
8
+ "Bash(gh auth:*)",
9
+ "Bash(sudo apt:*)",
10
+ "Bash(curl:*)",
11
+ "Bash(pip index:*)"
12
+ ]
13
+ }
14
+ }
@@ -0,0 +1,73 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ downloads/
10
+ eggs/
11
+ .eggs/
12
+ lib/
13
+ lib64/
14
+ parts/
15
+ sdist/
16
+ var/
17
+ wheels/
18
+ share/python-wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+ MANIFEST
23
+ dist/
24
+
25
+ # Virtual environments
26
+ .env
27
+ .venv
28
+ env/
29
+ venv/
30
+ ENV/
31
+ env.bak/
32
+ venv.bak/
33
+
34
+ # Testing
35
+ .tox/
36
+ .nox/
37
+ .coverage
38
+ .coverage.*
39
+ .cache
40
+ nosetests.xml
41
+ coverage.xml
42
+ *.cover
43
+ *.py,cover
44
+ .hypothesis/
45
+ .pytest_cache/
46
+ htmlcov/
47
+
48
+ # Type checking
49
+ .mypy_cache/
50
+ .dmypy.json
51
+ dmypy.json
52
+ .pytype/
53
+ .pyre/
54
+
55
+ # IDE
56
+ .idea/
57
+ .vscode/
58
+ *.swp
59
+ *.swo
60
+ *~
61
+ .DS_Store
62
+
63
+ # agentwit — witness log output
64
+ witness_logs/
65
+ *.jsonl
66
+ /tmp/agentwit_*/
67
+
68
+ # Secrets
69
+ .env
70
+ .env.*
71
+ *.pem
72
+ *.key
73
+ secrets.json
agentwit-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 agentwit contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,227 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentwit
3
+ Version: 0.1.0
4
+ Summary: Transparent proxy witness for AI agent ↔ MCP server communications
5
+ Project-URL: Homepage, https://github.com/tokotokokame/agentwit
6
+ Project-URL: Repository, https://github.com/tokotokokame/agentwit
7
+ Project-URL: Issues, https://github.com/tokotokokame/agentwit/issues
8
+ Project-URL: Changelog, https://github.com/tokotokokame/agentwit/releases
9
+ Author: tokotokokame
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: ai-agent,audit,llm,mcp,proxy,security,witness
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Information Technology
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
21
+ Classifier: Topic :: Security
22
+ Classifier: Topic :: System :: Logging
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: anyio>=4.3.0
25
+ Requires-Dist: click>=8.1.0
26
+ Requires-Dist: fastapi>=0.111.0
27
+ Requires-Dist: httpx>=0.27.0
28
+ Requires-Dist: uvicorn[standard]>=0.29.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: httpx>=0.27.0; extra == 'dev'
31
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
32
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # agentwit
36
+
37
+ > Transparent witness for AI agent ↔ MCP server communications
38
+
39
+ [日本語版 / Japanese](README.ja.md)
40
+
41
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
42
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
43
+ [![Tests](https://img.shields.io/badge/tests-48%20passing-brightgreen.svg)](#)
44
+
45
+ ## What is agentwit?
46
+
47
+ agentwit is a transparent proxy that sits between AI agents and MCP servers,
48
+ recording every communication as a tamper-proof witness log.
49
+
50
+ Unlike existing tools that act as **"guards"** (blocking suspicious traffic),
51
+ agentwit acts as a **"witness"** — it never blocks, never interferes, but
52
+ records everything with cryptographic chain integrity.
53
+
54
+ ## Guard vs. Witness
55
+
56
+ | Tool | Approach | Blocks traffic | Tamper-proof log |
57
+ |--------------|-------------------|:--------------:|:----------------:|
58
+ | mcp-scan | Proxy + Guard | ✅ | ❌ |
59
+ | Proximity | Static scanner | — | ❌ |
60
+ | Intercept | Policy proxy | ✅ | ❌ |
61
+ | **agentwit** | **Witness proxy** | **❌** | **✅** |
62
+
63
+ ## How it works
64
+
65
+ ```
66
+ AI Agent
67
+
68
+
69
+ agentwit proxy ◄── records every message with chain hash
70
+ │ never blocks, fully transparent
71
+
72
+ MCP Server ◄── zero modification required
73
+ ```
74
+
75
+ Each recorded event is chained to the previous one via SHA-256:
76
+
77
+ ```
78
+ genesis_hash = sha256("genesis:" + session_id)
79
+
80
+
81
+ event_1: session_chain = sha256(genesis_hash + hash(event_1))
82
+
83
+
84
+ event_2: session_chain = sha256(event_1_chain + hash(event_2))
85
+
86
+
87
+ ...
88
+ ```
89
+
90
+ Any single-byte modification to any event breaks the entire chain from
91
+ that point forward — making tampering immediately detectable.
92
+
93
+ ## Quick Start
94
+
95
+ ### Installation
96
+
97
+ ```bash
98
+ pip install agentwit
99
+ ```
100
+
101
+ ### 1. Start the witness proxy
102
+
103
+ ```bash
104
+ agentwit proxy --target http://localhost:3000 --port 8765
105
+ # Starting agentwit proxy → http://localhost:3000
106
+ # Listening on 127.0.0.1:8765
107
+ # Session: ./witness_logs/session_20260314_120000
108
+ ```
109
+
110
+ ### 2. Point your agent to the proxy
111
+
112
+ ```bash
113
+ # Before: http://localhost:3000
114
+ # After: http://localhost:8765
115
+ # That's it. No other changes needed.
116
+ ```
117
+
118
+ ### 3. Generate an audit report
119
+
120
+ ```bash
121
+ agentwit report --session ./witness_logs/session_20260314_120000 \
122
+ --format html --output report.html
123
+ ```
124
+
125
+ ### 4. Verify chain integrity
126
+
127
+ ```bash
128
+ agentwit replay --session ./witness_logs/session_20260314_120000
129
+ # Session: session_20260314_120000 (6 events)
130
+ # Chain integrity: VALID
131
+ ```
132
+
133
+ ## Commands
134
+
135
+ ```
136
+ agentwit proxy --target URL [--port 8765] [--log-dir ./witness_logs] [--actor NAME]
137
+ agentwit report --session DIR [--format json|markdown|html] [--output FILE]
138
+ agentwit replay --session DIR [--verify/--no-verify]
139
+ agentwit diff --session-a DIR --session-b DIR
140
+ ```
141
+
142
+ | Command | Description |
143
+ |-----------|------------------------------------------------|
144
+ | `proxy` | Start the transparent witness proxy |
145
+ | `report` | Generate audit report (json / markdown / html) |
146
+ | `replay` | Replay and verify chain integrity of a session |
147
+ | `diff` | Compare two sessions side by side |
148
+
149
+ ## Witness Log Format
150
+
151
+ Each intercepted event is stored as one JSON line in `witness.jsonl`:
152
+
153
+ ```json
154
+ {
155
+ "witness_id": "sha256 of the entire signed event",
156
+ "session_chain": "sha256(prev_chain_hash + event_hash)",
157
+ "timestamp": "2026-03-14T12:18:53.708937+00:00",
158
+ "actor": "demo-agent",
159
+ "action": "tools/call",
160
+ "tool": "bash",
161
+ "input_hash": "sha256 of the input payload",
162
+ "output_hash": "sha256 of the output payload",
163
+ "full_payload": { "params": {}, "result": {} },
164
+ "risk_indicators": [
165
+ { "pattern": "shell_exec", "severity": "high", "matched": "bash" }
166
+ ]
167
+ }
168
+ ```
169
+
170
+ Events are appended to a JSONL file as they arrive — the proxy never
171
+ buffers or delays the upstream response.
172
+
173
+ ## Tamper Detection
174
+
175
+ Modify any field in the log and agentwit detects it immediately:
176
+
177
+ ```bash
178
+ # Simulate tampering: change "actor" in event[0]
179
+ python3 -c "
180
+ import json; lines=open('witness.jsonl').readlines()
181
+ e=json.loads(lines[0]); e['actor']='ATTACKER'
182
+ lines[0]=json.dumps(e)+'\n'; open('witness.jsonl','w').writelines(lines)
183
+ "
184
+
185
+ agentwit replay --session ./witness_logs/session_20260314_120000
186
+ # Session: session_20260314_120000 (6 events)
187
+ # Chain integrity: TAMPERED
188
+ # [event 0] FAIL - session_chain mismatch:
189
+ # expected '0fd4d24bcb3dab7d171e…'
190
+ # got 'a79a9e4cdb19795a521e…'
191
+ ```
192
+
193
+ ## Use Cases
194
+
195
+ - **Security engineers** auditing AI agent behavior in production
196
+ - **Enterprise teams** requiring AI activity compliance logs
197
+ - **AI researchers** reproducibly comparing agent sessions
198
+ - **Penetration testers** documenting MCP tool usage as evidence
199
+
200
+ ## Python API
201
+
202
+ ```python
203
+ from agentwit import WitnessLogger, ChainManager
204
+
205
+ # Direct logging (no proxy needed)
206
+ logger = WitnessLogger(session_dir="./logs", actor="my-agent")
207
+ event = logger.log_event(
208
+ action="tools/call",
209
+ tool="bash",
210
+ full_payload={"params": {"command": "ls"}, "result": {"stdout": "..."}}
211
+ )
212
+ logger.close()
213
+
214
+ # Verify a recorded session
215
+ chain = ChainManager(session_id="session_20260314_120000")
216
+ results = chain.verify_chain(events)
217
+ all_valid = all(r["valid"] for r in results)
218
+ ```
219
+
220
+ ## Requirements
221
+
222
+ - Python 3.10+
223
+ - FastAPI, uvicorn, httpx, click (installed automatically)
224
+
225
+ ## License
226
+
227
+ [MIT](LICENSE) © agentwit contributors
@@ -0,0 +1,193 @@
1
+ # agentwit
2
+
3
+ > AIエージェントとMCPサーバー間の通信を記録する透過型Witnessプロキシ
4
+
5
+ [English](README.md)
6
+
7
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
9
+ [![Tests](https://img.shields.io/badge/tests-48%20passing-brightgreen.svg)](#)
10
+
11
+ ## agentwit とは?
12
+
13
+ agentwit は、AIエージェントとMCPサーバーの間に置く透過型プロキシです。
14
+ すべての通信を改ざん検知可能なWitness Log(改ざん検知ログ)として記録します。
15
+
16
+ 不審なトラフィックをブロックする **「ガード」** 型の既存ツールとは異なり、
17
+ agentwit は **「証人(Witness)」** として動作します。
18
+ 通信をブロックせず、改変もせず、ただ暗号化されたChain Integrity(チェーン整合性)付きですべてを記録します。
19
+
20
+ ## Guard(ガード)vs. Witness(証人)
21
+
22
+ | ツール | アプローチ | 通信のブロック | 改ざん検知ログ |
23
+ |--------------|-------------------|:--------------:|:--------------:|
24
+ | mcp-scan | プロキシ + ガード | ✅ | ❌ |
25
+ | Proximity | 静的スキャナー | — | ❌ |
26
+ | Intercept | ポリシープロキシ | ✅ | ❌ |
27
+ | **agentwit** | **Witnessプロキシ** | **❌** | **✅** |
28
+
29
+ ## 仕組み
30
+
31
+ ```
32
+ AIエージェント
33
+
34
+
35
+ agentwit proxy ◄── 全メッセージをChainハッシュ付きで記録
36
+ │ ブロックなし・完全透過
37
+
38
+ MCPサーバー ◄── 変更不要・そのまま動作
39
+ ```
40
+
41
+ 記録された各イベントは SHA-256 でチェーン状に連結されます:
42
+
43
+ ```
44
+ genesis_hash = sha256("genesis:" + session_id)
45
+
46
+
47
+ event_1: session_chain = sha256(genesis_hash + hash(event_1))
48
+
49
+
50
+ event_2: session_chain = sha256(event_1_chain + hash(event_2))
51
+
52
+
53
+ ...
54
+ ```
55
+
56
+ どのイベントに対しても1バイトの変更を加えると、その時点からチェーン全体が壊れます。
57
+ これにより改ざんを即座に検出できます。
58
+
59
+ ## クイックスタート
60
+
61
+ ### インストール
62
+
63
+ ```bash
64
+ pip install agentwit
65
+ ```
66
+
67
+ ### 1. Witnessプロキシを起動
68
+
69
+ ```bash
70
+ agentwit proxy --target http://localhost:3000 --port 8765
71
+ # Starting agentwit proxy → http://localhost:3000
72
+ # Listening on 127.0.0.1:8765
73
+ # Session: ./witness_logs/session_20260314_120000
74
+ ```
75
+
76
+ ### 2. エージェントの向き先をプロキシに変更
77
+
78
+ ```bash
79
+ # 変更前: http://localhost:3000
80
+ # 変更後: http://localhost:8765
81
+ # 以上です。他に変更は不要です。
82
+ ```
83
+
84
+ ### 3. 監査レポートを生成
85
+
86
+ ```bash
87
+ agentwit report --session ./witness_logs/session_20260314_120000 \
88
+ --format html --output report.html
89
+ ```
90
+
91
+ ### 4. Chain Integrityを検証
92
+
93
+ ```bash
94
+ agentwit replay --session ./witness_logs/session_20260314_120000
95
+ # Session: session_20260314_120000 (6 events)
96
+ # Chain integrity: VALID
97
+ ```
98
+
99
+ ## コマンド一覧
100
+
101
+ ```
102
+ agentwit proxy --target URL [--port 8765] [--log-dir ./witness_logs] [--actor NAME]
103
+ agentwit report --session DIR [--format json|markdown|html] [--output FILE]
104
+ agentwit replay --session DIR [--verify/--no-verify]
105
+ agentwit diff --session-a DIR --session-b DIR
106
+ ```
107
+
108
+ | コマンド | 説明 |
109
+ |-----------|----------------------------------------------------------|
110
+ | `proxy` | 透過Witnessプロキシを起動 |
111
+ | `report` | 監査レポートを生成(json / markdown / html) |
112
+ | `replay` | セッションを再生しChain Integrityを検証 |
113
+ | `diff` | 2つのセッションを並べて比較 |
114
+
115
+ ## Witness Logのフォーマット
116
+
117
+ 傍受された各イベントは `witness.jsonl` に1行のJSONとして記録されます:
118
+
119
+ ```json
120
+ {
121
+ "witness_id": "イベント全体のsha256",
122
+ "session_chain": "sha256(直前のchain_hash + event_hash)",
123
+ "timestamp": "2026-03-14T12:18:53.708937+00:00",
124
+ "actor": "demo-agent",
125
+ "action": "tools/call",
126
+ "tool": "bash",
127
+ "input_hash": "入力ペイロードのsha256",
128
+ "output_hash": "出力ペイロードのsha256",
129
+ "full_payload": { "params": {}, "result": {} },
130
+ "risk_indicators": [
131
+ { "pattern": "shell_exec", "severity": "high", "matched": "bash" }
132
+ ]
133
+ }
134
+ ```
135
+
136
+ イベントは到着と同時にJSONLファイルへ追記されます。
137
+ プロキシは上流のレスポンスをバッファリングせず、遅延も発生しません。
138
+
139
+ ## 改ざん検知
140
+
141
+ ログのどのフィールドを変更しても、agentwit は即座に検出します:
142
+
143
+ ```bash
144
+ # 改ざんのシミュレーション: event[0] の "actor" フィールドを変更
145
+ python3 -c "
146
+ import json; lines=open('witness.jsonl').readlines()
147
+ e=json.loads(lines[0]); e['actor']='ATTACKER'
148
+ lines[0]=json.dumps(e)+'\n'; open('witness.jsonl','w').writelines(lines)
149
+ "
150
+
151
+ agentwit replay --session ./witness_logs/session_20260314_120000
152
+ # Session: session_20260314_120000 (6 events)
153
+ # Chain integrity: TAMPERED
154
+ # [event 0] FAIL - session_chain mismatch:
155
+ # expected '0fd4d24bcb3dab7d171e…'
156
+ # got 'a79a9e4cdb19795a521e…'
157
+ ```
158
+
159
+ ## ユースケース
160
+
161
+ - **セキュリティエンジニア** — 本番環境でのAIエージェントの挙動を監査
162
+ - **エンタープライズチーム** — AI活動のコンプライアンスログとして保存
163
+ - **AI研究者** — エージェントセッションを再現可能な形式で比較・検証
164
+ - **ペネトレーションテスター** — MCPツール使用状況を証跡として文書化
165
+
166
+ ## Python API
167
+
168
+ ```python
169
+ from agentwit import WitnessLogger, ChainManager
170
+
171
+ # プロキシなしで直接ログを記録
172
+ logger = WitnessLogger(session_dir="./logs", actor="my-agent")
173
+ event = logger.log_event(
174
+ action="tools/call",
175
+ tool="bash",
176
+ full_payload={"params": {"command": "ls"}, "result": {"stdout": "..."}}
177
+ )
178
+ logger.close()
179
+
180
+ # 記録済みセッションのChain Integrityを検証
181
+ chain = ChainManager(session_id="session_20260314_120000")
182
+ results = chain.verify_chain(events)
183
+ all_valid = all(r["valid"] for r in results)
184
+ ```
185
+
186
+ ## 動作要件
187
+
188
+ - Python 3.10+
189
+ - FastAPI, uvicorn, httpx, click(インストール時に自動導入)
190
+
191
+ ## ライセンス
192
+
193
+ [MIT](LICENSE) © agentwit contributors