diff --git a/.vscode/HumanAgent-server.log b/.vscode/HumanAgent-server.log deleted file mode 100644 index 76faad2..0000000 --- a/.vscode/HumanAgent-server.log +++ /dev/null @@ -1,644 +0,0 @@ -[2025-10-24 20:43:48.111] [DEBUG] Debug logging started at 2025-10-24T09:43:48.111Z -[2025-10-24 20:43:48.111] [DEBUG] Current system time: Fri Oct 24 2025 20:43:48 GMT+1100 (Australian Eastern Daylight Time) -[2025-10-24 20:43:48.111] [DEBUG] Log file: /Users/benharper/Coding/HumanAgent-MCP/.vscode/HumanAgent-server.log -[2025-10-24 20:43:48.111] [DEBUG] Working directory: /Users/benharper/Coding/HumanAgent-MCP -[2025-10-24 20:43:48.111] [DEBUG] Logging level set to: DEBUG -[2025-10-24 20:43:48.111] [CHAT] [INFO] ChatManager initialized with max 50 messages per session -[2025-10-24 20:43:48.111] [INFO] McpServer initialized with centralized chat manager -[2025-10-24 20:43:48.112] [TEST] This is a test log message to verify DebugLogger is working -[2025-10-24 20:43:48.112] [INFO] === MCP SERVER STARTING === -[2025-10-24 20:43:48.112] [INFO] Starting HTTP server on port 3737... -[2025-10-24 20:43:48.116] [INFO] MCP HTTP server running on http://127.0.0.1:3737/mcp -[2025-10-24 20:43:48.823] [HTTP] GET /mcp -[2025-10-24 20:43:48.823] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "cache-control": "no-cache", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/event-stream", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:48.824] [HTTP] Handling GET request to /mcp -[2025-10-24 20:43:48.824] [HTTP] Setting up SSE stream for GET request -[2025-10-24 20:43:48.824] [SSE] === SSE CONNECTION ATTEMPT === -[2025-10-24 20:43:48.824] [SSE] Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "cache-control": "no-cache", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/event-stream", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:48.824] [SSE] URL: -"/mcp" -[2025-10-24 20:43:48.824] [SSE] No sessionId in SSE request (tried URL param and Mcp-Session-Id header) -[2025-10-24 20:43:48.824] [SSE] Request headers: {"host":"localhost:3737","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","cache-control":"no-cache","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36","accept":"text/event-stream","sec-ch-ua":"\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3737/HumanAgent","accept-encoding":"gzip, deflate, br, zstd","accept-language":"en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6","cookie":"csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh"} -[2025-10-24 20:43:48.824] [SSE] Request URL: /mcp -[2025-10-24 20:43:48.824] [SSE] Using default sessionId: default-sse-session -[2025-10-24 20:43:48.824] [SSE] SSE headers set for session default-sse-session, adding to connections... -[2025-10-24 20:43:48.824] [HTTP] Added SSE connection for session default-sse-session. Total connections: 1 -[2025-10-24 20:43:48.824] [SSE] SSE connection added for session default-sse-session. Total: 1 -[2025-10-24 20:43:48.825] [SSE] Sent initial SSE message: -"data: {\"type\":\"connection\",\"status\":\"established\",\"sessionId\":\"default-sse-session\"}" -[2025-10-24 20:43:48.831] [HTTP] GET /sessions/session-a8f49eee-068c-42f1-b611-14651fa5ccc6/messages -[2025-10-24 20:43:48.831] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "accept": "*/*", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:52.685] [HTTP] GET /HumanAgent -[2025-10-24 20:43:52.685] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "cache-control": "max-age=0", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-platform": "\"macOS\"", - "upgrade-insecure-requests": "1", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", - "sec-fetch-site": "none", - "sec-fetch-mode": "navigate", - "sec-fetch-user": "?1", - "sec-fetch-dest": "document", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:52.686] [HTTP] Serving web interface at /HumanAgent -[2025-10-24 20:43:52.691] [HTTP] SSE connection closed for session default-sse-session -[2025-10-24 20:43:52.691] [HTTP] Removed SSE connection for session default-sse-session. Total connections: 0 -[2025-10-24 20:43:52.691] [HTTP] SSE connection closed for session default-sse-session -[2025-10-24 20:43:52.691] [HTTP] Removed SSE connection for session default-sse-session. Total connections: 0 -[2025-10-24 20:43:52.696] [HTTP] GET /sessions//messages -[2025-10-24 20:43:52.696] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "accept": "*/*", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:52.704] [HTTP] GET /mcp -[2025-10-24 20:43:52.704] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "cache-control": "no-cache", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/event-stream", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:52.704] [HTTP] Handling GET request to /mcp -[2025-10-24 20:43:52.704] [HTTP] Setting up SSE stream for GET request -[2025-10-24 20:43:52.704] [SSE] === SSE CONNECTION ATTEMPT === -[2025-10-24 20:43:52.704] [SSE] Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "cache-control": "no-cache", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/event-stream", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:52.704] [SSE] URL: -"/mcp" -[2025-10-24 20:43:52.704] [SSE] No sessionId in SSE request (tried URL param and Mcp-Session-Id header) -[2025-10-24 20:43:52.704] [SSE] Request headers: {"host":"localhost:3737","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","cache-control":"no-cache","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36","accept":"text/event-stream","sec-ch-ua":"\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3737/HumanAgent","accept-encoding":"gzip, deflate, br, zstd","accept-language":"en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6","cookie":"csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh"} -[2025-10-24 20:43:52.704] [SSE] Request URL: /mcp -[2025-10-24 20:43:52.704] [SSE] Using default sessionId: default-sse-session -[2025-10-24 20:43:52.704] [SSE] SSE headers set for session default-sse-session, adding to connections... -[2025-10-24 20:43:52.704] [HTTP] Added SSE connection for session default-sse-session. Total connections: 1 -[2025-10-24 20:43:52.704] [SSE] SSE connection added for session default-sse-session. Total: 1 -[2025-10-24 20:43:52.705] [SSE] Sent initial SSE message: -"data: {\"type\":\"connection\",\"status\":\"established\",\"sessionId\":\"default-sse-session\"}" -[2025-10-24 20:43:53.571] [HTTP] GET /HumanAgent -[2025-10-24 20:43:53.572] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "cache-control": "max-age=0", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-platform": "\"macOS\"", - "upgrade-insecure-requests": "1", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", - "sec-fetch-site": "none", - "sec-fetch-mode": "navigate", - "sec-fetch-user": "?1", - "sec-fetch-dest": "document", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:53.572] [HTTP] Serving web interface at /HumanAgent -[2025-10-24 20:43:53.575] [HTTP] SSE connection closed for session default-sse-session -[2025-10-24 20:43:53.575] [HTTP] Removed SSE connection for session default-sse-session. Total connections: 0 -[2025-10-24 20:43:53.575] [HTTP] SSE connection closed for session default-sse-session -[2025-10-24 20:43:53.575] [HTTP] Removed SSE connection for session default-sse-session. Total connections: 0 -[2025-10-24 20:43:53.584] [HTTP] GET /sessions//messages -[2025-10-24 20:43:53.584] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "accept": "*/*", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:53.592] [HTTP] GET /mcp -[2025-10-24 20:43:53.592] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "cache-control": "no-cache", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/event-stream", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:53.592] [HTTP] Handling GET request to /mcp -[2025-10-24 20:43:53.592] [HTTP] Setting up SSE stream for GET request -[2025-10-24 20:43:53.592] [SSE] === SSE CONNECTION ATTEMPT === -[2025-10-24 20:43:53.592] [SSE] Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "cache-control": "no-cache", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/event-stream", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:53.592] [SSE] URL: -"/mcp" -[2025-10-24 20:43:53.593] [SSE] No sessionId in SSE request (tried URL param and Mcp-Session-Id header) -[2025-10-24 20:43:53.593] [SSE] Request headers: {"host":"localhost:3737","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","cache-control":"no-cache","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36","accept":"text/event-stream","sec-ch-ua":"\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3737/HumanAgent","accept-encoding":"gzip, deflate, br, zstd","accept-language":"en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6","cookie":"csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh"} -[2025-10-24 20:43:53.593] [SSE] Request URL: /mcp -[2025-10-24 20:43:53.593] [SSE] Using default sessionId: default-sse-session -[2025-10-24 20:43:53.593] [SSE] SSE headers set for session default-sse-session, adding to connections... -[2025-10-24 20:43:53.593] [HTTP] Added SSE connection for session default-sse-session. Total connections: 1 -[2025-10-24 20:43:53.593] [SSE] SSE connection added for session default-sse-session. Total: 1 -[2025-10-24 20:43:53.593] [SSE] Sent initial SSE message: -"data: {\"type\":\"connection\",\"status\":\"established\",\"sessionId\":\"default-sse-session\"}" -[2025-10-24 20:43:54.386] [HTTP] GET /HumanAgent -[2025-10-24 20:43:54.386] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "cache-control": "max-age=0", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-platform": "\"macOS\"", - "upgrade-insecure-requests": "1", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", - "sec-fetch-site": "none", - "sec-fetch-mode": "navigate", - "sec-fetch-user": "?1", - "sec-fetch-dest": "document", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:54.386] [HTTP] Serving web interface at /HumanAgent -[2025-10-24 20:43:54.390] [HTTP] SSE connection closed for session default-sse-session -[2025-10-24 20:43:54.390] [HTTP] Removed SSE connection for session default-sse-session. Total connections: 0 -[2025-10-24 20:43:54.390] [HTTP] SSE connection closed for session default-sse-session -[2025-10-24 20:43:54.390] [HTTP] Removed SSE connection for session default-sse-session. Total connections: 0 -[2025-10-24 20:43:54.401] [HTTP] GET /sessions//messages -[2025-10-24 20:43:54.401] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "accept": "*/*", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:54.407] [HTTP] GET /mcp -[2025-10-24 20:43:54.407] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "cache-control": "no-cache", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/event-stream", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:54.407] [HTTP] Handling GET request to /mcp -[2025-10-24 20:43:54.407] [HTTP] Setting up SSE stream for GET request -[2025-10-24 20:43:54.407] [SSE] === SSE CONNECTION ATTEMPT === -[2025-10-24 20:43:54.407] [SSE] Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "cache-control": "no-cache", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/event-stream", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:54.407] [SSE] URL: -"/mcp" -[2025-10-24 20:43:54.407] [SSE] No sessionId in SSE request (tried URL param and Mcp-Session-Id header) -[2025-10-24 20:43:54.407] [SSE] Request headers: {"host":"localhost:3737","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","cache-control":"no-cache","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36","accept":"text/event-stream","sec-ch-ua":"\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3737/HumanAgent","accept-encoding":"gzip, deflate, br, zstd","accept-language":"en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6","cookie":"csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh"} -[2025-10-24 20:43:54.407] [SSE] Request URL: /mcp -[2025-10-24 20:43:54.407] [SSE] Using default sessionId: default-sse-session -[2025-10-24 20:43:54.407] [SSE] SSE headers set for session default-sse-session, adding to connections... -[2025-10-24 20:43:54.407] [HTTP] Added SSE connection for session default-sse-session. Total connections: 1 -[2025-10-24 20:43:54.407] [SSE] SSE connection added for session default-sse-session. Total: 1 -[2025-10-24 20:43:54.407] [SSE] Sent initial SSE message: -"data: {\"type\":\"connection\",\"status\":\"established\",\"sessionId\":\"default-sse-session\"}" -[2025-10-24 20:43:56.550] [HTTP] GET /HumanAgent -[2025-10-24 20:43:56.550] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "cache-control": "max-age=0", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-platform": "\"macOS\"", - "upgrade-insecure-requests": "1", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", - "sec-fetch-site": "none", - "sec-fetch-mode": "navigate", - "sec-fetch-user": "?1", - "sec-fetch-dest": "document", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:56.550] [HTTP] Serving web interface at /HumanAgent -[2025-10-24 20:43:56.557] [HTTP] SSE connection closed for session default-sse-session -[2025-10-24 20:43:56.557] [HTTP] Removed SSE connection for session default-sse-session. Total connections: 0 -[2025-10-24 20:43:56.557] [HTTP] SSE connection closed for session default-sse-session -[2025-10-24 20:43:56.557] [HTTP] Removed SSE connection for session default-sse-session. Total connections: 0 -[2025-10-24 20:43:56.565] [HTTP] GET /sessions//messages -[2025-10-24 20:43:56.565] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "accept": "*/*", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:56.568] [HTTP] GET /mcp -[2025-10-24 20:43:56.568] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "cache-control": "no-cache", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/event-stream", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:56.568] [HTTP] Handling GET request to /mcp -[2025-10-24 20:43:56.568] [HTTP] Setting up SSE stream for GET request -[2025-10-24 20:43:56.568] [SSE] === SSE CONNECTION ATTEMPT === -[2025-10-24 20:43:56.568] [SSE] Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "cache-control": "no-cache", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/event-stream", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:56.568] [SSE] URL: -"/mcp" -[2025-10-24 20:43:56.568] [SSE] No sessionId in SSE request (tried URL param and Mcp-Session-Id header) -[2025-10-24 20:43:56.568] [SSE] Request headers: {"host":"localhost:3737","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","cache-control":"no-cache","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36","accept":"text/event-stream","sec-ch-ua":"\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3737/HumanAgent","accept-encoding":"gzip, deflate, br, zstd","accept-language":"en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6","cookie":"csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh"} -[2025-10-24 20:43:56.568] [SSE] Request URL: /mcp -[2025-10-24 20:43:56.568] [SSE] Using default sessionId: default-sse-session -[2025-10-24 20:43:56.568] [SSE] SSE headers set for session default-sse-session, adding to connections... -[2025-10-24 20:43:56.568] [HTTP] Added SSE connection for session default-sse-session. Total connections: 1 -[2025-10-24 20:43:56.568] [SSE] SSE connection added for session default-sse-session. Total: 1 -[2025-10-24 20:43:56.568] [SSE] Sent initial SSE message: -"data: {\"type\":\"connection\",\"status\":\"established\",\"sessionId\":\"default-sse-session\"}" -[2025-10-24 20:43:58.232] [HTTP] GET /HumanAgent -[2025-10-24 20:43:58.232] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "cache-control": "max-age=0", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-platform": "\"macOS\"", - "upgrade-insecure-requests": "1", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", - "sec-fetch-site": "none", - "sec-fetch-mode": "navigate", - "sec-fetch-user": "?1", - "sec-fetch-dest": "document", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:58.233] [HTTP] Serving web interface at /HumanAgent -[2025-10-24 20:43:58.237] [HTTP] SSE connection closed for session default-sse-session -[2025-10-24 20:43:58.238] [HTTP] Removed SSE connection for session default-sse-session. Total connections: 0 -[2025-10-24 20:43:58.238] [HTTP] SSE connection closed for session default-sse-session -[2025-10-24 20:43:58.238] [HTTP] Removed SSE connection for session default-sse-session. Total connections: 0 -[2025-10-24 20:43:58.246] [HTTP] GET /sessions//messages -[2025-10-24 20:43:58.246] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "accept": "*/*", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:58.250] [HTTP] GET /mcp -[2025-10-24 20:43:58.250] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "cache-control": "no-cache", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/event-stream", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:58.250] [HTTP] Handling GET request to /mcp -[2025-10-24 20:43:58.250] [HTTP] Setting up SSE stream for GET request -[2025-10-24 20:43:58.250] [SSE] === SSE CONNECTION ATTEMPT === -[2025-10-24 20:43:58.250] [SSE] Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "cache-control": "no-cache", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/event-stream", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:58.250] [SSE] URL: -"/mcp" -[2025-10-24 20:43:58.250] [SSE] No sessionId in SSE request (tried URL param and Mcp-Session-Id header) -[2025-10-24 20:43:58.250] [SSE] Request headers: {"host":"localhost:3737","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","cache-control":"no-cache","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36","accept":"text/event-stream","sec-ch-ua":"\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3737/HumanAgent","accept-encoding":"gzip, deflate, br, zstd","accept-language":"en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6","cookie":"csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh"} -[2025-10-24 20:43:58.250] [SSE] Request URL: /mcp -[2025-10-24 20:43:58.250] [SSE] Using default sessionId: default-sse-session -[2025-10-24 20:43:58.250] [SSE] SSE headers set for session default-sse-session, adding to connections... -[2025-10-24 20:43:58.250] [HTTP] Added SSE connection for session default-sse-session. Total connections: 1 -[2025-10-24 20:43:58.250] [SSE] SSE connection added for session default-sse-session. Total: 1 -[2025-10-24 20:43:58.250] [SSE] Sent initial SSE message: -"data: {\"type\":\"connection\",\"status\":\"established\",\"sessionId\":\"default-sse-session\"}" -[2025-10-24 20:43:58.406] [HTTP] GET /HumanAgent -[2025-10-24 20:43:58.406] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "cache-control": "max-age=0", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-ch-ua-platform": "\"macOS\"", - "upgrade-insecure-requests": "1", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", - "sec-fetch-site": "none", - "sec-fetch-mode": "navigate", - "sec-fetch-user": "?1", - "sec-fetch-dest": "document", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:58.406] [HTTP] Serving web interface at /HumanAgent -[2025-10-24 20:43:58.411] [HTTP] SSE connection closed for session default-sse-session -[2025-10-24 20:43:58.411] [HTTP] Removed SSE connection for session default-sse-session. Total connections: 0 -[2025-10-24 20:43:58.411] [HTTP] SSE connection closed for session default-sse-session -[2025-10-24 20:43:58.411] [HTTP] Removed SSE connection for session default-sse-session. Total connections: 0 -[2025-10-24 20:43:58.420] [HTTP] GET /sessions//messages -[2025-10-24 20:43:58.420] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "accept": "*/*", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:58.425] [HTTP] GET /mcp -[2025-10-24 20:43:58.425] [HTTP] Request Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "cache-control": "no-cache", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/event-stream", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:58.425] [HTTP] Handling GET request to /mcp -[2025-10-24 20:43:58.425] [HTTP] Setting up SSE stream for GET request -[2025-10-24 20:43:58.425] [SSE] === SSE CONNECTION ATTEMPT === -[2025-10-24 20:43:58.425] [SSE] Headers: -{ - "host": "localhost:3737", - "connection": "keep-alive", - "sec-ch-ua-platform": "\"macOS\"", - "cache-control": "no-cache", - "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36", - "accept": "text/event-stream", - "sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"", - "sec-ch-ua-mobile": "?0", - "sec-fetch-site": "same-origin", - "sec-fetch-mode": "cors", - "sec-fetch-dest": "empty", - "referer": "http://localhost:3737/HumanAgent", - "accept-encoding": "gzip, deflate, br, zstd", - "accept-language": "en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6", - "cookie": "csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh" -} -[2025-10-24 20:43:58.425] [SSE] URL: -"/mcp" -[2025-10-24 20:43:58.425] [SSE] No sessionId in SSE request (tried URL param and Mcp-Session-Id header) -[2025-10-24 20:43:58.425] [SSE] Request headers: {"host":"localhost:3737","connection":"keep-alive","sec-ch-ua-platform":"\"macOS\"","cache-control":"no-cache","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36","accept":"text/event-stream","sec-ch-ua":"\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:3737/HumanAgent","accept-encoding":"gzip, deflate, br, zstd","accept-language":"en,en-US;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6","cookie":"csrftoken=ZAgfvccRW3GTeUh5I2OhLyXWqlCkYBLh"} -[2025-10-24 20:43:58.425] [SSE] Request URL: /mcp -[2025-10-24 20:43:58.425] [SSE] Using default sessionId: default-sse-session -[2025-10-24 20:43:58.425] [SSE] SSE headers set for session default-sse-session, adding to connections... -[2025-10-24 20:43:58.425] [HTTP] Added SSE connection for session default-sse-session. Total connections: 1 -[2025-10-24 20:43:58.425] [SSE] SSE connection added for session default-sse-session. Total: 1 -[2025-10-24 20:43:58.425] [SSE] Sent initial SSE message: -"data: {\"type\":\"connection\",\"status\":\"established\",\"sessionId\":\"default-sse-session\"}" diff --git a/.vscode/mcp.json b/.vscode/mcp.json index 748ddae..cc549a0 100644 --- a/.vscode/mcp.json +++ b/.vscode/mcp.json @@ -10,14 +10,6 @@ "6000" ], "env": {} - }, - "humanagent-mcp": { - "type": "http", - "url": "http://127.0.0.1:3737/mcp?sessionId=session-a8f49eee-068c-42f1-b611-14651fa5ccc6", - "notifications": { - "enableSound": true, - "enableFlashing": true - } } }, "inputs": [] diff --git a/README.md b/README.md deleted file mode 100644 index 5b6d66e..0000000 --- a/README.md +++ /dev/null @@ -1,314 +0,0 @@ -# HumanAgent MCP - VS Code Extension - -# HumanAgent MCP - -A VS Code extension that enables AI agents to communicate directly with developers through an integrated chat interface. Built on the Model Context Protocol (MCP) standard. - -## What it does - -When AI assistants like Claude or Cursor need clarification, approval, or input from you, they can use the HumanAgent_Chat tool to send messages directly to your VS Code interface. You see their questions in real-time and can respond immediately, creating a seamless collaborative workflow. - -## Installation - -1. Open VS Code -2. Install the HumanAgent MCP extension from the marketplace -3. The extension automatically starts an MCP server on port 3737 -4. Configure your AI assistant to use the MCP server at `http://127.0.0.1:3737/mcp` - -## Usage - -### VS Code Interface - -After installation, you'll see: -- **Chat Sessions** view in the Explorer panel showing active conversations -- **HumanAgent Chat** panel (dockable) for the main chat interface -- Audio notifications when new messages arrive (configurable) - -### Basic Workflow - -1. AI assistant calls the `HumanAgent_Chat` tool when it needs human input -2. Message appears in your VS Code chat interface with optional sound notification -3. You respond through the chat interface -4. AI assistant receives your response and continues working - -### Commands - -- **Create New Chat Session** - Start a fresh conversation -- **Configure MCP Server** - Set up workspace or global MCP registration -- **Show Status** - View server status and active sessions - -## Configuration - -### MCP Server Registration - -The extension can register the MCP server in two ways: - -**Workspace Registration** (Recommended) -- Creates `.vscode/mcp.json` in your current workspace -- Server only available to this workspace -- Automatic session management per workspace - -**Global Registration** -- Registers in VS Code's global MCP settings -- Available to all workspaces -- Manual session management - -### Settings - -Access via VS Code Settings (search for "HumanAgent"): - -- `humanagent-mcp.logging.enabled` - Enable debug logging to `.vscode` directory (default: false) -- `humanagent-mcp.logging.level` - Log level: ERROR, WARN, INFO, DEBUG (default: INFO) - -### Tool Customization - -Create `.vscode/override-prompt.md` in your workspace to customize how the AI tool behaves: - -```markdown -# Custom HumanAgent_Chat Tool - -## Description -Your custom description here - -## Properties -- message: Custom message field description -- timeout: Response timeout in seconds (optional) -``` - -## Web Interface - -Access the web interface at `http://127.0.0.1:3737/` to: -- View chat sessions from any browser -- Send messages from outside VS Code -- Monitor active conversations - -## Requirements - -- VS Code 1.105.0 or higher -- Network access to localhost port 3737 -- AI assistant configured to use MCP (Claude, Cursor, etc.) - -## Troubleshooting - -**Extension not starting** -- Check VS Code Developer Console for errors -- Verify port 3737 is not in use by another application - -**AI can't connect** -- Ensure MCP server is registered (use Configure MCP Server command) -- Check the server URL includes your session ID: `http://127.0.0.1:3737/mcp?sessionId=your-session-id` - -**No audio notifications** -- Check VS Code notification settings -- Test notifications using the Configure panel - -**Messages not appearing** -- Refresh the Chat Sessions view -- Check server status in the HumanAgent Chat panel - -## License - -MIT License - -## Features - -- ** AI-to-Human Communication**: AI agents can send messages and questions directly to developers -- ** VS Code Chat Interface**: Dockable chat panel integrated into VS Code -- ** Session Management**: Each workspace gets its own communication session -- ** Workspace Tool Overrides**: Customize MCP tool behavior per workspace -- ** Audio Notifications**: Optional sound alerts for new AI messages -- ** Status Monitoring**: Track server status and pending requests -- ** HTTP + Stdio Support**: Compatible with various MCP clients - -## Installation - -### VS Code Marketplace (Recommended) - -1. Open VS Code -2. Go to Extensions (`Ctrl+Shift+X` or `Cmd+Shift+X`) -3. Search for "HumanAgent MCP" -4. Click **Install** -5. The extension will auto-configure and start working - -### Manual Installation - -Download the `.vsix` file from releases and install: -```bash -code --install-extension humanagent-mcp-*.vsix -``` - -## Quick Start - -1. **Install the extension** in VS Code -2. **Open any workspace** - the extension auto-starts -3. **Open the HumanAgent Chat** panel (View → HumanAgent MCP Chat) -4. **AI agents can immediately send messages** that appear in your chat interface - -The extension automatically: -- ✅ Configures MCP server settings -- ✅ Starts HTTP server on port 3737 -- ✅ Registers with VS Code's MCP system -- ✅ Creates workspace-specific session - -## How It Works - -The extension automatically: -- ✅ Starts an MCP server on `http://127.0.0.1:3737/mcp` -- ✅ Configures itself within VS Code's extension system -- ✅ Provides the `HumanAgent_Chat` tool for AI agents -- ✅ Creates a chat interface for receiving AI messages - -**For AI agents:** Use the MCP tool `HumanAgent_Chat` to send messages to the human developer. Messages appear instantly in the VS Code chat panel. - -## Tool Customization - -Create a `.vscode/HumanAgentOverride.json` file in your workspace to customize tool behavior: - -```json -{ - "version": "1.0.0", - "description": "Custom HumanAgent tools for this workspace", - "tools": { - "HumanAgent_Chat": { - "name": "HumanAgent_Chat", - "description": "Custom description for this workspace's chat tool", - "inputSchema": { - "type": "object", - "properties": { - "message": { - "type": "string", - "description": "The message to send" - }, - "context": { - "type": "string", - "description": "Optional context" - }, - "priority": { - "type": "string", - "enum": ["low", "normal", "high", "urgent"], - "default": "normal" - } - }, - "required": ["message"] - } - } - } -} -``` - -Use the **🔄 Reload Override File** option in the chat panel's cog menu to apply changes. - -## Available Commands - -- **Create Session**: Initialize a new chat session -- **Show Status**: Display server status and statistics -- **Configure MCP**: Set up MCP server registration -- **Override Prompt**: Create workspace-specific tool configurations - -## Architecture - -``` -┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ -│ MCP Client │ │ HumanAgent MCP │ │ VS Code UI │ -│ (Claude/Cursor) │◄──►│ Server │◄──►│ Chat Interface │ -│ │ │ (Port 3737) │ │ │ -└─────────────────┘ └──────────────────┘ └─────────────────┘ -``` - -## Development - -### Development Installation - -```bash -git clone -cd humanagent-mcp -npm install -npm run compile -``` - -Press `F5` in VS Code to launch the Extension Development Host. - -### Project Structure -``` -src/ -├── extension.ts # VS Code extension entry point -├── mcp/ -│ ├── server.ts # MCP HTTP server implementation -│ ├── mcpStandalone.js # Standalone server runner -│ └── types.ts # TypeScript definitions -├── webview/ -│ └── chatWebviewProvider.ts # Chat UI implementation -└── providers/ - └── chatTreeProvider.ts # Session tree view -``` - -### Build Commands -```bash -npm run compile # TypeScript compilation -npm run watch # Watch mode for development -npm run package # Production build -``` - -### Testing -```bash -# Test MCP server directly -curl -X POST http://localhost:3737/mcp \ - -H "Content-Type: application/json" \ - -d '{"id":"test","type":"request","method":"tools/list"}' -``` - -## Logging - -- **Development**: Logs appear in VS Code Developer Console -- **Production**: Logs saved to `.vscode/HumanAgent.log` in each workspace -- **Standalone**: Logs saved to system temp directory - -## Technical Details - -### MCP Protocol Support -- **Protocol Version**: 2024-11-05 -- **Transport**: HTTP (primary), Stdio (compatibility) -- **Tools**: `HumanAgent_Chat` with workspace customization -- **Session Management**: Isolated per workspace - -### Security Considerations -- HTTP server binds to localhost only (127.0.0.1) -- No external network access required -- Workspace-specific tool isolation - -## Limitations - -- Requires VS Code to be running for AI communication -- HTTP server uses fixed port 3737 (configurable in code) -- Tool overrides require manual reload after changes - -## Troubleshooting - -**Server not starting?** -- Check port 3737 is available: `lsof -i :3737` -- Verify workspace has write permissions for `.vscode/` directory - -**AI messages not appearing?** -- Confirm MCP client is connected to `http://127.0.0.1:3737/mcp` -- Check HumanAgent Chat panel is open in VS Code -- Review logs in `.vscode/HumanAgent.log` - -**Override file not working?** -- Validate JSON syntax in HumanAgentOverride.json -- Use "🔄 Reload Override File" to apply changes -- Check Developer Console for error messages - -## License - -MIT License - see [LICENSE](LICENSE) file for details. - -## Contributing - -1. Fork the repository -2. Create a feature branch -3. Make your changes with tests -4. Submit a pull request - ---- - -**Built for seamless AI-human collaboration in VS Code** 🚀 \ No newline at end of file diff --git a/ReadMeDev.md b/ReadMeDev.md deleted file mode 100644 index 481197f..0000000 --- a/ReadMeDev.md +++ /dev/null @@ -1,330 +0,0 @@ -# HumanAgent MCP - Developer Documentation - -Technical documentation for developers working on or extending the HumanAgent MCP extension. - -## Architecture - -### Core Components - -**Extension Entry Point** (`src/extension.ts`) -- VS Code extension activation and lifecycle -- MCP server definition provider for VS Code native integration -- Session management and workspace detection -- Command registration and event handling - -**MCP Server** (`src/mcp/server.ts`) -- HTTP server on port 3737 serving MCP protocol -- Tool definitions and execution (HumanAgent_Chat) -- Session-specific tool overrides -- SSE connections for real-time updates -- Web interface generation - -**Chat Manager** (`src/mcp/chatManager.ts`) -- Centralized message and session storage -- Request/response correlation -- Session cleanup and memory management - -**Webview Provider** (`src/webview/chatWebviewProvider.ts`) -- VS Code webview integration -- Chat interface UI and messaging -- Server configuration and status monitoring - -**Configuration Manager** (`src/mcp/mcpConfigManager.ts`) -- MCP server registration (workspace/global) -- Configuration file management (.vscode/mcp.json) - -### Data Flow - -``` -AI Client -> MCP Server (port 3737) -> ChatManager -> Webview Provider -> VS Code UI - -> SSE Client -> Web Interface -``` - -## Key Features Implementation - -### Session Management - -Each workspace gets a unique session ID based on workspace path hash. Session data includes: -- Chat message history (managed by ChatManager) -- Pending requests awaiting human response -- Tool overrides loaded from `.vscode/override-prompt.md` -- Workspace-specific configuration - -### Tool Override System - -1. Default `HumanAgent_Chat` tool defined in `server.ts` -2. Per-workspace overrides loaded from `.vscode/override-prompt.md` -3. Markdown parsed to extract tool description and schema modifications -4. Session-specific tool maps maintain overrides per workspace - -### Real-time Communication - -- **MCP Protocol**: Standard JSON-RPC over HTTP for AI client communication -- **SSE (Server-Sent Events)**: Real-time updates to webview and web interface -- **VS Code Events**: Native VS Code messaging for webview updates - -## Development Setup - -### Prerequisites - -- Node.js 18+ -- VS Code 1.105.0+ -- TypeScript knowledge - -### Build Process - -```bash -# Install dependencies -npm install - -# Development build with watch -npm run watch - -# Production build -npm run package - -# Compile extension only -npm run compile -``` - -### Project Structure - -``` -src/ -├── extension.ts # Extension entry point -├── mcp/ -│ ├── server.ts # MCP server implementation -│ ├── chatManager.ts # Session and message management -│ ├── mcpConfigManager.ts # Configuration handling -│ ├── types.ts # TypeScript interfaces -│ └── mcpStandalone.ts # Standalone server entry -├── webview/ -│ └── chatWebviewProvider.ts # VS Code webview integration -├── providers/ -│ └── chatTreeProvider.ts # Explorer tree view -├── audio/ -│ └── audioNotification.ts # Sound notifications -└── serverManager.ts # Server lifecycle management -``` - -### Key Classes - -**McpServer** -- Main server class implementing MCP protocol -- Tool registration and execution -- HTTP request handling and routing -- SSE connection management - -**ChatManager** -- Message storage and retrieval -- Pending request tracking -- Session lifecycle management -- Memory cleanup and limits - -**ChatWebviewProvider** -- VS Code webview implementation -- Chat UI rendering and interaction -- Server status monitoring -- Configuration management - -## Configuration Files - -### Extension Manifest (`package.json`) - -Key sections: -- `contributes.commands` - VS Code commands -- `contributes.views` - Panel and tree view definitions -- `contributes.configuration` - User settings schema -- `contributes.mcpServerDefinitionProviders` - VS Code MCP integration - -### Workspace Configuration (`.vscode/mcp.json`) - -Generated automatically when registering workspace MCP server: - -```json -{ - "servers": { - "humanagent-mcp": { - "type": "http", - "url": "http://127.0.0.1:3737/mcp?sessionId=session-xxx", - "notifications": { - "enableSound": true, - "enableFlashing": true - } - } - } -} -``` - -### Tool Override (`.vscode/override-prompt.md`) - -Markdown file for customizing tool behavior per workspace. Parsed sections: -- Description becomes tool description -- Properties section modifies input schema -- Additional context included in tool execution - -## API Endpoints - -The MCP server exposes both MCP protocol and web endpoints: - -### MCP Protocol (`/mcp`) - -Standard MCP JSON-RPC methods: -- `initialize` - Client initialization -- `tools/list` - Available tools query -- `tools/call` - Tool execution (HumanAgent_Chat) - -### Web Endpoints - -- `GET /` - Web chat interface -- `GET /sessions` - Session list API -- `POST /send-message` - Web message sending -- `GET /sse/{sessionId}` - Server-sent events connection - -## Testing - -### Extension Testing - -```bash -# Run in extension development host -# Press F5 in VS Code to launch debug instance -``` - -### MCP Server Testing - -```bash -# Test server independently -node dist/mcpStandalone.js -curl http://127.0.0.1:3737/sessions -``` - -### Integration Testing - -Test AI client integration by configuring Claude/Cursor with: -``` -http://127.0.0.1:3737/mcp?sessionId=test-session -``` - -## Logging and Debugging - -### Extension Logs - -Enable debug logging via settings: -- `humanagent-mcp.logging.enabled` = true -- `humanagent-mcp.logging.level` = "DEBUG" - -Logs written to `.vscode/HumanAgent-server.log` in workspace. - -### VS Code Debug Console - -View extension debug output: -1. Help > Toggle Developer Tools -2. Console tab shows extension logs - -### Server Debug Mode - -Environment variables for standalone server: -```bash -HUMANAGENT_LOGGING_ENABLED=true -HUMANAGENT_LOGGING_LEVEL=DEBUG -node dist/mcpStandalone.js -``` - -## Extension Points - -### Adding New Tools - -1. Define tool in `initializeDefaultTools()` method -2. Add handler in `handleToolCall()` method -3. Update tool override parsing if needed - -### Custom Notification Types - -1. Add new SSE message types in `sendMcpNotification()` -2. Handle in webview JavaScript -3. Update UI accordingly - -### Additional Configuration - -1. Add to `package.json` contributes.configuration -2. Read settings in extension code -3. Pass to server during initialization - -## Common Patterns - -### Async Request Handling - -```typescript -// Store request resolver -this.requestResolvers.set(requestId, { - resolve: (response: string) => { - // Handle response - }, - reject: (error: Error) => { - // Handle error - } -}); - -// Set timeout if needed -if (timeoutMs) { - setTimeout(() => { - // Timeout logic - }, timeoutMs); -} -``` - -### Session-Specific Operations - -```typescript -// Get session tools -const sessionTools = this.sessionTools.get(sessionId) || this.tools; - -// Store session data -this.sessionData.set(sessionId, data); - -// Clean up session -this.activeSessions.delete(sessionId); -``` - -### Webview Communication - -```typescript -// Send to webview -this._view.webview.postMessage({ - type: 'messageType', - data: payload -}); - -// Handle webview messages -webview.onDidReceiveMessage(message => { - switch (message.type) { - case 'actionType': - // Handle action - break; - } -}); -``` - -## Build and Packaging - -### Development Build - -```bash -npm run compile -``` - -### Production Package - -```bash -npm run package -``` - -This creates `dist/extension.js` and `dist/mcpStandalone.js` for distribution. - -### Extension Packaging - -```bash -vsce package -``` - -Creates `.vsix` file for manual installation or marketplace publishing. \ No newline at end of file diff --git a/package.json b/package.json index 639a219..b1aede2 100644 --- a/package.json +++ b/package.json @@ -127,6 +127,16 @@ "enum": ["ERROR", "WARN", "INFO", "DEBUG"], "default": "INFO", "description": "Set the logging level for HumanAgent MCP server" + }, + "humanagent-mcp.notifications.enableSound": { + "type": "boolean", + "default": true, + "description": "Enable audio notifications when AI agents send messages" + }, + "humanagent-mcp.notifications.enableFlashing": { + "type": "boolean", + "default": true, + "description": "Enable visual flashing notifications when AI agents send messages" } } } diff --git a/response-debug.txt b/response-debug.txt index 6f3ff9a..20698cc 100644 --- a/response-debug.txt +++ b/response-debug.txt @@ -7,3 +7,42 @@ 2025-10-24T09:36:01.128Z - RESPONSE ENDPOINT CALLED - RequestID: 10-1761298555386 2025-10-24T09:36:37.205Z - RESPONSE ENDPOINT CALLED - RequestID: 11-1761298573778 2025-10-25T00:51:00.473Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761353445662 +2025-10-25T04:01:02.918Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761364822234 +2025-10-25T04:15:25.912Z - RESPONSE ENDPOINT CALLED - RequestID: 4-1761365673152 +2025-10-25T05:11:52.195Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761369085275 +2025-10-25T05:13:08.587Z - RESPONSE ENDPOINT CALLED - RequestID: 4-1761369125738 +2025-10-25T05:13:46.757Z - RESPONSE ENDPOINT CALLED - RequestID: 5-1761369196447 +2025-10-25T05:14:13.224Z - RESPONSE ENDPOINT CALLED - RequestID: 6-1761369242206 +2025-10-25T05:14:37.881Z - RESPONSE ENDPOINT CALLED - RequestID: 7-1761369262103 +2025-10-25T05:15:07.921Z - RESPONSE ENDPOINT CALLED - RequestID: 8-1761369292715 +2025-10-25T05:16:21.162Z - RESPONSE ENDPOINT CALLED - RequestID: 9-1761369320152 +2025-10-25T05:16:54.687Z - RESPONSE ENDPOINT CALLED - RequestID: 10-1761369392733 +2025-10-25T05:18:12.537Z - RESPONSE ENDPOINT CALLED - RequestID: 11-1761369434229 +2025-10-25T05:31:53.635Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761370255763 +2025-10-25T22:25:03.252Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761430956625 +2025-10-25T23:25:06.434Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761433618081 +2025-10-25T23:51:51.036Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761436271152 +2025-10-26T00:10:24.529Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761437390231 +2025-10-26T00:50:40.987Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761439764111 +2025-10-26T02:36:30.812Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761446137388 +2025-10-26T02:36:46.213Z - RESPONSE ENDPOINT CALLED - RequestID: 4-1761446194329 +2025-10-26T02:37:06.823Z - RESPONSE ENDPOINT CALLED - RequestID: 5-1761446210035 +2025-10-26T02:39:35.845Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761446268480 +2025-10-26T02:52:49.230Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761447129937 +2025-10-26T02:58:10.739Z - RESPONSE ENDPOINT CALLED - RequestID: 4-1761447173815 +2025-10-26T02:58:23.071Z - RESPONSE ENDPOINT CALLED - RequestID: 6-1761446231600 +2025-10-26T03:12:51.723Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761448352577 +2025-10-26T03:13:06.068Z - RESPONSE ENDPOINT CALLED - RequestID: 4-1761448377257 +2025-10-26T03:14:30.027Z - RESPONSE ENDPOINT CALLED - RequestID: 5-1761448389577 +2025-10-26T03:27:07.019Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761449187260 +2025-10-26T03:28:01.453Z - RESPONSE ENDPOINT CALLED - RequestID: 4-1761449230412 +2025-10-26T04:12:40.297Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761451913551 +2025-10-26T04:32:38.258Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761453136803 +2025-10-26T04:33:24.748Z - RESPONSE ENDPOINT CALLED - RequestID: 4-1761453160409 +2025-10-26T04:34:19.385Z - RESPONSE ENDPOINT CALLED - RequestID: 3-1761453244838 +2025-10-26T04:34:47.275Z - RESPONSE ENDPOINT CALLED - RequestID: 5-1761453207008 +2025-10-26T04:35:07.379Z - RESPONSE ENDPOINT CALLED - RequestID: 6-1761453290240 +2025-10-26T04:35:22.313Z - RESPONSE ENDPOINT CALLED - RequestID: 7-1761453309691 +2025-10-26T04:35:24.503Z - RESPONSE ENDPOINT CALLED - RequestID: 8-1761453324492 +2025-10-26T04:35:34.152Z - RESPONSE ENDPOINT CALLED - RequestID: 9-1761453327469 +2025-10-26T04:35:59.241Z - RESPONSE ENDPOINT CALLED - RequestID: 4-1761453262457 diff --git a/src/extension.ts b/src/extension.ts index 778e3d4..cd808ee 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -21,10 +21,11 @@ class HumanAgentMcpProvider implements vscode.McpServerDefinitionProvider { constructor(private sessionId: string) {} provideMcpServerDefinitions(token: vscode.CancellationToken): vscode.ProviderResult { - // Return our HumanAgent MCP server definition with current sessionId - const serverUrl = `http://127.0.0.1:3737/mcp?sessionId=${this.sessionId}`; + // Use separate endpoint for MCP tools to avoid SSE conflicts with webview + const serverUrl = `http://127.0.0.1:3737/mcp-tools?sessionId=${this.sessionId}`; const serverUri = vscode.Uri.parse(serverUrl); const server = new vscode.McpHttpServerDefinition('HumanAgent MCP', serverUri); + console.log('HumanAgent MCP: Using separate MCP tools endpoint to avoid SSE conflicts'); return [server]; } @@ -144,8 +145,8 @@ export async function activate(context: vscode.ExtensionContext) { serverManager = ServerManager.getInstance(serverOptions); - // Auto-detect and start standalone MCP server if already configured - await autoStartMcpServer(mcpConfigManager, workspaceSessionId); + // Auto-start server and register session (no mcp.json dependency) + await ensureServerAndRegisterSession(workspaceSessionId); // Restore the persisted session name after server is running (with retry) setTimeout(async () => { @@ -191,9 +192,6 @@ export async function activate(context: vscode.ExtensionContext) { // Create dedicated status command const showStatusCommand = vscode.commands.registerCommand('humanagent-mcp.showStatus', async () => { - const isWorkspaceRegistered = mcpConfigManager?.isMcpServerRegistered(false) ?? false; - const isGlobalRegistered = mcpConfigManager?.isMcpServerRegistered(true) ?? false; - // Get detailed server status const serverStatus = await serverManager.getServerStatus(); @@ -204,8 +202,7 @@ export async function activate(context: vscode.ExtensionContext) { `- Port: ${serverStatus.port}\n` + `- Host: ${serverStatus.host}\n` + `- Session: ${workspaceSessionId}\n` + - `- Workspace registration: ${isWorkspaceRegistered ? '✅' : '❌'}\n` + - `- Global registration: ${isGlobalRegistered ? '✅' : '❌'}` + `- Registration: Native Provider ✅` ); }); @@ -252,16 +249,9 @@ export async function activate(context: vscode.ExtensionContext) { }); const configureMcpCommand = vscode.commands.registerCommand('humanagent-mcp.configureMcp', async () => { - // Refresh state checks each time the command is executed - const hasWorkspace = mcpConfigManager?.hasWorkspace() ?? false; - const isWorkspaceRegistered = mcpConfigManager?.isMcpServerRegistered(false) ?? false; - const isGlobalRegistered = mcpConfigManager?.isMcpServerRegistered(true) ?? false; - - console.log(`HumanAgent MCP: Configure command - hasWorkspace: ${hasWorkspace}, workspaceRegistered: ${isWorkspaceRegistered}, globalRegistered: ${isGlobalRegistered}`); - const options = []; - // Server management options + // Server management options only (registration handled automatically by native provider) const serverStatus = await serverManager.getServerStatus(); if (serverStatus.isRunning) { options.push('🔴 Stop Server'); @@ -270,33 +260,10 @@ export async function activate(context: vscode.ExtensionContext) { options.push('▶️ Start Server'); } - if (hasWorkspace) { - if (isWorkspaceRegistered) { - options.push('🗑️ Unregister from This Workspace'); - console.log('HumanAgent MCP: Added workspace UNREGISTER option'); - } else { - options.push('📝 Register for This Workspace'); - console.log('HumanAgent MCP: Added workspace REGISTER option'); - } - } - - if (isGlobalRegistered) { - options.push('🗑️ Unregister Globally'); - console.log('HumanAgent MCP: Added global UNREGISTER option'); - } else { - options.push('🌐 Register Globally'); - console.log('HumanAgent MCP: Added global REGISTER option'); - } - - if (hasWorkspace) { - options.push('📄 Open Workspace Configuration'); - } options.push('📊 Show Status'); - - console.log(`HumanAgent MCP: Final options: ${options.join(', ')}`); const action = await vscode.window.showQuickPick(options, { - placeHolder: 'Choose MCP Server configuration action:' + placeHolder: 'Choose MCP Server action:' }); if (!action) { @@ -314,36 +281,12 @@ export async function activate(context: vscode.ExtensionContext) { case '🔄 Restart Server': await vscode.commands.executeCommand('humanagent-mcp.restartServer'); break; - case '📝 Register for This Workspace': - await mcpConfigManager!.ensureMcpServerRegistered(false, workspaceSessionId); - vscode.window.showInformationMessage('MCP server registered for this workspace! Restart VS Code to enable Copilot integration.'); - break; - case '🌐 Register Globally': - await mcpConfigManager!.ensureMcpServerRegistered(true, workspaceSessionId); - vscode.window.showInformationMessage('MCP server registered globally! Restart VS Code to enable Copilot integration.'); - break; - case '🗑️ Unregister from This Workspace': - await mcpConfigManager!.removeMcpServerRegistration(false); - vscode.window.showInformationMessage('MCP server unregistered from this workspace. Restart VS Code to apply changes.'); - break; - case '🗑️ Unregister Globally': - await mcpConfigManager!.removeMcpServerRegistration(true); - vscode.window.showInformationMessage('MCP server unregistered globally. Restart VS Code to apply changes.'); - break; - case '📄 Open Workspace Configuration': - const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; - if (workspaceRoot) { - const configPath = vscode.Uri.file(workspaceRoot + '/.vscode/mcp.json'); - vscode.commands.executeCommand('vscode.open', configPath); - } - break; case '📊 Show Status': - // Call the dedicated status command vscode.commands.executeCommand('humanagent-mcp.showStatus'); break; } } catch (error) { - vscode.window.showErrorMessage(`MCP configuration failed: ${error instanceof Error ? error.message : String(error)}`); + vscode.window.showErrorMessage(`Server action failed: ${error instanceof Error ? error.message : String(error)}`); } }); @@ -364,37 +307,38 @@ export async function activate(context: vscode.ExtensionContext) { //vscode.window.showInformationMessage('HumanAgent MCP extension activated successfully!'); } -// Auto-detect MCP server configuration and guide user if needed -async function autoStartMcpServer(configManager: McpConfigManager, sessionId: string): Promise { +// Simplified server startup and session registration (no mcp.json dependency) +async function ensureServerAndRegisterSession(sessionId: string): Promise { try { - // Check for workspace configuration first (higher priority) - if (configManager.isMcpServerRegistered(false)) { - console.log(`HumanAgent MCP: Found workspace configuration for session ${sessionId}, checking server status...`); - await ensureServerAccessibleAndRegister(sessionId, 'workspace'); - return; - } + console.log(`HumanAgent MCP: Starting server and registering session ${sessionId}...`); - // Check for global configuration - if (configManager.isMcpServerRegistered(true)) { - console.log(`HumanAgent MCP: Found global configuration for session ${sessionId}, checking server status...`); - await ensureServerAccessibleAndRegister(sessionId, 'global'); - return; - } - - // No configuration found - guide user to setup - console.log(`HumanAgent MCP: No MCP configuration found for session ${sessionId}`); - vscode.window.showInformationMessage( - 'HumanAgent MCP Server not configured. Use the Configure MCP command to set up the server.', - 'Configure Now' - ).then(selection => { - if (selection === 'Configure Now') { - vscode.commands.executeCommand('humanagent-mcp.configureMcp'); + // Check if server is accessible, if not start it + const serverAccessible = await isServerAccessible(); + if (!serverAccessible) { + console.log('HumanAgent MCP: Server not accessible, starting server...'); + const serverStarted = await serverManager.ensureServerRunning(); + if (!serverStarted) { + console.error('HumanAgent MCP: Failed to start server'); + vscode.window.showWarningMessage('HumanAgent MCP Server could not be started. Some features may not work.'); + return; } - }); + console.log('HumanAgent MCP: Server started successfully'); + } + + // Register session with the server + const sessionExists = await validateSessionWithServer(sessionId); + if (!sessionExists) { + console.log(`HumanAgent MCP: Session ${sessionId} not found on server, registering new session...`); + await registerSessionWithStandaloneServer(sessionId, false); + } else { + console.log(`HumanAgent MCP: Session ${sessionId} exists on server, re-registering with override data...`); + await registerSessionWithStandaloneServer(sessionId, true); + } + console.log(`HumanAgent MCP: Session registration complete for ${sessionId}`); } catch (error) { - console.error('HumanAgent MCP: Failed to check server configuration:', error); - vscode.window.showErrorMessage('Failed to check HumanAgent MCP Server configuration'); + console.error('HumanAgent MCP: Failed to start server or register session:', error); + vscode.window.showWarningMessage('HumanAgent MCP Server could not be initialized. Please check the server status and try reloading the workspace.'); } } @@ -414,7 +358,7 @@ async function isPortInUse(port: number): Promise { }); } -// Check if MCP server is accessible and responding +// Check if MCP server is accessible and responding with retry async function isServerAccessible(): Promise { try { const response = await fetch('http://127.0.0.1:3737/sessions', { @@ -423,12 +367,30 @@ async function isServerAccessible(): Promise { }); return response.ok; } catch (error) { - console.log('HumanAgent MCP: Server accessibility check failed:', error); + console.log('HumanAgent MCP: Server accessibility check failed, retrying in 3 seconds...', error); + + // Wait 3 seconds and try once more + await new Promise(resolve => setTimeout(resolve, 3000)); + + try { + const retryResponse = await fetch('http://127.0.0.1:3737/sessions', { + method: 'GET', + signal: AbortSignal.timeout(5000) + }); + + if (retryResponse.ok) { + console.log('HumanAgent MCP: Server accessible on retry'); + return true; + } + } catch (retryError) { + console.log('HumanAgent MCP: Server accessibility retry failed:', retryError); + } + return false; } } -// Check if session exists on server by testing a simple MCP call +// Check if session exists on server by testing a simple MCP call with retry async function validateSessionWithServer(sessionId: string): Promise { try { const response = await fetch('http://127.0.0.1:3737/mcp', { @@ -449,49 +411,100 @@ async function validateSessionWithServer(sessionId: string): Promise { return false; } } catch (error) { - console.log(`HumanAgent MCP: Session ${sessionId} validation failed:`, error); - return false; + console.log(`HumanAgent MCP: Session ${sessionId} validation failed, retrying in 3 seconds...`, error); + + // Wait 3 seconds and try once more + await new Promise(resolve => setTimeout(resolve, 3000)); + + try { + const retryResponse = await fetch('http://127.0.0.1:3737/mcp', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + sessionId, + method: 'tools/list' + }) + }); + + if (retryResponse.ok) { + const result = await retryResponse.json() as any; + console.log(`HumanAgent MCP: Session ${sessionId} validated on server (retry)`); + return true; + } else { + console.log(`HumanAgent MCP: Session ${sessionId} not found on server (${retryResponse.status}) (retry)`); + return false; + } + } catch (retryError) { + console.log(`HumanAgent MCP: Session ${sessionId} validation retry failed:`, retryError); + return false; + } } } -// Register session with standalone server via HTTP (always sends override data) +// Register session with standalone server via HTTP (always sends override data) with retry async function registerSessionWithStandaloneServer(sessionId: string, forceReregister: boolean = false): Promise { - try { - // Read workspace override file if it exists - let overrideData = null; - const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; - if (workspaceRoot) { - const overrideFilePath = path.join(workspaceRoot, '.vscode', 'HumanAgentOverride.json'); - try { - const fs = require('fs'); - if (fs.existsSync(overrideFilePath)) { - const overrideContent = fs.readFileSync(overrideFilePath, 'utf8'); - overrideData = JSON.parse(overrideContent); - console.log(`HumanAgent MCP: Loaded override data for session ${sessionId}`); - } - } catch (error) { - console.error(`HumanAgent MCP: Error reading override file:`, error); + // Read workspace override file if it exists + let overrideData = null; + const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; + if (workspaceRoot) { + const overrideFilePath = path.join(workspaceRoot, '.vscode', 'HumanAgentOverride.json'); + try { + const fs = require('fs'); + if (fs.existsSync(overrideFilePath)) { + const overrideContent = fs.readFileSync(overrideFilePath, 'utf8'); + overrideData = JSON.parse(overrideContent); + console.log(`HumanAgent MCP: Loaded override data for session ${sessionId}`); } + } catch (error) { + console.error(`HumanAgent MCP: Error reading override file:`, error); } - + } + + const requestBody = { + sessionId, + overrideData: overrideData, + forceReregister: forceReregister + }; + + try { const response = await fetch('http://127.0.0.1:3737/sessions/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - sessionId, - overrideData: overrideData, - forceReregister: forceReregister - }) + body: JSON.stringify(requestBody) }); if (response.ok) { const result = await response.json() as any; console.log(`HumanAgent MCP: Session ${sessionId} registered successfully. Total sessions: ${result.totalSessions}`); + return; } else { console.error(`HumanAgent MCP: Failed to register session ${sessionId}: ${response.status}`); } } catch (error) { - console.error(`HumanAgent MCP: Error registering session ${sessionId}:`, error); + console.error(`HumanAgent MCP: Error registering session ${sessionId}, retrying in 3 seconds...`, error); + + // Wait 3 seconds and try once more + await new Promise(resolve => setTimeout(resolve, 3000)); + + try { + const retryResponse = await fetch('http://127.0.0.1:3737/sessions/register', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(requestBody) + }); + + if (retryResponse.ok) { + const result = await retryResponse.json() as any; + console.log(`HumanAgent MCP: Session ${sessionId} registered successfully on retry. Total sessions: ${result.totalSessions}`); + return; + } else { + console.error(`HumanAgent MCP: Failed to register session ${sessionId} on retry: ${retryResponse.status}`); + throw new Error(`Registration failed: ${retryResponse.status}`); + } + } catch (retryError) { + console.error(`HumanAgent MCP: Session registration retry failed:`, retryError); + throw new Error(`Registration failed after retry: ${retryError}`); + } } } diff --git a/src/mcp/mcpConfigManager.ts b/src/mcp/mcpConfigManager.ts index 9d43d1b..f7e7c19 100644 --- a/src/mcp/mcpConfigManager.ts +++ b/src/mcp/mcpConfigManager.ts @@ -68,15 +68,10 @@ export class McpConfigManager { // Use the extension path passed during construction - // Configure our MCP server (HTTP transport) - const mcpUrl = sessionId ? `http://127.0.0.1:3737/mcp?sessionId=${sessionId}` : 'http://127.0.0.1:3737/mcp'; + // Configure our MCP server (HTTP transport) - no sessionId in URL const serverConfig: any = { type: 'http', - url: mcpUrl, - notifications: { - enableSound: true, - enableFlashing: true - } + url: 'http://127.0.0.1:3737/mcp' }; // Add our server to the config @@ -100,15 +95,10 @@ export class McpConfigManager { try { // Use the extension path passed during construction - // Configure our MCP server (HTTP transport) - const mcpUrl = sessionId ? `http://127.0.0.1:3737/mcp?sessionId=${sessionId}` : 'http://127.0.0.1:3737/mcp'; + // Configure our MCP server (HTTP transport) - no sessionId in URL const serverConfig: any = { type: 'http', - url: mcpUrl, - notifications: { - enableSound: true, - enableFlashing: true - } + url: 'http://127.0.0.1:3737/mcp' }; // Get current global MCP servers configuration diff --git a/src/mcp/server.ts b/src/mcp/server.ts index d641979..e025191 100644 --- a/src/mcp/server.ts +++ b/src/mcp/server.ts @@ -17,8 +17,8 @@ class DebugLogger { constructor(workspaceRoot?: string) { // Check environment variables for logging configuration - this.loggingEnabled = process.env.HUMANAGENT_LOGGING_ENABLED === 'true'; - this.loggingLevel = process.env.HUMANAGENT_LOGGING_LEVEL || 'INFO'; + this.loggingEnabled = process.env.HUMANAGENT_LOGGING_ENABLED === 'true' || true; // Enable by default for debugging + this.loggingLevel = process.env.HUMANAGENT_LOGGING_LEVEL || 'DEBUG'; // Debug level by default // If logging is disabled, just log to console for important messages if (!this.loggingEnabled) { @@ -27,20 +27,9 @@ class DebugLogger { } try { - // Determine log path based on workspace or fallback to temp directory - if (workspaceRoot) { - const vscodeDir = path.join(workspaceRoot, '.vscode'); - this.logPath = path.join(vscodeDir, 'HumanAgent-server.log'); - - // Ensure .vscode directory exists - if (!fs.existsSync(vscodeDir)) { - fs.mkdirSync(vscodeDir, { recursive: true }); - } - } else { - // Fallback for standalone server or when no workspace available - const tempDir = os.tmpdir(); - this.logPath = path.join(tempDir, 'HumanAgent-server.log'); - } + // Always log to system temp directory - server is workspace-independent + const tempDir = os.tmpdir(); + this.logPath = path.join(tempDir, 'HumanAgent-server.log'); console.log(`[LOGGER] Attempting to create log file at: ${this.logPath}`); @@ -134,9 +123,9 @@ export class McpServer extends EventEmitter { private requestResolvers: Map void; reject: (error: Error) => void }> = new Map(); private activeSessions: Set = new Set(); private sseConnections: Set = new Set(); - private conversationToSession: Map = new Map(); // Map VS Code conversation IDs to registered session IDs private chatManager: ChatManager; // Centralized chat and session management - private sseClients: Map = new Map(); // Per-session SSE connections + private sseClients: Map = new Map(); // Per-session SSE connections (VS Code webviews) + private webInterfaceConnections: Set = new Set(); // Web interface connections (all browsers) constructor(private sessionId?: string, private workspacePath?: string) { super(); @@ -169,32 +158,62 @@ export class McpServer extends EventEmitter { private setupEventForwarding(): void { this.on('request-state-change', (data) => { - this.debugLogger.log('SSE', 'Forwarding request-state-change to SSE connections'); - this.broadcastToSSE('request-state-change', data); + this.debugLogger.log('SSE', 'Forwarding request-state-change to target session and web interface'); + this.sendToSessionAndWeb(data.sessionId, 'request-state-change', data); }); } - private broadcastToSSE(eventType: string, data: any): void { + // Send event to web interface connections only + private sendToWebInterface(eventType: string, data: any): void { const message = JSON.stringify({ type: eventType, data }); const eventData = `data: ${message}\n\n`; - this.debugLogger.log('SSE', `Broadcasting to ${this.sseConnections.size} SSE connections:`, message); + this.debugLogger.log('SSE', `Sending to ${this.webInterfaceConnections.size} web interface connections:`, message); - // Send to all active SSE connections - for (const connection of this.sseConnections) { + for (const connection of this.webInterfaceConnections) { if (!connection.destroyed) { try { connection.write(eventData); } catch (error) { - this.debugLogger.log('SSE', 'Failed to write to SSE connection:', error); + this.debugLogger.log('SSE', 'Failed to write to web interface connection:', error); + this.webInterfaceConnections.delete(connection); this.sseConnections.delete(connection); } } else { + this.webInterfaceConnections.delete(connection); this.sseConnections.delete(connection); } } } + // Send event to specific session only + private sendToSession(sessionId: string, eventType: string, data: any): void { + const message = { type: eventType, data }; + + const sessionConnection = this.sseClients.get(sessionId); + if (!sessionConnection) { + this.debugLogger.log('WARN', `❌ No SSE connection found for session ${sessionId}`); + return; + } + + // Debug: Compare connection objects to see if they match the heartbeat connection + this.debugLogger.log('SSE', `🔍 Sending to session ${sessionId} - Connection destroyed: ${sessionConnection.destroyed}, writable: ${sessionConnection.writable}`); + + // Use the enhanced sendSSEMessage method with health checking + this.sendSSEMessage(sessionConnection, message); + this.debugLogger.log('SSE', `Sent to session ${sessionId}:`, JSON.stringify(message)); + } + + // Send event to specific session AND web interface + private sendToSessionAndWeb(sessionId: string, eventType: string, data: any): void { + // Send to specific session + this.sendToSession(sessionId, eventType, data); + // Also send to web interface + this.sendToWebInterface(eventType, data); + } + + + private sendMcpNotification(method: string, params?: any, sessionId?: string): void { this.debugLogger.log('MCP', `Sending SSE notification: ${method}`, params); @@ -229,11 +248,27 @@ export class McpServer extends EventEmitter { private sendSSEMessage(response: http.ServerResponse, message: any): void { try { + // Check connection health before sending + if (response.destroyed) { + this.debugLogger.log('ERROR', `Cannot send SSE message: connection is destroyed`); + return; + } + + if (!response.writable) { + this.debugLogger.log('ERROR', `Cannot send SSE message: connection is not writable`); + return; + } + const data = JSON.stringify(message); - response.write(`data: ${data}\n\n`); - this.debugLogger.log('SSE', `Sent SSE message: ${message.method || 'response'}`); + const success = response.write(`data: ${data}\n\n`); + + if (success) { + this.debugLogger.log('SSE', `✅ Successfully sent SSE message: ${message.type || message.method || 'response'}`); + } else { + this.debugLogger.log('ERROR', `❌ Failed to write SSE message (buffer full): ${message.type || message.method || 'response'}`); + } } catch (error) { - this.debugLogger.log('ERROR', `Failed to send SSE message:`, error); + this.debugLogger.log('ERROR', `❌ Exception sending SSE message:`, error); } } @@ -257,10 +292,7 @@ export class McpServer extends EventEmitter { type: 'string', description: 'Optional context or background information for the human agent' }, - sessionId: { - type: 'string', - description: 'Optional specific session ID to use. If not provided, a new session will be created.' - }, + priority: { type: 'string', enum: ['low', 'normal', 'high', 'urgent'], @@ -512,7 +544,11 @@ export class McpServer extends EventEmitter { const reqUrl = new URL(req.url!, `http://${req.headers.host}`); if (reqUrl.pathname === '/mcp') { - // Main MCP protocol endpoint + // Main MCP protocol endpoint (webview SSE) + } else if (reqUrl.pathname === '/mcp-tools') { + // MCP tools endpoint (extension only, no SSE conflicts) + await this.handleMcpToolsEndpoint(req, res, reqUrl); + return; } else if (req.url === '/HumanAgent') { // Web interface for multi-session chat await this.handleWebInterface(req, res); @@ -626,22 +662,31 @@ export class McpServer extends EventEmitter { this.debugLogger.log('SSE', 'Headers:', req.headers); this.debugLogger.log('SSE', 'URL:', req.url); - // Extract sessionId from query params in URL or Mcp-Session-Id header + // Extract sessionId and clientType from query params in URL or headers const url = new URL(req.url!, `http://${req.headers.host}`); let sessionId = url.searchParams.get('sessionId'); + const clientType = url.searchParams.get('clientType'); // If not in URL, try the Mcp-Session-Id header (per MCP spec) if (!sessionId) { sessionId = req.headers['mcp-session-id'] as string; } - if (!sessionId) { - this.debugLogger.log('SSE', 'No sessionId in SSE request (tried URL param and Mcp-Session-Id header)'); + // Validate connection parameters + if (!sessionId && clientType !== 'web') { + this.debugLogger.log('ERROR', 'SSE connection rejected: sessionId required for VS Code connections, or use clientType=web for web interface'); this.debugLogger.log('SSE', `Request headers: ${JSON.stringify(req.headers)}`); this.debugLogger.log('SSE', `Request URL: ${req.url}`); - // For now, let's allow connection without sessionId and use a default - sessionId = 'default-sse-session'; - this.debugLogger.log('SSE', `Using default sessionId: ${sessionId}`); + res.statusCode = 400; + res.setHeader('Content-Type', 'application/json'); + res.end(JSON.stringify({ error: 'sessionId required for VS Code connections, or use clientType=web for web interface' })); + return; + } + + // For web interface connections, use a placeholder sessionId for logging + if (clientType === 'web') { + sessionId = 'web-interface'; + this.debugLogger.log('SSE', 'Web interface SSE connection detected via clientType=web'); } // Set up Server-Sent Events (SSE) stream @@ -657,11 +702,21 @@ export class McpServer extends EventEmitter { this.debugLogger.log('SSE', `SSE headers set for session ${sessionId}, adding to connections...`); - // Add this connection to our session-based SSE connections - this.sseClients.set(sessionId, res); - this.sseConnections.add(res); // Keep old connections for cleanup - this.debugLogger.log('HTTP', `Added SSE connection for session ${sessionId}. Total connections: ${this.sseConnections.size}`); - this.debugLogger.log('SSE', `SSE connection added for session ${sessionId}. Total: ${this.sseConnections.size}`); + // Detect connection type: web interface via clientType=web, VS Code via sessionId + const isWebInterface = clientType === 'web'; + const isVSCodeWebview = !isWebInterface && sessionId !== 'web-interface'; + + if (isWebInterface) { + // Web interface connection - add to web interface connections + this.webInterfaceConnections.add(res); + this.sseConnections.add(res); // Keep old connections for cleanup + this.debugLogger.log('SSE', `Added web interface SSE connection. Total web connections: ${this.webInterfaceConnections.size}`); + } else { + // VS Code webview connection - add to session-specific connections + this.sseClients.set(sessionId!, res); + this.sseConnections.add(res); // Keep old connections for cleanup + this.debugLogger.log('SSE', `Added VS Code SSE connection for session ${sessionId}. Total session connections: ${this.sseClients.size}`); + } // Send initial connection acknowledgment const initialMessage = 'data: {"type":"connection","status":"established","sessionId":"' + sessionId + '"}\n\n'; @@ -676,15 +731,22 @@ export class McpServer extends EventEmitter { clearInterval(heartbeat); this.sseConnections.delete(res); } - }, 30000); // Send heartbeat every 30 seconds + }, 10000); // Send heartbeat every 10 seconds // Handle client disconnect const cleanup = () => { this.debugLogger.log('HTTP', `SSE connection closed for session ${sessionId}`); clearInterval(heartbeat); this.sseConnections.delete(res); - this.sseClients.delete(sessionId); - this.debugLogger.log('HTTP', `Removed SSE connection for session ${sessionId}. Total connections: ${this.sseConnections.size}`); + + // Remove from appropriate connection type + if (isWebInterface) { + this.webInterfaceConnections.delete(res); + this.debugLogger.log('HTTP', `Removed web interface SSE connection. Total web connections: ${this.webInterfaceConnections.size}`); + } else { + this.sseClients.delete(sessionId); + this.debugLogger.log('HTTP', `Removed VS Code SSE connection for session ${sessionId}. Total session connections: ${this.sseClients.size}`); + } }; req.on('close', cleanup); @@ -698,6 +760,33 @@ export class McpServer extends EventEmitter { res.end('Method Not Allowed'); } + private async handleMcpToolsEndpoint(req: http.IncomingMessage, res: http.ServerResponse, reqUrl: URL): Promise { + // MCP tools endpoint - handles MCP protocol for VS Code extension without SSE conflicts + this.debugLogger.log('HTTP', `MCP Tools: ${req.method} ${req.url}`); + + // Extract sessionId from query params + const sessionId = reqUrl.searchParams.get('sessionId'); + if (!sessionId) { + this.debugLogger.log('ERROR', 'MCP Tools: sessionId required'); + res.statusCode = 400; + res.end(JSON.stringify({ error: 'sessionId required' })); + return; + } + + if (req.method === 'POST') { + // Handle MCP protocol messages (initialize, tools/list, tools/call) + await this.handleHttpPost(req, res); + } else if (req.method === 'GET') { + // Reject GET requests to prevent SSE conflicts - tools only via POST + this.debugLogger.log('WARN', 'MCP Tools: GET requests not allowed (use /mcp for SSE)'); + res.statusCode = 405; + res.end(JSON.stringify({ error: 'GET not allowed on /mcp-tools - use /mcp for SSE' })); + } else { + res.statusCode = 405; + res.end('Method Not Allowed'); + } + } + private async handleSessionEndpoint(req: http.IncomingMessage, res: http.ServerResponse): Promise { const url = new URL(req.url || '', `http://localhost:${this.port}`); @@ -769,9 +858,9 @@ export class McpServer extends EventEmitter { this.sessionNames.set(sessionId, name); this.debugLogger.log('INFO', `Session ${sessionId} named: "${name}"`); - // Broadcast name change via SSE to all connected clients - this.broadcastToSSE('session-name-changed', { sessionId, name }); - this.debugLogger.log('SSE', 'Broadcasting session name change to all clients'); + // Send name change to target session and web interface + this.sendToSessionAndWeb(sessionId, 'session-name-changed', { sessionId, name }); + this.debugLogger.log('SSE', 'Sent session name change to target session and web interface'); res.statusCode = 200; res.setHeader('Content-Type', 'application/json'); @@ -1417,6 +1506,95 @@ export class McpServer extends EventEmitter { } } + function addSessionTab(sessionId) { + // Check if tab already exists + const existingTab = document.querySelector(\`[data-session="\${sessionId}"].tab\`); + if (existingTab) { + console.log(\`Tab for session \${sessionId} already exists\`); + return; + } + + const tabsContainer = document.getElementById('tabs'); + const contentDiv = document.querySelector('.content'); + + if (!tabsContainer || !contentDiv) { + console.error('Could not find tabs container or content div'); + return; + } + + // Create new tab + const tabElement = document.createElement('div'); + tabElement.className = 'tab'; + tabElement.setAttribute('data-session', sessionId); + tabElement.textContent = \`Session: \${sessionId.substring(0, 8)}\`; + tabElement.onclick = () => switchToSession(sessionId); + + // Add tab to container + tabsContainer.appendChild(tabElement); + + // Create new chat container + const chatContainer = document.createElement('div'); + chatContainer.className = 'chat-container'; + chatContainer.setAttribute('data-session', sessionId); + chatContainer.innerHTML = \` +
+ +
+
+ + +
+ \`; + + // Add chat container to content + contentDiv.appendChild(chatContainer); + + // Set up event listeners for new input elements + const textarea = chatContainer.querySelector('textarea'); + const button = chatContainer.querySelector('button'); + + if (textarea) { + textarea.addEventListener('keypress', function(e) { + if (e.key === 'Enter' && !e.shiftKey) { + e.preventDefault(); + sendResponse(sessionId); + } + }); + } + + if (button) { + button.addEventListener('click', () => sendResponse(sessionId)); + } + + console.log(\`Added new session tab: \${sessionId}\`); + } + + function removeSessionTab(sessionId) { + // Remove tab + const tabElement = document.querySelector(\`[data-session="\${sessionId}"].tab\`); + if (tabElement) { + tabElement.remove(); + } + + // Remove chat container + const chatContainer = document.querySelector(\`[data-session="\${sessionId}"].chat-container\`); + if (chatContainer) { + chatContainer.remove(); + } + + // If this was the active session, switch to first available + const remainingTabs = document.querySelectorAll('.tab'); + if (remainingTabs.length > 0) { + const firstTab = remainingTabs[0]; + const firstSessionId = firstTab.getAttribute('data-session'); + if (firstSessionId) { + switchToSession(firstSessionId); + } + } + + console.log(\`Removed session tab: \${sessionId}\`); + } + // Load existing messages for all sessions async function loadExistingMessages() { const sessions = ['${sessions.map(s => s.id).join("', '")}']; @@ -1478,7 +1656,7 @@ export class McpServer extends EventEmitter { // WebSocket connection for real-time updates function setupRealtimeUpdates() { console.log('Setting up SSE connection to /mcp...'); - const eventSource = new EventSource('/mcp'); + const eventSource = new EventSource('/mcp?clientType=web'); eventSource.onopen = function(event) { console.log('SSE connection opened successfully:', event); @@ -1548,6 +1726,14 @@ export class McpServer extends EventEmitter { } else if (data.type === 'session_update') { // Refresh the page to show new sessions window.location.reload(); + } else if (data.type === 'session-registered' && data.data) { + // Add new session tab dynamically + console.log('New session registered:', data.data); + addSessionTab(data.data.sessionId); + } else if (data.type === 'session-unregistered' && data.data) { + // Remove session tab dynamically + console.log('Session unregistered:', data.data); + removeSessionTab(data.data.sessionId); } else if (data.type === 'session-name-changed' && data.data) { // Handle session name changes console.log('Session name changed:', data.data); @@ -1646,11 +1832,10 @@ export class McpServer extends EventEmitter { private async handleToolCall(message: McpMessage): Promise { const { name, arguments: args } = message.params; - // Extract session ID from _meta.vscode.conversationId (VS Code) or fallback to args.sessionId (web) - const rawSessionId = message.params._meta?.['vscode.conversationId'] || args?.sessionId; - const sessionId = this.mapToRegisteredSession(rawSessionId); + // Use actual session ID from MCP message context, not tool argument + const sessionId = message.params.sessionId; - this.debugLogger.log('MCP', `Tool call - name: "${name}", raw session: ${rawSessionId}, mapped session: ${sessionId}`, { name, args }); + this.debugLogger.log('MCP', `Tool call - name: "${name}", sessionId: ${sessionId}`, { name, args }); // Check session-specific tools first, then default tools const sessionTools = sessionId ? this.sessionTools.get(sessionId) : null; @@ -1676,6 +1861,21 @@ export class McpServer extends EventEmitter { private async handleHumanAgentChatTool(messageId: string, params: HumanAgentChatToolParams, sessionId?: string, toolName?: string): Promise { this.debugLogger.log('TOOL', 'HumanAgent_Chat called with params:', params); + + // Require valid session ID - no default fallback allowed + const actualSessionId = sessionId || params.sessionId; + if (!actualSessionId) { + this.debugLogger.log('ERROR', 'HumanAgent_Chat tool called without session ID - rejecting'); + return { + id: messageId, + type: 'response', + error: { + code: -32602, + message: 'Invalid parameters: sessionId is required for HumanAgent_Chat tool' + } + }; + } + const startTime = Date.now(); const timeoutMs = params.timeout ? params.timeout * 1000 : null; // Convert to milliseconds or null for no timeout this.debugLogger.log('TOOL', `Using timeout: ${timeoutMs ? `${timeoutMs}ms (${timeoutMs/1000}s)` : 'no timeout (wait indefinitely)'}`); @@ -1711,9 +1911,8 @@ export class McpServer extends EventEmitter { }, timeoutMs); } - // Store the pending request using the extracted session ID - const sessionToUse = sessionId || params.sessionId || 'default'; - this.debugLogger.log('TOOL', `Adding pending request ${requestId} to session: ${sessionToUse}`); + // Use the validated session ID + this.debugLogger.log('TOOL', `Adding pending request ${requestId} to session: ${actualSessionId}`); // Store the AI's message (this IS the AI communication - it talks by calling the tool) const aiMessage: ChatMessage = { @@ -1723,21 +1922,21 @@ export class McpServer extends EventEmitter { timestamp: new Date(), type: 'text' }; - this.chatManager.addMessage(sessionToUse, aiMessage); - this.debugLogger.log('CHAT', `Stored AI message in ChatManager for session ${sessionToUse}: ${aiMessage.content.substring(0, 50)}...`); - this.broadcastMessageToClients(sessionToUse, aiMessage); + this.chatManager.addMessage(actualSessionId, aiMessage); + this.debugLogger.log('CHAT', `Stored AI message in ChatManager for session ${actualSessionId}: ${aiMessage.content.substring(0, 50)}...`); + this.broadcastMessageToClients(actualSessionId, aiMessage); // Emit request state to enable input controls and show waiting indicator this.emit('request-state-change', { requestId, - sessionId: sessionToUse, + sessionId: actualSessionId, state: 'waiting_for_response', message: params.message, context: params.context, timestamp: new Date().toISOString() }); - this.chatManager.addPendingRequest(sessionToUse, requestId, { ...params, toolName: toolName || 'HumanAgent_Chat' }); + this.chatManager.addPendingRequest(actualSessionId, requestId, { ...params, toolName: toolName || 'HumanAgent_Chat' }); this.requestResolvers.set(requestId, { resolve: (response: string) => { if (timeoutHandle) { clearTimeout(timeoutHandle); } @@ -1747,7 +1946,7 @@ export class McpServer extends EventEmitter { // Emit request completed state to disable input controls and hide waiting indicator this.emit('request-state-change', { requestId, - sessionId: sessionToUse, + sessionId: actualSessionId, state: 'completed', response: response, timestamp: new Date().toISOString() @@ -1872,38 +2071,12 @@ export class McpServer extends EventEmitter { } this.debugLogger.log('INFO', `Session registered: ${sessionId} (${this.activeSessions.size} total sessions)`); + + // Send session registration to web interface only (for web UI tab creation) + this.sendToWebInterface('session-registered', { sessionId, totalSessions: this.activeSessions.size }); } - private mapToRegisteredSession(conversationId?: string): string | undefined { - if (!conversationId) { - return undefined; - } - // Check if it's already a registered session ID - if (this.activeSessions.has(conversationId)) { - return conversationId; - } - - // Check if it's a conversation ID we've seen before - const mappedSession = this.conversationToSession.get(conversationId); - if (mappedSession && this.activeSessions.has(mappedSession)) { - this.debugLogger.log('MCP', `Mapped conversation ${conversationId} to session ${mappedSession}`); - return mappedSession; - } - - // If not found, try to map to the first available registered session - // This handles the case where VS Code conversation ID needs to be linked to a web-registered session - const activeSessions = Array.from(this.activeSessions); - if (activeSessions.length > 0) { - const targetSession = activeSessions[0]; // Use first available session - this.conversationToSession.set(conversationId, targetSession); - this.debugLogger.log('MCP', `Auto-mapped conversation ${conversationId} to session ${targetSession}`); - return targetSession; - } - - this.debugLogger.log('MCP', `No registered session found for conversation ${conversationId}`); - return undefined; - } unregisterSession(sessionId: string): void { this.activeSessions.delete(sessionId); @@ -1912,6 +2085,9 @@ export class McpServer extends EventEmitter { this.sessionWorkspacePaths.delete(sessionId); this.sessionMessageSettings.delete(sessionId); this.debugLogger.log('INFO', `Session unregistered and cleaned up: ${sessionId} (${this.activeSessions.size} total sessions)`); + + // Send session unregistration to web interface only (for web UI tab removal) + this.sendToWebInterface('session-unregistered', { sessionId, totalSessions: this.activeSessions.size }); } getActiveSessions(): string[] { @@ -1975,7 +2151,7 @@ export class McpServer extends EventEmitter { // Removed: storeMessage and getSessionMessages wrapper methods - call ChatManager directly private broadcastMessageToClients(sessionId: string, message: ChatMessage): void { - // Broadcast message to all connected SSE clients + // Send message to specific session AND all web interface connections const messageEvent = { type: 'chat_message', sessionId: sessionId, @@ -1990,15 +2166,32 @@ export class McpServer extends EventEmitter { const sseData = `data: ${JSON.stringify(messageEvent)}\n\n`; - // Send to all connected SSE clients (VS Code webviews and web interfaces) - for (const connection of this.sseConnections) { + // Send to the specific session's SSE connection (VS Code webview) + const sessionConnection = this.sseClients.get(sessionId); + if (sessionConnection) { try { - connection.write(sseData); - this.debugLogger.log('CHAT', `Broadcasted message to SSE client for session ${sessionId}`); + sessionConnection.write(sseData); + this.debugLogger.log('CHAT', `Sent message to VS Code session ${sessionId}`); } catch (error) { - this.debugLogger.log('ERROR', 'Failed to broadcast message to SSE client:', error); + this.debugLogger.log('ERROR', `Failed to send message to VS Code session ${sessionId}:`, error); // Remove failed connection - this.sseConnections.delete(connection); + this.sseClients.delete(sessionId); + this.sseConnections.delete(sessionConnection); + } + } else { + this.debugLogger.log('WARN', `No VS Code SSE connection found for session ${sessionId}`); + } + + // Also send to all web interface connections + for (const webConnection of this.webInterfaceConnections) { + try { + webConnection.write(sseData); + this.debugLogger.log('CHAT', `Sent message to web interface for session ${sessionId}`); + } catch (error) { + this.debugLogger.log('ERROR', `Failed to send message to web interface:`, error); + // Remove failed connection + this.webInterfaceConnections.delete(webConnection); + this.sseConnections.delete(webConnection); } } } diff --git a/src/webview/chatWebviewProvider.ts b/src/webview/chatWebviewProvider.ts index 3a29664..dd87a45 100644 --- a/src/webview/chatWebviewProvider.ts +++ b/src/webview/chatWebviewProvider.ts @@ -51,23 +51,12 @@ export class ChatWebviewProvider implements vscode.WebviewViewProvider { private loadNotificationSettings() { try { - // Try to load settings from mcp.json - const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; - if (workspaceRoot) { - const mcpConfigPath = `${workspaceRoot}/.vscode/mcp.json`; - const fs = require('fs'); - if (fs.existsSync(mcpConfigPath)) { - const mcpConfig = JSON.parse(fs.readFileSync(mcpConfigPath, 'utf8')); - // Check if humanagent-mcp server has notifications settings - if (mcpConfig.servers && mcpConfig.servers['humanagent-mcp'] && mcpConfig.servers['humanagent-mcp'].notifications) { - const notifications = mcpConfig.servers['humanagent-mcp'].notifications; - this.notificationSettings = { - enableSound: notifications.enableSound ?? true, - enableFlashing: notifications.enableFlashing ?? true - }; - } - } - } + // Load settings from VS Code configuration + const config = vscode.workspace.getConfiguration('humanagent-mcp'); + this.notificationSettings = { + enableSound: config.get('notifications.enableSound', true), + enableFlashing: config.get('notifications.enableFlashing', true) + }; } catch (error) { console.error('ChatWebviewProvider: Error loading notification settings:', error); // Use defaults on error @@ -248,18 +237,14 @@ export class ChatWebviewProvider implements vscode.WebviewViewProvider { return; } - const isRegisteredWorkspace = this.mcpConfigManager?.isMcpServerRegistered(false) ?? false; - const isRegisteredGlobal = this.mcpConfigManager?.isMcpServerRegistered(true) ?? false; - const configType = isRegisteredWorkspace ? 'workspace' : (isRegisteredGlobal ? 'global' : 'none'); - this._view.webview.postMessage({ type: 'serverStatus', data: { running: true, // Assume standalone server is running if configured tools: 1, // Default tool count pendingRequests: 0, // Can't get from standalone server easily - registered: isRegisteredWorkspace || isRegisteredGlobal, - configType: configType + registered: true, // Always true with native provider + configType: 'native' // Native provider registration } }); } @@ -488,11 +473,9 @@ export class ChatWebviewProvider implements vscode.WebviewViewProvider { vscode.window.showInformationMessage('MCP Server management not available - using standalone server'); break; case 'register': - // Use the MCP configuration from the parent command - vscode.commands.executeCommand('humanagent-mcp.configureMcp'); - break; case 'unregister': - vscode.commands.executeCommand('humanagent-mcp.configureMcp'); + // Registration handled automatically by native provider + vscode.window.showInformationMessage('HumanAgent MCP registration is handled automatically by the native provider.'); break; case 'configure': vscode.commands.executeCommand('humanagent-mcp.configureMcp'); @@ -501,6 +484,10 @@ export class ChatWebviewProvider implements vscode.WebviewViewProvider { // Test notification sound by triggering a fake notification await this.displayHumanAgentMessage('🔊 Audio test - this is a test notification sound!', 'Testing audio notifications', 'test-audio'); break; + case 'requestServerStatus': + // Show the same notification popup as the main status command + vscode.commands.executeCommand('humanagent-mcp.showStatus'); + break; case 'overridePrompt': await this.createPromptOverrideFile(); break; @@ -850,7 +837,8 @@ export class ChatWebviewProvider implements vscode.WebviewViewProvider {