-
Notifications
You must be signed in to change notification settings - Fork 29
Expand file tree
/
Copy pathview_trace.py
More file actions
executable file
·148 lines (131 loc) · 5.02 KB
/
view_trace.py
File metadata and controls
executable file
·148 lines (131 loc) · 5.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/env python3
"""
MCP Trace Viewer - Analyzes and displays MCP trace logs
"""
import json
import sys
import os
from datetime import datetime
from collections import defaultdict
def analyze_trace(filename):
"""Analyze MCP trace file and display summary"""
print(f"=== MCP Trace Analysis ===")
print(f"File: {filename}")
print()
requests = []
responses = []
errors = []
methods = defaultdict(int)
with open(filename, 'r') as f:
for line_no, line in enumerate(f, 1):
try:
entry = json.loads(line.strip())
level = entry.get('level', '')
if level == 'TRANSPORT_IN':
data = entry.get('data', {})
raw = data.get('raw', '')
if raw:
try:
msg = json.loads(raw.strip())
if 'method' in msg:
methods[msg['method']] += 1
requests.append({
'line': line_no,
'time': entry.get('timestamp'),
'method': msg['method'],
'id': msg.get('id'),
'params': msg.get('params', {})
})
except:
pass
elif level == 'TRANSPORT_OUT':
data = entry.get('data', {})
if data.get('has_error'):
errors.append({
'line': line_no,
'time': entry.get('timestamp'),
'id': data.get('id')
})
else:
responses.append({
'line': line_no,
'time': entry.get('timestamp'),
'id': data.get('id')
})
elif level == 'ERROR':
errors.append({
'line': line_no,
'time': entry.get('timestamp'),
'message': entry.get('message'),
'data': entry.get('data')
})
except json.JSONDecodeError:
print(f"Warning: Invalid JSON at line {line_no}")
# Display summary
print("📊 Summary:")
print(f" Total requests: {len(requests)}")
print(f" Total responses: {len(responses)}")
print(f" Total errors: {len([e for e in errors if 'message' in e])}")
print()
print("📨 Methods called:")
for method, count in sorted(methods.items()):
print(f" {method}: {count}")
print()
print("📋 Request sequence:")
for req in requests:
print(f" Line {req['line']}: {req['method']} (id: {req['id']})")
if req['method'] == 'initialize':
params = req.get('params', {})
client = params.get('clientInfo', {})
if client:
print(f" Client: {client.get('name')} v{client.get('version')}")
caps = params.get('capabilities', {})
if caps:
print(f" Capabilities: {', '.join(caps.keys())}")
print()
if errors:
print("❌ Errors found:")
for err in errors:
if 'message' in err:
print(f" Line {err['line']}: {err.get('message')}")
if err.get('data'):
print(f" Details: {err['data']}")
else:
print("✅ No errors found")
# Check for potential issues
print("\n🔍 Potential issues:")
issues = []
# Check if all requests got responses
req_ids = {r['id'] for r in requests if r['id'] is not None}
resp_ids = {r['id'] for r in responses}
missing = req_ids - resp_ids
if missing:
issues.append(f"Requests without responses: {missing}")
# Check for unknown methods
known_methods = {'initialize', 'initialized', 'tools/list', 'resources/list',
'prompts/list', 'tools/call', 'ping'}
unknown = set(methods.keys()) - known_methods - {''}
if unknown:
issues.append(f"Unknown methods: {unknown}")
if issues:
for issue in issues:
print(f" ⚠️ {issue}")
else:
print(" None detected")
if __name__ == "__main__":
# Find latest trace file if not specified
if len(sys.argv) > 1:
trace_file = sys.argv[1]
else:
# Find latest in /tmp
import glob
files = glob.glob('/tmp/mcp_trace_*.log')
if not files:
print("No trace files found in /tmp/")
sys.exit(1)
trace_file = max(files, key=os.path.getmtime)
if os.path.exists(trace_file):
analyze_trace(trace_file)
else:
print(f"Error: File not found: {trace_file}")
sys.exit(1)