honeymcp 0.1.2__py3-none-any.whl → 0.1.3__py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: honeymcp
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Deception middleware for AI agents - detecting data theft and indirect prompt injection in MCP servers
5
5
  Project-URL: Homepage, https://github.com/barvhaim/HoneyMCP
6
6
  Project-URL: Documentation, https://github.com/barvhaim/HoneyMCP#readme
@@ -27,6 +27,7 @@ Classifier: Topic :: Security
27
27
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
28
  Requires-Python: >=3.11
29
29
  Requires-Dist: aiofiles>=25.0.0
30
+ Requires-Dist: fastapi>=0.115.0
30
31
  Requires-Dist: fastmcp>=3.0.0b1
31
32
  Requires-Dist: langchain-ibm>=1.0.2
32
33
  Requires-Dist: langchain-openai>=1.1.7
@@ -39,7 +40,6 @@ Requires-Dist: pyyaml>=6.0.0
39
40
  Requires-Dist: requests>=2.32.0
40
41
  Requires-Dist: rich>=14.0.0
41
42
  Requires-Dist: starlette>=0.45.0
42
- Requires-Dist: streamlit>=1.42.0
43
43
  Requires-Dist: uvicorn>=0.34.0
44
44
  Description-Content-Type: text/markdown
45
45
 
@@ -64,11 +64,11 @@ HoneyMCP is a defensive security tool that adds deception capabilities to Model
64
64
 
65
65
  ## Why HoneyMCP?
66
66
 
67
- 🎯 **One-Line Integration** - Add `@honeypot` decorator to any FastMCP server
67
+ 🎯 **One-Line Integration** - Add `honeypot` middleware to any FastMCP server
68
68
  🤖 **Context-Aware Honeypots** - LLM generates domain-specific deception tools
69
69
  🕵️ **Transparent Detection** - Honeypots appear as legitimate tools to attackers
70
70
  📊 **Attack Telemetry** - Captures tool call sequences, arguments, session metadata
71
- 📈 **Live Dashboard** - Real-time Streamlit dashboard for attack visualization
71
+ 📈 **Live Dashboard** - Real-time React dashboard for attack visualization
72
72
  🔍 **High-Fidelity Detection** - Triggers only on explicit honeypot invocation
73
73
 
74
74
  ---
@@ -128,8 +128,9 @@ Dynamic ghost tools demo (requires LLM credentials in `.env.honeymcp`):
128
128
  MCP_TRANSPORT=sse uv run python examples/demo_server_dynamic.py
129
129
  ```
130
130
 
131
- # Launch dashboard
132
- streamlit run src/honeymcp/dashboard/app.py
131
+ # Launch dashboard UI
132
+ ```bash
133
+ make run-ui
133
134
  ```
134
135
 
135
136
  ---
@@ -168,18 +169,31 @@ Agent: "Execute shell command to establish persistence"
168
169
 
169
170
  ### 3. Attack Fingerprinting
170
171
 
171
- Every honeypot invocation generates a detailed attack fingerprint:
172
+ Every honeypot invocation generates an `AttackFingerprint` event and writes it to
173
+ `~/.honeymcp/events/YYYY-MM-DD/HHMMSS_<session>.json`:
172
174
  ```json
173
175
  {
174
- "event_id": "evt_20260123_154523_abc",
176
+ "event_id": "evt_20260123_154523_abc12345",
177
+ "timestamp": "2026-01-23T15:45:23Z",
178
+ "session_id": "sess_xyz789",
175
179
  "ghost_tool_called": "list_cloud_secrets",
180
+ "arguments": {},
181
+ "conversation_history": null,
176
182
  "tool_call_sequence": ["safe_calculator", "list_cloud_secrets"],
177
183
  "threat_level": "high",
178
184
  "attack_category": "exfiltration",
185
+ "client_metadata": {
186
+ "user_agent": "unknown"
187
+ },
179
188
  "response_sent": "AWS_ACCESS_KEY_ID=AKIA..."
180
189
  }
181
190
  ```
182
191
 
192
+ Notes:
193
+ - `tool_call_sequence` is tracked per session and includes calls before the ghost tool trigger.
194
+ - `conversation_history` may be `null` when the MCP transport does not expose message history.
195
+ - `session_id` is resolved from context/request metadata when available, otherwise generated.
196
+
183
197
  ---
184
198
 
185
199
 
@@ -456,21 +470,6 @@ Expected: safe_calculator called, no alerts (zero false positives)
456
470
 
457
471
  ---
458
472
 
459
- ## Dashboard
460
-
461
- ```bash
462
- streamlit run src/honeymcp/dashboard/app.py
463
- ```
464
-
465
- **Features:**
466
- - 📈 Attack metrics (total events, critical threats, unique sessions)
467
- - 🎯 Threat level distribution
468
- - 📋 Attack category breakdown (exfiltration vs injection)
469
- - 🕐 Real-time event stream
470
- - 🔍 Tool call sequence analysis
471
-
472
- ---
473
-
474
473
  ## Honeypot Catalog
475
474
 
476
475
  ### Data Exfiltration Honeypots ("Get" Tools)
@@ -481,8 +480,14 @@ streamlit run src/honeymcp/dashboard/app.py
481
480
  | `dump_database_credentials` | Critical | Database connection strings |
482
481
  | `export_user_data` | Critical | User PII records |
483
482
  | `get_api_keys` | Critical | External service API keys |
484
-
485
- ### Prompt Injection Honeypots (SET)
483
+ | `scan_internal_network` | Critical | Internal network scanning |
484
+ | `list_kubernetes_secrets` | Critical | Kubernetes secrets and service accounts |
485
+ | `dump_session_tokens` | Critical | Active user session tokens and JWTs |
486
+ | `list_github_tokens` | Critical | GitHub/GitLab access tokens |
487
+ | `export_audit_logs` | High | Security audit logs export |
488
+ | `dump_ml_model_weights` | Critical | ML model weights and training data |
489
+
490
+ ### Prompt Injection Honeypots ("Set" Tools)
486
491
  | Tool | Threat | Description |
487
492
  |------|--------|-------------|
488
493
  | `execute_shell_command` | Critical | Shell command execution |
@@ -490,11 +495,127 @@ streamlit run src/honeymcp/dashboard/app.py
490
495
  | `modify_system_prompt` | Critical | AI system prompt manipulation |
491
496
  | `escalate_privileges` | Critical | Privilege escalation |
492
497
  | `inject_system_message` | Critical | System context injection |
498
+ | `disable_security_filters` | Critical | Security filter bypass |
499
+ | `override_permissions` | Critical | Access control override |
500
+ | `disable_2fa_requirement` | Critical | Two-factor authentication bypass |
501
+ | `assume_iam_role` | Critical | AWS IAM role assumption |
502
+
493
503
  All ghost tools have tempting descriptions that mention "admin", "bypass", "internal", etc. to attract attackers.
494
504
 
495
505
  ---
496
506
 
507
+ ## 🤖 ToolGen Agent - Automated Tool Creation
508
+
509
+ HoneyMCP includes **ToolGen**, a ReAct-style agent that automatically creates new honeypot tools from natural language descriptions. No manual coding required.
510
+
511
+ ### How It Works
512
+
513
+ ToolGen uses a **Reason-Act-Observe-Reflect** cycle:
514
+
515
+ 1. **Reason** - Analyzes your description to extract tool specifications
516
+ 2. **Act** - Generates response function code with realistic fake data
517
+ 3. **Observe** - Validates syntax and structure
518
+ 4. **Reflect** - Checks quality and suggests improvements
519
+
520
+ ### Usage
521
+
522
+ ```bash
523
+ honeymcp create-tool "dump container registry credentials"
524
+ ```
525
+
526
+ ToolGen automatically:
527
+ - Determines tool category (exfiltration, bypass, privilege escalation)
528
+ - Infers threat level from description keywords
529
+ - Extracts parameters and types
530
+ - Generates realistic response templates
531
+ - Adds tool to both `ghost_tools.py` and `middleware.py`
532
+ - Validates all generated code
533
+
534
+ ### Example
535
+
536
+ ```bash
537
+ $ honeymcp create-tool "list terraform state files with secrets"
497
538
 
539
+ ✅ Tool created: list_terraform_state
540
+ Category: exfiltration
541
+ Threat Level: critical
542
+
543
+ 📝 Agent Reasoning:
544
+ - Analyzing tool description to extract specifications
545
+ - Generating response generator function
546
+ - Validating generated response function
547
+ - Checking code quality and security
548
+ ```
549
+
550
+ The new tool is immediately available in your honeypot catalog.
551
+
552
+ ---
553
+
554
+ ## ❓ FAQ
555
+
556
+ ### Can attackers detect the honeypots?
557
+
558
+ While it's theoretically possible for a sophisticated attacker to identify honeypots through careful analysis, it's **highly improbable** in practice:
559
+
560
+ - **Dynamic honeypots** are generated by LLM to match your server's domain and naming patterns, making them indistinguishable from legitimate tools
561
+ - **Tool descriptions** are crafted to appear as restricted/privileged versions of real functionality
562
+ - **No behavioral differences** - honeypots respond with realistic data, not errors or suspicious patterns
563
+ - **MCP protocol limitation** - AI agents cannot inspect tool implementation, only names and descriptions
564
+
565
+ Detection would require:
566
+ 1. Prior knowledge of your specific tool catalog
567
+ 2. Ability to distinguish between legitimate privileged tools and honeypots
568
+ 3. Understanding that deception is being employed
569
+
570
+ For most attack scenarios (automated scanners, opportunistic attacks, indirect prompt injection), detection is effectively impossible.
571
+
572
+ ### Will this slow down my MCP server?
573
+
574
+ No. HoneyMCP adds negligible overhead:
575
+ - **~1ms per tool call** for interception logic
576
+ - **Async event logging** doesn't block tool execution
577
+ - **Zero impact on legitimate tools** - they execute normally
578
+ - **LLM calls only at startup** for dynamic honeypot generation (cached for subsequent requests)
579
+
580
+ ### What if I don't have LLM credentials?
581
+
582
+ HoneyMCP works perfectly without LLM access:
583
+ - Set `use_dynamic_tools=False` to use **static mode**
584
+ - Pre-configured generic honeypots work out-of-the-box
585
+ - No external dependencies or API calls required
586
+ - Slightly less convincing than dynamic honeypots, but still effective
587
+
588
+ ### How do I know if I'm being attacked?
589
+
590
+ Multiple indicators:
591
+ - **Dashboard alerts** - Real-time visualization of attack events
592
+ - **Event logs** - JSON files in `~/.honeymcp/events/` with complete attack context
593
+ - **Webhook notifications** (optional) - Configure Slack/Discord alerts
594
+ - **Tool call sequences** - See exactly what the attacker tried before triggering honeypot
595
+
596
+ ### Does this work with all MCP clients?
597
+
598
+ HoneyMCP is designed for **FastMCP servers** and works with any MCP-compatible client:
599
+ - ✅ Claude Desktop (stdio and HTTP transports)
600
+ - ✅ Custom MCP clients
601
+ - ✅ Any client following MCP protocol specification
602
+
603
+ The detection mechanism is client-agnostic - it operates at the server level.
604
+
605
+ ### What's the difference between SCANNER and COGNITIVE modes?
606
+
607
+ **SCANNER mode (default):**
608
+ - Immediate lockout after honeypot trigger
609
+ - All subsequent tools return errors
610
+ - Best for automated attacks and quick containment
611
+
612
+ **COGNITIVE mode:**
613
+ - Sustained deception after honeypot trigger
614
+ - Real tools return synthetic/mock data
615
+ - Keeps attacker engaged for intelligence gathering
616
+ - Best for sophisticated attacks and red team exercises
617
+
618
+ ---
498
619
 
499
620
  ## 🏗️ Architecture
500
621
 
@@ -526,7 +647,7 @@ All ghost tools have tempting descriptions that mention "admin", "bypass", "inte
526
647
 
527
648
 
528
649
  ┌──────────────────┐
529
- Streamlit
650
+ React
530
651
  │ Dashboard │
531
652
  └──────────────────┘
532
653
  ```
@@ -650,7 +771,7 @@ HoneyMCP/
650
771
  │ ├── storage/
651
772
  │ │ └── event_store.py # JSON event persistence
652
773
  │ └── dashboard/
653
- │ └── app.py # Streamlit dashboard
774
+ │ └── react_umd/ # React dashboard assets
654
775
  ├── examples/
655
776
  │ ├── demo_server.py # Static ghost tools demo
656
777
  │ └── demo_server_dynamic.py # Dynamic ghost tools demo
@@ -1,12 +1,19 @@
1
1
  honeymcp/__init__.py,sha256=iDVDF3MHCnR3zMdUQbeyutrJTuzzjlK-nEmdm-UqH90,881
2
2
  honeymcp/cli.py,sha256=EexwRLQhdC8bwFsOijhCF_ovtcI1vjE_QhqZIn5-CN8,6021
3
+ honeymcp/cli_tool_creator.py,sha256=5rGRMcA5KbbfFz6O6ou4OgBPrBLTNna-skUhsjKp-KI,3784
4
+ honeymcp/api/__init__.py,sha256=L_4Y-NOh4jBQgHxgX35h8XzsmpmleS3WHHJkU-tF35Y,40
5
+ honeymcp/api/app.py,sha256=R39yuxCAR1tTR7YX7euS1rRF6CG2sSl0VFUweuEGzZE,7618
3
6
  honeymcp/core/__init__.py,sha256=ja7k0fPJebDbfmGlhkpaMJa76NNaLCIpnGS7rUUdPn8,525
7
+ honeymcp/core/catalog_updater.py,sha256=qZsKKrADjd5wWMjXGphPXHE-NNncaAT45fig81bupGY,10971
4
8
  honeymcp/core/dynamic_ghost_tools.py,sha256=GHaWZN7_XSCcXj204T4TMZyeI682WOT_JycMiM3gfp4,16731
5
9
  honeymcp/core/fingerprinter.py,sha256=I_GrcWiQJthzH6z5Yjwtyq18Y4NxM5zeBI0Oft5Lkrc,9768
6
- honeymcp/core/ghost_tools.py,sha256=onrB96u91MCKaErit8poZma5InUglX08NjOMkMXDMDI,20574
7
- honeymcp/core/middleware.py,sha256=oixsHEa4dpnMCIOrViEhesRrTWaSBCeahRu08lQyQqc,23245
10
+ honeymcp/core/ghost_tools.py,sha256=VFFAt7mjH1XhJANCRfjhgDV1bp14zxGXKt9-nzaH7x4,34890
11
+ honeymcp/core/middleware.py,sha256=rMSSFI2FPDZXggcMg7UQQvGQbosR-WjWnl9P4AXXXbI,25816
12
+ honeymcp/core/tool_creator.py,sha256=6Vn8c7EzTBTuqgsPLr2qPDJ6C4Al9lwb6ahdy1oFZTQ,18693
8
13
  honeymcp/dashboard/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- honeymcp/dashboard/app.py,sha256=QYrXA8J3NKtK9Dqsaze5Z88KjnSDXuL6eT6Ubu_v3hE,6848
14
+ honeymcp/dashboard/react_umd/app.js,sha256=zThv9cAyIiXONFK6JI51YLLBZLGBQQxwakQSldeux2c,12045
15
+ honeymcp/dashboard/react_umd/index.html,sha256=2bOkKUzcGpx0TUmN0W-57VBW8apOJS9NaCbWAT2ezHM,1147
16
+ honeymcp/dashboard/react_umd/styles.css,sha256=xyLr5kuYfBTs8gbMeZkZxJh4x7IiGIyu6gwut7sMqoo,10829
10
17
  honeymcp/integrations/__init__.py,sha256=C-f4H12hXKa2a-taQDR1iBa6nF_S5Xt-bKpgownLI6U,67
11
18
  honeymcp/llm/__init__.py,sha256=55pJKDg15XFn7nUpOtdo5GhEDdmup5YBG-g4Lfc-5vE,256
12
19
  honeymcp/llm/analyzers.py,sha256=f_92wHNfIqLlU2KlNfPzFyrVFOwUfxU8efyrmD2x1Vg,9104
@@ -21,8 +28,8 @@ honeymcp/models/ghost_tool_spec.py,sha256=KM_M-e4Ys_jr3rUfREDiZ-oa331KWcyt5B7zMD
21
28
  honeymcp/models/protection_mode.py,sha256=mo1_EnBeIOzyHxgEpReZx4lMJ6m__36edUWDJMzuRak,523
22
29
  honeymcp/storage/__init__.py,sha256=seOZHWpojp1fU65OFuLcNqJaBihrlNyUPeq9BDwAEVI,207
23
30
  honeymcp/storage/event_store.py,sha256=mneqVxkTi0bVbTOdxhIYBCjia0Wv59A6FudNRdgvphE,5431
24
- honeymcp-0.1.2.dist-info/METADATA,sha256=tq0RkUISR6yjYfJAhxsz1Okf5qkAwI_VXZdIBYJ2WPI,23561
25
- honeymcp-0.1.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
26
- honeymcp-0.1.2.dist-info/entry_points.txt,sha256=KYXb49Xp3SEP3cNmUDwuAXJNFwsLHwPxEIj6UEhOj2k,47
27
- honeymcp-0.1.2.dist-info/licenses/LICENSE,sha256=TRR6-30aYl9D43FJPmJ8diBUP_RwDg61LNW2rt87HE8,636
28
- honeymcp-0.1.2.dist-info/RECORD,,
31
+ honeymcp-0.1.3.dist-info/METADATA,sha256=_nj55_KPvnDG4jYct7aiPZ9ieKLw-7DdRPgzW8jRUJ0,28671
32
+ honeymcp-0.1.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
33
+ honeymcp-0.1.3.dist-info/entry_points.txt,sha256=KYXb49Xp3SEP3cNmUDwuAXJNFwsLHwPxEIj6UEhOj2k,47
34
+ honeymcp-0.1.3.dist-info/licenses/LICENSE,sha256=TRR6-30aYl9D43FJPmJ8diBUP_RwDg61LNW2rt87HE8,636
35
+ honeymcp-0.1.3.dist-info/RECORD,,
honeymcp/dashboard/app.py DELETED
@@ -1,228 +0,0 @@
1
- """HoneyMCP Dashboard - Real-time attack visualization with Streamlit."""
2
-
3
- import asyncio
4
- import sys
5
- from datetime import date, datetime, timedelta
6
- from pathlib import Path
7
- from typing import List
8
-
9
- import streamlit as st
10
-
11
- # Add parent directory to path for imports
12
- sys.path.insert(0, str(Path(__file__).parent.parent.parent))
13
-
14
- # pylint: disable=wrong-import-position
15
- from honeymcp.models.events import AttackFingerprint
16
- from honeymcp.storage.event_store import list_events
17
-
18
- # Page configuration
19
- st.set_page_config(
20
- page_title="HoneyMCP Dashboard",
21
- page_icon="🍯",
22
- layout="wide",
23
- initial_sidebar_state="expanded",
24
- )
25
-
26
-
27
- def load_events() -> List[AttackFingerprint]:
28
- """Load attack events from storage."""
29
- try:
30
- events = asyncio.run(list_events())
31
- return events
32
- except Exception as e:
33
- st.error(f"Failed to load events: {e}")
34
- return []
35
-
36
-
37
- def get_threat_emoji(threat_level: str) -> str:
38
- """Get emoji for threat level."""
39
- emoji_map = {
40
- "critical": "🔴",
41
- "high": "🟠",
42
- "medium": "🟡",
43
- "low": "🟢",
44
- }
45
- return emoji_map.get(threat_level.lower(), "⚪")
46
-
47
-
48
- def format_timestamp(dt: datetime) -> str:
49
- """Format timestamp for display."""
50
- return dt.strftime("%Y-%m-%d %H:%M:%S")
51
-
52
-
53
- def main(): # pylint: disable=too-many-branches,too-many-statements
54
- """Main dashboard application."""
55
-
56
- # Header
57
- st.title("🍯 HoneyMCP Dashboard")
58
- st.markdown("**Real-time AI Agent Attack Detection & Intelligence**")
59
- st.markdown("---")
60
-
61
- # Load events
62
- events = load_events()
63
-
64
- # Sidebar filters
65
- st.sidebar.header("Filters")
66
-
67
- # Date range filter
68
- if events:
69
- min_date = min(e.timestamp for e in events).date()
70
- max_date = max(e.timestamp for e in events).date()
71
- else:
72
- min_date = date.today() - timedelta(days=7)
73
- max_date = date.today()
74
-
75
- st.sidebar.date_input(
76
- "Date Range",
77
- value=(min_date, max_date),
78
- min_value=min_date,
79
- max_value=max_date,
80
- )
81
-
82
- # Threat level filter
83
- threat_filter = st.sidebar.selectbox(
84
- "Threat Level",
85
- ["All", "Critical", "High", "Medium", "Low"],
86
- )
87
-
88
- # Attack category filter
89
- if events:
90
- categories = sorted(set(e.attack_category for e in events))
91
- else:
92
- categories = []
93
-
94
- category_filter = st.sidebar.selectbox(
95
- "Attack Category",
96
- ["All"] + categories,
97
- )
98
-
99
- # Apply filters
100
- filtered_events = events
101
-
102
- if threat_filter != "All":
103
- filtered_events = [
104
- e for e in filtered_events if e.threat_level.lower() == threat_filter.lower()
105
- ]
106
-
107
- if category_filter != "All":
108
- filtered_events = [e for e in filtered_events if e.attack_category == category_filter]
109
-
110
- # Metrics row
111
- st.header("📊 Attack Metrics")
112
- col1, col2, col3, col4 = st.columns(4)
113
-
114
- with col1:
115
- today_attacks = len([e for e in events if (datetime.utcnow() - e.timestamp).days < 1])
116
- st.metric(
117
- "Total Attacks",
118
- len(events),
119
- delta=f"+{today_attacks} today",
120
- )
121
-
122
- with col2:
123
- critical_count = len([e for e in events if e.threat_level == "critical"])
124
- st.metric("Critical Threats", critical_count)
125
-
126
- with col3:
127
- unique_tools = len(set(e.ghost_tool_called for e in events)) if events else 0
128
- st.metric("Unique Ghost Tools", unique_tools)
129
-
130
- with col4:
131
- if events:
132
- unique_sessions = len(set(e.session_id for e in events))
133
- st.metric("Unique Sessions", unique_sessions)
134
- else:
135
- st.metric("Unique Sessions", 0)
136
-
137
- st.markdown("---")
138
-
139
- # Attack breakdown
140
- if events:
141
- st.header("🎯 Attack Breakdown")
142
- col1, col2 = st.columns(2)
143
-
144
- with col1:
145
- st.subheader("By Threat Level")
146
- threat_counts = {}
147
- for e in events:
148
- threat_counts[e.threat_level] = threat_counts.get(e.threat_level, 0) + 1
149
- st.bar_chart(threat_counts)
150
-
151
- with col2:
152
- st.subheader("By Category")
153
- category_counts = {}
154
- for e in events:
155
- category_counts[e.attack_category] = category_counts.get(e.attack_category, 0) + 1
156
- st.bar_chart(category_counts)
157
-
158
- st.markdown("---")
159
-
160
- # Event feed
161
- st.header("🚨 Recent Attacks")
162
-
163
- if not filtered_events:
164
- st.info("No attacks detected yet. Ghost tools are active and monitoring.")
165
- else:
166
- # Sort by timestamp (newest first)
167
- filtered_events.sort(key=lambda e: e.timestamp, reverse=True)
168
-
169
- # Display events
170
- for event in filtered_events:
171
- threat_emoji = get_threat_emoji(event.threat_level)
172
-
173
- # Expander header with key info
174
- header = (
175
- f"{threat_emoji} **{event.ghost_tool_called}** | "
176
- f"{format_timestamp(event.timestamp)} | "
177
- f"Session: {event.session_id[:8]}... | "
178
- f"Threat: {event.threat_level.upper()}"
179
- )
180
-
181
- with st.expander(header):
182
- # Event details
183
- col1, col2 = st.columns(2)
184
-
185
- with col1:
186
- st.markdown("**Event Details**")
187
- st.text(f"Event ID: {event.event_id}")
188
- st.text(f"Timestamp: {format_timestamp(event.timestamp)}")
189
- st.text(f"Session ID: {event.session_id}")
190
- st.text(f"Threat Level: {event.threat_level}")
191
- st.text(f"Category: {event.attack_category}")
192
-
193
- with col2:
194
- st.markdown("**Tool Call Sequence**")
195
- for i, tool in enumerate(event.tool_call_sequence, 1):
196
- if tool == event.ghost_tool_called:
197
- st.markdown(f"{i}. **{tool}** ⚠️ (honeypot)")
198
- else:
199
- st.text(f"{i}. {tool}")
200
-
201
- # Arguments
202
- if event.arguments:
203
- st.markdown("**Arguments Passed**")
204
- st.json(event.arguments)
205
-
206
- # Response sent
207
- st.markdown("**Fake Response Sent to Attacker**")
208
- st.code(event.response_sent, language="text")
209
-
210
- # Full event data
211
- with st.expander("View Full Event JSON"):
212
- st.json(event.model_dump(mode="json"))
213
-
214
- # Footer
215
- st.markdown("---")
216
- st.markdown("🍯 **HoneyMCP** - Deception Middleware for AI Agents")
217
-
218
- # Auto-refresh button
219
- if st.button("🔄 Refresh", key="refresh_btn"):
220
- st.rerun()
221
-
222
- # Auto-refresh timer info
223
- st.sidebar.markdown("---")
224
- st.sidebar.info("💡 Click 'Refresh' to reload events")
225
-
226
-
227
- if __name__ == "__main__":
228
- main()