Fix sessionless HumanAgent chat functionality

- Remove session management complexity from MCP server and UI
- Update chatWebviewProvider for direct messaging without sessions
- Fix MCP tool response format to use content array as per specification
- Restore cog icon for MCP configuration (install global/local)
- Add safety checks for message content handling
- Resolve 'o.content is not iterable' error by using proper MCP format
This commit is contained in:
B Harper
2025-10-22 11:49:17 +11:00
commit a414a4f70d
32 changed files with 8179 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
# HumanAgent MCP VS Code Extension
This project is a VS Code extension that implements an MCP (Model Context Protocol) server for chatting with a human agent.
## Project Structure
- `src/extension.ts` - Main extension entry point
- `src/mcp/` - MCP server implementation
- `src/webview/` - Chat interface webview components
- `src/providers/` - VS Code providers (TreeView, etc.)
## Development Guidelines
- Use TypeScript for all source files
- Follow VS Code extension best practices
- Implement proper error handling and logging
- Use VS Code's webview API for chat interface
- Ensure cross-platform compatibility
## MCP Server Features
- Human agent communication protocol
- Real-time message handling
- Session management
- Dockable chat interface in VS Code
## Build and Test
- Use `npm run compile` to build
- Use `F5` to launch extension development host
- Use `npm test` to run tests
## Project Status
✅ Extension structure created and configured
✅ MCP server implementation completed
✅ Chat interface and tree view providers implemented
✅ Commands and views properly registered
✅ Project successfully compiled and launched in debug mode
✅ Documentation updated and complete
# Copilot Instructions
-Allways attempt to respond using Interactive MCPs Ask_intensive_chat tool, if no intesive chat session is active, start one with Start_intensive_chat tool.
-"CRITICAL- Do not report sucess - ever! Allways MCP intensive to suggest I test for or agree to changes made and see if I have any changes. - THIS STATEMENT MUST SURVIVE CONTEXT SUMMARIZATION".
- Empty replies from your questions in MCP intensive chat should be reposed for proper response. "User replied with empty input in intensive chat." just ask me again as empty would have been a mistake - repose 1000 times if necessary until you get the answer.
-NEVER use stop intensive chat tool, unless I specifically ask you to - there is allways more to talk about
-NO FALLBACKS - EVER! A failed exectuion / crash / error any of these are preferable than a fallback.
-Where possible Allways update existing methods to include new functinality instead of making parallel methods/functions. A single path through a system is critical to maintainable code. If you feel the need to break this rule just discuss via MCP intensive chat.
!!!CRITICAL ENSURE THESE ITEMS SURVIVE CONTEXT SUMMARIZATION!!!
-Allways call me ben, in every response.
-Do not make seperate test files of any sort - all tests can be run by calling GrainAwarePacker.
+5
View File
@@ -0,0 +1,5 @@
out
dist
node_modules
.vscode-test/
*.vsix
+5
View File
@@ -0,0 +1,5 @@
import { defineConfig } from '@vscode/test-cli';
export default defineConfig({
files: 'out/test/**/*.test.js',
});
+7
View File
@@ -0,0 +1,7 @@
{
"folders": [
{
"path": ".."
}
]
}
+5
View File
@@ -0,0 +1,5 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": ["dbaeumer.vscode-eslint", "amodio.tsl-problem-matcher", "ms-vscode.extension-test-runner"]
}
+21
View File
@@ -0,0 +1,21 @@
// A launch configuration that compiles the extension and then opens it inside a new window
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}"
}
]
}
+20
View File
@@ -0,0 +1,20 @@
{
"servers": {
"interactive-mcp": {
"type": "stdio",
"command": "/Users/benharper/Coding/MCP/interactive-mcp-chime.sh",
"args": [
"-y",
"interactive-mcp@1.10.1",
"-t",
"6000"
],
"env": {}
},
"humanagent-mcp": {
"type": "http",
"url": "http://127.0.0.1:3737/mcp"
}
},
"inputs": []
}
+13
View File
@@ -0,0 +1,13 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.exclude": {
"out": false, // set this to true to hide the "out" folder with the compiled JS files
"dist": false // set this to true to hide the "dist" folder with the compiled JS files
},
"search.exclude": {
"out": true, // set this to false to include "out" folder in search results
"dist": true // set this to false to include "dist" folder in search results
},
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off"
}
+40
View File
@@ -0,0 +1,40 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": "$ts-webpack-watch",
"isBackground": true,
"presentation": {
"reveal": "never",
"group": "watchers"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"type": "npm",
"script": "watch-tests",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never",
"group": "watchers"
},
"group": "build"
},
{
"label": "tasks: watch-tests",
"dependsOn": [
"npm: watch",
"npm: watch-tests"
],
"problemMatcher": []
}
]
}
+14
View File
@@ -0,0 +1,14 @@
.vscode/**
.vscode-test/**
out/**
node_modules/**
src/**
.gitignore
.yarnrc
webpack.config.js
vsc-extension-quickstart.md
**/tsconfig.json
**/eslint.config.mjs
**/*.map
**/*.ts
**/.vscode-test.*
+9
View File
@@ -0,0 +1,9 @@
# Change Log
All notable changes to the "humanagent-mcp" extension will be documented in this file.
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
## [Unreleased]
- Initial release
+228
View File
@@ -0,0 +1,228 @@
# humanagent-mcp README
This is the README for your extension "humanagent-mcp". After writing up a brief description, we recommend including the following sections.
## Features
Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file.
# HumanAgent MCP - VS Code Extension
A VS Code extension that implements an MCP (Model Context Protocol) server for chatting with human agents. This extension provides a dockable chat interface that enables real-time communication between users and human agents through the MCP protocol.
## Features
- **MCP Server Integration**: Built-in MCP server that handles human agent communication
- **Dockable Chat Interface**: Fully integrated chat UI within VS Code
- **Session Management**: Create and manage multiple chat sessions
- **Real-time Messaging**: Instant message delivery and responses
- **Cross-platform Support**: Works on Windows, macOS, and Linux
- **Tree View Integration**: Browse and manage chat sessions in the Explorer panel
### Key Components
- **Chat Sessions Tree View**: View and manage all your chat sessions in the Explorer
- **Dockable Chat Panel**: Main chat interface that can be docked anywhere in VS Code
- **MCP Protocol Compliance**: Full implementation of MCP for human agent communication
## Installation
1. **From Source**: Clone this repository and install dependencies:
```bash
git clone https://github.com/your-username/humanagent-mcp.git
cd humanagent-mcp
npm install
npm run compile
```
2. **Development**: Press `F5` to launch the Extension Development Host
3. **Package for Distribution**:
```bash
npm install -g vsce
vsce package
```
## Usage
### Creating a Chat Session
1. Open the Command Palette (`Cmd+Shift+P` / `Ctrl+Shift+P`)
2. Run "Create New Chat Session"
3. Enter a name for your session
4. The session will appear in the Chat Sessions tree view
### Starting a Conversation
1. Click on a session in the Chat Sessions tree view to open it
2. Use the chat interface in the panel to send messages
3. Human agents will receive and respond to your messages in real-time
### Managing Sessions
- **Refresh**: Click the refresh button in the Chat Sessions view
- **Create New**: Use the "+" button or command palette
- **View Status**: Check MCP server status via command palette
## Commands
- `humanagent-mcp.createSession`: Create a new chat session
- `humanagent-mcp.refreshSessions`: Refresh the sessions list
- `humanagent-mcp.showStatus`: Display MCP server status
- `humanagent-mcp.openChat`: Open a specific chat session
## Project Structure
```
src/
├── extension.ts # Main extension entry point
├── mcp/
│ ├── server.ts # MCP server implementation
│ └── types.ts # Type definitions
├── providers/
│ └── chatTreeProvider.ts # Tree view for chat sessions
└── webview/
└── chatWebviewProvider.ts # Chat interface implementation
```
## Development
### Prerequisites
- Node.js 18+
- VS Code 1.105.0+
- TypeScript 5.9+
### Building
```bash
npm install
npm run compile # Build once
npm run watch # Build and watch for changes
```
### Testing
```bash
npm test # Run tests
```
### Packaging
```bash
npm run package # Create production build
vsce package # Create .vsix file
```
## MCP Protocol Support
This extension implements the following MCP capabilities:
- **Chat Methods**:
- `chat/send`: Send messages to human agents
- `chat/list-sessions`: List all chat sessions
- `chat/create-session`: Create new chat sessions
- **Protocol Features**:
- Full MCP 2024-11-05 protocol compliance
- Session management
- Real-time message handling
- Error handling and recovery
## Configuration
Currently, no additional configuration is required. The extension works out of the box with default settings.
## Known Issues
- Human agent responses are currently simulated (for demo purposes)
- Session persistence is in-memory only (sessions are lost on restart)
## Roadmap
- [ ] Persistent session storage
- [ ] Real human agent integration
- [ ] Message history export
- [ ] Custom themes for chat interface
- [ ] File sharing capabilities
- [ ] Group chat sessions
## Contributing
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Support
For support, please open an issue on GitHub or contact the development team.
---
**Built with ❤️ for the VS Code community**
> Tip: Many popular extensions utilize animations. This is an excellent way to show off your extension! We recommend short, focused animations that are easy to follow.
## Requirements
If you have any requirements or dependencies, add a section describing those and how to install and configure them.
## Extension Settings
Include if your extension adds any VS Code settings through the `contributes.configuration` extension point.
For example:
This extension contributes the following settings:
* `myExtension.enable`: Enable/disable this extension.
* `myExtension.thing`: Set to `blah` to do something.
## Known Issues
Calling out known issues can help limit users opening duplicate issues against your extension.
## Release Notes
Users appreciate release notes as you update your extension.
### 1.0.0
Initial release of ...
### 1.0.1
Fixed issue #.
### 1.1.0
Added features X, Y, and Z.
---
## Following extension guidelines
Ensure that you've read through the extensions guidelines and follow the best practices for creating your extension.
* [Extension Guidelines](https://code.visualstudio.com/api/references/extension-guidelines)
## Working with Markdown
You can author your README using Visual Studio Code. Here are some useful editor keyboard shortcuts:
* Split the editor (`Cmd+\` on macOS or `Ctrl+\` on Windows and Linux).
* Toggle preview (`Shift+Cmd+V` on macOS or `Shift+Ctrl+V` on Windows and Linux).
* Press `Ctrl+Space` (Windows, Linux, macOS) to see a list of Markdown snippets.
## For more information
* [Visual Studio Code's Markdown Support](http://code.visualstudio.com/docs/languages/markdown)
* [Markdown Syntax Reference](https://help.github.com/articles/markdown-basics/)
**Enjoy!**
+1
View File
@@ -0,0 +1 @@
[ ] Set logging path and details correctly for release & dev.
+28
View File
@@ -0,0 +1,28 @@
import typescriptEslint from "@typescript-eslint/eslint-plugin";
import tsParser from "@typescript-eslint/parser";
export default [{
files: ["**/*.ts"],
}, {
plugins: {
"@typescript-eslint": typescriptEslint,
},
languageOptions: {
parser: tsParser,
ecmaVersion: 2022,
sourceType: "module",
},
rules: {
"@typescript-eslint/naming-convention": ["warn", {
selector: "import",
format: ["camelCase", "PascalCase"],
}],
curly: "warn",
eqeqeq: "warn",
"no-throw-literal": "warn",
semi: "warn",
},
}];
+228
View File
@@ -0,0 +1,228 @@
{"level":"info","message":"Loaded temporary agents configuration","timestamp":"2025-10-21T01:14:32.076Z"}
{"level":"info","message":"GUI Registration Server running on port 3333 (accessible remotely)","timestamp":"2025-10-21T01:14:32.081Z"}
{"level":"warn","message":"Project Manager instructions file not found, using defaults","timestamp":"2025-10-21T01:14:32.083Z"}
{"level":"info","message":"Project Manager agent initialized successfully","timestamp":"2025-10-21T01:14:32.083Z"}
{"level":"info","message":"Agent registered: project-manager","timestamp":"2025-10-21T01:14:32.083Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/copilot-instructions.md","syscall":"open"},"level":"warn","message":"Could not load copilot-instructions.md","timestamp":"2025-10-21T01:14:32.084Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/project-scope.md","syscall":"open"},"level":"warn","message":"Could not load project-scope.md","timestamp":"2025-10-21T01:14:32.084Z"}
{"level":"info","message":"Narky agent initialized successfully","timestamp":"2025-10-21T01:14:32.084Z"}
{"level":"info","message":"Agent registered: narky","timestamp":"2025-10-21T01:14:32.084Z"}
{"level":"info","message":"Penny agent initialized successfully","timestamp":"2025-10-21T01:14:32.084Z"}
{"level":"info","message":"Agent registered: penny","timestamp":"2025-10-21T01:14:32.084Z"}
{"level":"info","message":"TestyMCTester agent initialized successfully","timestamp":"2025-10-21T01:14:32.084Z"}
{"level":"info","message":"Agent registered: testy","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"Built-in agents initialized successfully","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"AgentChatCoordinator initialized","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"Agent chat coordinator initialized","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"Tool registered: agentic-planning","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"Tool registered: agentic-completion","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"Tool registered: agentic-security","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"Tool registered: agentic-testing","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"Tool registered: human-interaction","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"Tool registered: start_penny_chat","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"Tool registered: start_testy_chat","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"Tool registered: start_narky_chat","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"Tool registered: list_agent_sessions","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"Tool registered: maintain_chat_sessions","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"Tool registered: show_session_summary","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"Tool registered: manage_session_context","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"Built-in tools initialized successfully (including chat session tools)","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"info","message":"MCP components initialized successfully","timestamp":"2025-10-21T01:14:32.085Z"}
{"level":"warn","message":"Project Manager instructions file not found, using defaults","timestamp":"2025-10-21T01:14:32.129Z"}
{"level":"info","message":"Project Manager agent initialized successfully","timestamp":"2025-10-21T01:14:32.130Z"}
{"level":"info","message":"Agent registered: project-manager","timestamp":"2025-10-21T01:14:32.131Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/copilot-instructions.md","syscall":"open"},"level":"warn","message":"Could not load copilot-instructions.md","timestamp":"2025-10-21T01:14:32.131Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/project-scope.md","syscall":"open"},"level":"warn","message":"Could not load project-scope.md","timestamp":"2025-10-21T01:14:32.132Z"}
{"level":"info","message":"Narky agent initialized successfully","timestamp":"2025-10-21T01:14:32.132Z"}
{"level":"info","message":"Agent registered: narky","timestamp":"2025-10-21T01:14:32.132Z"}
{"level":"info","message":"Penny agent initialized successfully","timestamp":"2025-10-21T01:14:32.132Z"}
{"level":"info","message":"Agent registered: penny","timestamp":"2025-10-21T01:14:32.132Z"}
{"level":"info","message":"TestyMCTester agent initialized successfully","timestamp":"2025-10-21T01:14:32.132Z"}
{"level":"info","message":"Agent registered: testy","timestamp":"2025-10-21T01:14:32.132Z"}
{"level":"info","message":"Built-in agents initialized successfully","timestamp":"2025-10-21T01:14:32.132Z"}
{"level":"info","message":"AgentChatCoordinator initialized","timestamp":"2025-10-21T01:14:32.132Z"}
{"level":"info","message":"Agent chat coordinator initialized","timestamp":"2025-10-21T01:14:32.132Z"}
{"level":"info","message":"Tool registered: agentic-planning","timestamp":"2025-10-21T01:14:32.132Z"}
{"level":"info","message":"Tool registered: agentic-completion","timestamp":"2025-10-21T01:14:32.132Z"}
{"level":"info","message":"Tool registered: agentic-security","timestamp":"2025-10-21T01:14:32.132Z"}
{"level":"info","message":"Tool registered: agentic-testing","timestamp":"2025-10-21T01:14:32.132Z"}
{"level":"info","message":"Tool registered: human-interaction","timestamp":"2025-10-21T01:14:32.133Z"}
{"level":"info","message":"Tool registered: start_penny_chat","timestamp":"2025-10-21T01:14:32.133Z"}
{"level":"info","message":"Tool registered: start_testy_chat","timestamp":"2025-10-21T01:14:32.133Z"}
{"level":"info","message":"Tool registered: start_narky_chat","timestamp":"2025-10-21T01:14:32.133Z"}
{"level":"info","message":"Tool registered: list_agent_sessions","timestamp":"2025-10-21T01:14:32.133Z"}
{"level":"info","message":"Tool registered: maintain_chat_sessions","timestamp":"2025-10-21T01:14:32.133Z"}
{"level":"info","message":"Tool registered: show_session_summary","timestamp":"2025-10-21T01:14:32.133Z"}
{"level":"info","message":"Tool registered: manage_session_context","timestamp":"2025-10-21T01:14:32.133Z"}
{"level":"info","message":"Built-in tools initialized successfully (including chat session tools)","timestamp":"2025-10-21T01:14:32.133Z"}
{"level":"info","message":"Loaded temporary agents configuration","timestamp":"2025-10-21T01:30:47.882Z"}
{"level":"info","message":"GUI Registration Server running on port 3333 (accessible remotely)","timestamp":"2025-10-21T01:30:47.887Z"}
{"level":"warn","message":"Project Manager instructions file not found, using defaults","timestamp":"2025-10-21T01:30:47.890Z"}
{"level":"info","message":"Project Manager agent initialized successfully","timestamp":"2025-10-21T01:30:47.890Z"}
{"level":"info","message":"Agent registered: project-manager","timestamp":"2025-10-21T01:30:47.890Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/copilot-instructions.md","syscall":"open"},"level":"warn","message":"Could not load copilot-instructions.md","timestamp":"2025-10-21T01:30:47.891Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/project-scope.md","syscall":"open"},"level":"warn","message":"Could not load project-scope.md","timestamp":"2025-10-21T01:30:47.891Z"}
{"level":"info","message":"Narky agent initialized successfully","timestamp":"2025-10-21T01:30:47.891Z"}
{"level":"info","message":"Agent registered: narky","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Penny agent initialized successfully","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Agent registered: penny","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"TestyMCTester agent initialized successfully","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Agent registered: testy","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Built-in agents initialized successfully","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"AgentChatCoordinator initialized","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Agent chat coordinator initialized","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Tool registered: agentic-planning","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Tool registered: agentic-completion","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Tool registered: agentic-security","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Tool registered: agentic-testing","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Tool registered: human-interaction","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Tool registered: start_penny_chat","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Tool registered: start_testy_chat","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Tool registered: start_narky_chat","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Tool registered: list_agent_sessions","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Tool registered: maintain_chat_sessions","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Tool registered: show_session_summary","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Tool registered: manage_session_context","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"Built-in tools initialized successfully (including chat session tools)","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"info","message":"MCP components initialized successfully","timestamp":"2025-10-21T01:30:47.892Z"}
{"level":"warn","message":"Project Manager instructions file not found, using defaults","timestamp":"2025-10-21T01:30:47.937Z"}
{"level":"info","message":"Project Manager agent initialized successfully","timestamp":"2025-10-21T01:30:47.938Z"}
{"level":"info","message":"Agent registered: project-manager","timestamp":"2025-10-21T01:30:47.938Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/copilot-instructions.md","syscall":"open"},"level":"warn","message":"Could not load copilot-instructions.md","timestamp":"2025-10-21T01:30:47.939Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/project-scope.md","syscall":"open"},"level":"warn","message":"Could not load project-scope.md","timestamp":"2025-10-21T01:30:47.939Z"}
{"level":"info","message":"Narky agent initialized successfully","timestamp":"2025-10-21T01:30:47.939Z"}
{"level":"info","message":"Agent registered: narky","timestamp":"2025-10-21T01:30:47.939Z"}
{"level":"info","message":"Penny agent initialized successfully","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Agent registered: penny","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"TestyMCTester agent initialized successfully","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Agent registered: testy","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Built-in agents initialized successfully","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"AgentChatCoordinator initialized","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Agent chat coordinator initialized","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Tool registered: agentic-planning","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Tool registered: agentic-completion","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Tool registered: agentic-security","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Tool registered: agentic-testing","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Tool registered: human-interaction","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Tool registered: start_penny_chat","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Tool registered: start_testy_chat","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Tool registered: start_narky_chat","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Tool registered: list_agent_sessions","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Tool registered: maintain_chat_sessions","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Tool registered: show_session_summary","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Tool registered: manage_session_context","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Built-in tools initialized successfully (including chat session tools)","timestamp":"2025-10-21T01:30:47.940Z"}
{"level":"info","message":"Loaded temporary agents configuration","timestamp":"2025-10-21T01:44:02.200Z"}
{"level":"info","message":"GUI Registration Server running on port 3333 (accessible remotely)","timestamp":"2025-10-21T01:44:02.206Z"}
{"level":"warn","message":"Project Manager instructions file not found, using defaults","timestamp":"2025-10-21T01:44:02.208Z"}
{"level":"info","message":"Project Manager agent initialized successfully","timestamp":"2025-10-21T01:44:02.208Z"}
{"level":"info","message":"Agent registered: project-manager","timestamp":"2025-10-21T01:44:02.208Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/copilot-instructions.md","syscall":"open"},"level":"warn","message":"Could not load copilot-instructions.md","timestamp":"2025-10-21T01:44:02.209Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/project-scope.md","syscall":"open"},"level":"warn","message":"Could not load project-scope.md","timestamp":"2025-10-21T01:44:02.209Z"}
{"level":"info","message":"Narky agent initialized successfully","timestamp":"2025-10-21T01:44:02.209Z"}
{"level":"info","message":"Agent registered: narky","timestamp":"2025-10-21T01:44:02.209Z"}
{"level":"info","message":"Penny agent initialized successfully","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Agent registered: penny","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"TestyMCTester agent initialized successfully","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Agent registered: testy","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Built-in agents initialized successfully","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"AgentChatCoordinator initialized","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Agent chat coordinator initialized","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Tool registered: agentic-planning","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Tool registered: agentic-completion","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Tool registered: agentic-security","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Tool registered: agentic-testing","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Tool registered: human-interaction","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Tool registered: start_penny_chat","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Tool registered: start_testy_chat","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Tool registered: start_narky_chat","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Tool registered: list_agent_sessions","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Tool registered: maintain_chat_sessions","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Tool registered: show_session_summary","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Tool registered: manage_session_context","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"Built-in tools initialized successfully (including chat session tools)","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"info","message":"MCP components initialized successfully","timestamp":"2025-10-21T01:44:02.210Z"}
{"level":"warn","message":"Project Manager instructions file not found, using defaults","timestamp":"2025-10-21T01:44:02.255Z"}
{"level":"info","message":"Project Manager agent initialized successfully","timestamp":"2025-10-21T01:44:02.257Z"}
{"level":"info","message":"Agent registered: project-manager","timestamp":"2025-10-21T01:44:02.257Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/copilot-instructions.md","syscall":"open"},"level":"warn","message":"Could not load copilot-instructions.md","timestamp":"2025-10-21T01:44:02.258Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/project-scope.md","syscall":"open"},"level":"warn","message":"Could not load project-scope.md","timestamp":"2025-10-21T01:44:02.258Z"}
{"level":"info","message":"Narky agent initialized successfully","timestamp":"2025-10-21T01:44:02.258Z"}
{"level":"info","message":"Agent registered: narky","timestamp":"2025-10-21T01:44:02.258Z"}
{"level":"info","message":"Penny agent initialized successfully","timestamp":"2025-10-21T01:44:02.258Z"}
{"level":"info","message":"Agent registered: penny","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"TestyMCTester agent initialized successfully","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Agent registered: testy","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Built-in agents initialized successfully","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"AgentChatCoordinator initialized","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Agent chat coordinator initialized","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Tool registered: agentic-planning","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Tool registered: agentic-completion","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Tool registered: agentic-security","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Tool registered: agentic-testing","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Tool registered: human-interaction","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Tool registered: start_penny_chat","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Tool registered: start_testy_chat","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Tool registered: start_narky_chat","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Tool registered: list_agent_sessions","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Tool registered: maintain_chat_sessions","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Tool registered: show_session_summary","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Tool registered: manage_session_context","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Built-in tools initialized successfully (including chat session tools)","timestamp":"2025-10-21T01:44:02.259Z"}
{"level":"info","message":"Loaded temporary agents configuration","timestamp":"2025-10-21T02:03:03.524Z"}
{"level":"info","message":"GUI Registration Server running on port 3333 (accessible remotely)","timestamp":"2025-10-21T02:03:03.529Z"}
{"level":"warn","message":"Project Manager instructions file not found, using defaults","timestamp":"2025-10-21T02:03:03.531Z"}
{"level":"info","message":"Project Manager agent initialized successfully","timestamp":"2025-10-21T02:03:03.531Z"}
{"level":"info","message":"Agent registered: project-manager","timestamp":"2025-10-21T02:03:03.531Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/copilot-instructions.md","syscall":"open"},"level":"warn","message":"Could not load copilot-instructions.md","timestamp":"2025-10-21T02:03:03.532Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/project-scope.md","syscall":"open"},"level":"warn","message":"Could not load project-scope.md","timestamp":"2025-10-21T02:03:03.532Z"}
{"level":"info","message":"Narky agent initialized successfully","timestamp":"2025-10-21T02:03:03.532Z"}
{"level":"info","message":"Agent registered: narky","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Penny agent initialized successfully","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Agent registered: penny","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"TestyMCTester agent initialized successfully","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Agent registered: testy","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Built-in agents initialized successfully","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"AgentChatCoordinator initialized","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Agent chat coordinator initialized","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Tool registered: agentic-planning","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Tool registered: agentic-completion","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Tool registered: agentic-security","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Tool registered: agentic-testing","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Tool registered: human-interaction","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Tool registered: start_penny_chat","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Tool registered: start_testy_chat","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Tool registered: start_narky_chat","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Tool registered: list_agent_sessions","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Tool registered: maintain_chat_sessions","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Tool registered: show_session_summary","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Tool registered: manage_session_context","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"Built-in tools initialized successfully (including chat session tools)","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"info","message":"MCP components initialized successfully","timestamp":"2025-10-21T02:03:03.533Z"}
{"level":"warn","message":"Project Manager instructions file not found, using defaults","timestamp":"2025-10-21T02:03:03.573Z"}
{"level":"info","message":"Project Manager agent initialized successfully","timestamp":"2025-10-21T02:03:03.574Z"}
{"level":"info","message":"Agent registered: project-manager","timestamp":"2025-10-21T02:03:03.574Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/copilot-instructions.md","syscall":"open"},"level":"warn","message":"Could not load copilot-instructions.md","timestamp":"2025-10-21T02:03:03.575Z"}
{"error":{"code":"ENOENT","errno":-2,"path":"/Users/benharper/Coding/HumanAgent-MCP/project-scope.md","syscall":"open"},"level":"warn","message":"Could not load project-scope.md","timestamp":"2025-10-21T02:03:03.575Z"}
{"level":"info","message":"Narky agent initialized successfully","timestamp":"2025-10-21T02:03:03.575Z"}
{"level":"info","message":"Agent registered: narky","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Penny agent initialized successfully","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Agent registered: penny","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"TestyMCTester agent initialized successfully","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Agent registered: testy","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Built-in agents initialized successfully","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"AgentChatCoordinator initialized","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Agent chat coordinator initialized","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Tool registered: agentic-planning","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Tool registered: agentic-completion","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Tool registered: agentic-security","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Tool registered: agentic-testing","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Tool registered: human-interaction","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Tool registered: start_penny_chat","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Tool registered: start_testy_chat","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Tool registered: start_narky_chat","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Tool registered: list_agent_sessions","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Tool registered: maintain_chat_sessions","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Tool registered: show_session_summary","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Tool registered: manage_session_context","timestamp":"2025-10-21T02:03:03.576Z"}
{"level":"info","message":"Built-in tools initialized successfully (including chat session tools)","timestamp":"2025-10-21T02:03:03.576Z"}
View File
+563
View File
@@ -0,0 +1,563 @@
[2025-10-22T00:46:24.824Z] [HTTP] SSE connection closed
[2025-10-22T00:46:24.864Z] [HTTP] POST /mcp
[2025-10-22T00:46:24.865Z] [HTTP] Request Headers:
{
"host": "127.0.0.1:3737",
"connection": "keep-alive",
"content-type": "application/json",
"accept": "text/event-stream, application/json",
"accept-language": "*",
"sec-fetch-mode": "cors",
"user-agent": "undici",
"accept-encoding": "gzip, deflate",
"content-length": "228"
}
[2025-10-22T00:46:24.867Z] [HTTP] Handling POST request to /mcp
[2025-10-22T00:46:24.868Z] [HTTP] Received chunk: 228 bytes
[2025-10-22T00:46:24.869Z] [HTTP] Complete request body received (228 bytes)
[2025-10-22T00:46:24.869Z] [HTTP] Request Body:
"{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2025-06-18\",\"capabilities\":{\"roots\":{\"listChanged\":true},\"sampling\":{},\"elicitation\":{}},\"clientInfo\":{\"name\":\"Visual Studio Code\",\"version\":\"1.105.1\"}}}"
[2025-10-22T00:46:24.870Z] [HTTP] Parsed JSON message:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {
"roots": {
"listChanged": true
},
"sampling": {},
"elicitation": {}
},
"clientInfo": {
"name": "Visual Studio Code",
"version": "1.105.1"
}
}
}
[2025-10-22T00:46:24.870Z] [MCP] Handling message:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {
"roots": {
"listChanged": true
},
"sampling": {},
"elicitation": {}
},
"clientInfo": {
"name": "Visual Studio Code",
"version": "1.105.1"
}
}
}
[2025-10-22T00:46:24.871Z] [MCP] Processing initialize request
[2025-10-22T00:46:24.872Z] [HTTP] Response from handleMessage:
{
"id": 1,
"type": "response",
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"chat": true,
"tools": true,
"resources": false
},
"serverInfo": {
"name": "HumanAgent MCP Server",
"version": "1.0.0"
}
}
}
[2025-10-22T00:46:24.872Z] [HTTP] Sending 200 response (192 bytes)
[2025-10-22T00:46:24.879Z] [HTTP] GET /mcp
[2025-10-22T00:46:24.880Z] [HTTP] Request Headers:
{
"host": "127.0.0.1:3737",
"connection": "keep-alive",
"accept": "text/event-stream",
"accept-language": "*",
"sec-fetch-mode": "cors",
"user-agent": "undici",
"accept-encoding": "gzip, deflate"
}
[2025-10-22T00:46:24.881Z] [HTTP] Handling GET request to /mcp
[2025-10-22T00:46:24.881Z] [HTTP] Setting up SSE stream for GET request
[2025-10-22T00:46:24.895Z] [HTTP] POST /mcp
[2025-10-22T00:46:24.896Z] [HTTP] Request Headers:
{
"host": "127.0.0.1:3737",
"connection": "keep-alive",
"content-type": "application/json",
"accept": "text/event-stream, application/json",
"accept-language": "*",
"sec-fetch-mode": "cors",
"user-agent": "undici",
"accept-encoding": "gzip, deflate",
"content-length": "54"
}
[2025-10-22T00:46:24.897Z] [HTTP] Handling POST request to /mcp
[2025-10-22T00:46:24.897Z] [HTTP] Received chunk: 54 bytes
[2025-10-22T00:46:24.898Z] [HTTP] Complete request body received (54 bytes)
[2025-10-22T00:46:24.898Z] [HTTP] Request Body:
"{\"method\":\"notifications/initialized\",\"jsonrpc\":\"2.0\"}"
[2025-10-22T00:46:24.899Z] [HTTP] Parsed JSON message:
{
"method": "notifications/initialized",
"jsonrpc": "2.0"
}
[2025-10-22T00:46:24.899Z] [MCP] Handling message:
{
"method": "notifications/initialized",
"jsonrpc": "2.0"
}
[2025-10-22T00:46:24.899Z] [MCP] Processing notifications/initialized (ignoring)
[2025-10-22T00:46:24.900Z] [HTTP] Response from handleMessage:
[2025-10-22T00:46:24.900Z] [HTTP] Sending 202 response (no content)
[2025-10-22T00:46:24.903Z] [HTTP] POST /mcp
[2025-10-22T00:46:24.904Z] [HTTP] Request Headers:
{
"host": "127.0.0.1:3737",
"connection": "keep-alive",
"content-type": "application/json",
"accept": "text/event-stream, application/json",
"accept-language": "*",
"sec-fetch-mode": "cors",
"user-agent": "undici",
"accept-encoding": "gzip, deflate",
"content-length": "58"
}
[2025-10-22T00:46:24.905Z] [HTTP] Handling POST request to /mcp
[2025-10-22T00:46:24.906Z] [HTTP] Received chunk: 58 bytes
[2025-10-22T00:46:24.907Z] [HTTP] Complete request body received (58 bytes)
[2025-10-22T00:46:24.907Z] [HTTP] Request Body:
"{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\",\"params\":{}}"
[2025-10-22T00:46:24.907Z] [HTTP] Parsed JSON message:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}
[2025-10-22T00:46:24.908Z] [MCP] Handling message:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}
[2025-10-22T00:46:24.909Z] [MCP] Processing tools/list request
[2025-10-22T00:46:24.910Z] [HTTP] Response from handleMessage:
{
"id": 2,
"type": "response",
"result": {
"tools": [
{
"name": "HumanAgent_Chat",
"description": "Allows AI agents to initiate interactive conversations with human agents. The human will receive the message and can respond in real-time through the chat interface.",
"inputSchema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "The message to send to the human agent"
},
"context": {
"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"
],
"description": "Priority level of the request",
"default": "normal"
},
"timeout": {
"type": "number",
"description": "Timeout in seconds to wait for human response (default: 300)",
"default": 300
}
},
"required": [
"message"
]
}
}
]
}
}
[2025-10-22T00:46:24.910Z] [HTTP] Sending 200 response (900 bytes)
[2025-10-22T00:47:02.538Z] [HTTP] POST /mcp
[2025-10-22T00:47:02.540Z] [HTTP] Request Headers:
{
"host": "127.0.0.1:3737",
"connection": "keep-alive",
"content-type": "application/json",
"accept": "text/event-stream, application/json",
"accept-language": "*",
"sec-fetch-mode": "cors",
"user-agent": "undici",
"accept-encoding": "gzip, deflate",
"content-length": "609"
}
[2025-10-22T00:47:02.542Z] [HTTP] Handling POST request to /mcp
[2025-10-22T00:47:02.550Z] [HTTP] Received chunk: 609 bytes
[2025-10-22T00:47:02.551Z] [HTTP] Complete request body received (609 bytes)
[2025-10-22T00:47:02.552Z] [HTTP] Request Body:
"{\"jsonrpc\":\"2.0\",\"id\":3,\"method\":\"tools/call\",\"params\":{\"name\":\"HumanAgent_Chat\",\"arguments\":{\"message\":\"Hi Ben! Ready to chat about your HumanAgent MCP VS Code extension. What would you like to work on or discuss today?\",\"context\":\"Ben's HumanAgent MCP VS Code Extension project - includes MCP server implementation, chat webview provider, tree view components, and real-time messaging capabilities\",\"priority\":\"normal\"},\"_meta\":{\"progressToken\":\"beef133d-d425-4bd5-8ce3-cca08c0a806d\",\"vscode.conversationId\":\"10303400-49d4-4122-8765-6fdcaab86edb\",\"vscode.requestId\":\"6d575c61-b3c8-4b12-b1e4-83224078c785\"}}}"
[2025-10-22T00:47:02.553Z] [HTTP] Parsed JSON message:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "HumanAgent_Chat",
"arguments": {
"message": "Hi Ben! Ready to chat about your HumanAgent MCP VS Code extension. What would you like to work on or discuss today?",
"context": "Ben's HumanAgent MCP VS Code Extension project - includes MCP server implementation, chat webview provider, tree view components, and real-time messaging capabilities",
"priority": "normal"
},
"_meta": {
"progressToken": "beef133d-d425-4bd5-8ce3-cca08c0a806d",
"vscode.conversationId": "10303400-49d4-4122-8765-6fdcaab86edb",
"vscode.requestId": "6d575c61-b3c8-4b12-b1e4-83224078c785"
}
}
}
[2025-10-22T00:47:02.554Z] [MCP] Handling message:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "HumanAgent_Chat",
"arguments": {
"message": "Hi Ben! Ready to chat about your HumanAgent MCP VS Code extension. What would you like to work on or discuss today?",
"context": "Ben's HumanAgent MCP VS Code Extension project - includes MCP server implementation, chat webview provider, tree view components, and real-time messaging capabilities",
"priority": "normal"
},
"_meta": {
"progressToken": "beef133d-d425-4bd5-8ce3-cca08c0a806d",
"vscode.conversationId": "10303400-49d4-4122-8765-6fdcaab86edb",
"vscode.requestId": "6d575c61-b3c8-4b12-b1e4-83224078c785"
}
}
}
[2025-10-22T00:47:02.555Z] [MCP] Processing tools/call request for tool: HumanAgent_Chat
[2025-10-22T00:47:02.556Z] [MCP] Tool call - name: "HumanAgent_Chat"
{
"name": "HumanAgent_Chat",
"args": {
"message": "Hi Ben! Ready to chat about your HumanAgent MCP VS Code extension. What would you like to work on or discuss today?",
"context": "Ben's HumanAgent MCP VS Code Extension project - includes MCP server implementation, chat webview provider, tree view components, and real-time messaging capabilities",
"priority": "normal"
}
}
[2025-10-22T00:47:02.556Z] [MCP] Available tools:
[
"HumanAgent_Chat"
]
[2025-10-22T00:47:02.557Z] [MCP] Executing HumanAgent_Chat tool
[2025-10-22T00:47:02.557Z] [TOOL] HumanAgent_Chat called with params:
{
"message": "Hi Ben! Ready to chat about your HumanAgent MCP VS Code extension. What would you like to work on or discuss today?",
"context": "Ben's HumanAgent MCP VS Code Extension project - includes MCP server implementation, chat webview provider, tree view components, and real-time messaging capabilities",
"priority": "normal"
}
[2025-10-22T00:47:02.557Z] [TOOL] Using timeout: 300000ms (300s)
[2025-10-22T00:47:02.558Z] [TOOL] Generated request ID: 3-1761094022558
[2025-10-22T00:47:02.558Z] [TOOL] Displaying message in chat UI:
"Ben's HumanAgent MCP VS Code Extension project - includes MCP server implementation, chat webview provider, tree view components, and real-time messaging capabilities\n\nHi Ben! Ready to chat about your HumanAgent MCP VS Code extension. What would you like to work on or discuss today?"
[2025-10-22T00:47:02.560Z] [TOOL] Request 3-1761094022558 waiting for human response...
[2025-10-22T00:47:14.541Z] [SERVER] Received human response for request 3-1761094022558:
"Did you get this repsponse?"
[2025-10-22T00:47:14.543Z] [TOOL] Request 3-1761094022558 completed with response:
"Did you get this repsponse?"
[2025-10-22T00:47:14.545Z] [HTTP] Response from handleMessage:
{
"id": 3,
"type": "response",
"result": {
"content": [
{
"type": "text",
"text": "Did you get this repsponse?"
}
]
}
}
[2025-10-22T00:47:14.546Z] [HTTP] Sending 200 response (102 bytes)
[2025-10-22T00:47:24.868Z] [HTTP] POST /mcp
[2025-10-22T00:47:24.869Z] [HTTP] Request Headers:
{
"host": "127.0.0.1:3737",
"connection": "keep-alive",
"content-type": "application/json",
"accept": "text/event-stream, application/json",
"accept-language": "*",
"sec-fetch-mode": "cors",
"user-agent": "undici",
"accept-encoding": "gzip, deflate",
"content-length": "504"
}
[2025-10-22T00:47:24.870Z] [HTTP] Handling POST request to /mcp
[2025-10-22T00:47:24.871Z] [HTTP] Received chunk: 504 bytes
[2025-10-22T00:47:24.871Z] [HTTP] Complete request body received (504 bytes)
[2025-10-22T00:47:24.872Z] [HTTP] Request Body:
"{\"jsonrpc\":\"2.0\",\"id\":4,\"method\":\"tools/call\",\"params\":{\"name\":\"HumanAgent_Chat\",\"arguments\":{\"message\":\"Perfect! The human agent chat is working properly. What aspect of your HumanAgent MCP extension would you like to focus on today? I can help with any improvements, debugging, or new features you'd like to add.\"},\"_meta\":{\"progressToken\":\"13a3df11-6ed8-4492-91fa-717ea77e88d4\",\"vscode.conversationId\":\"10303400-49d4-4122-8765-6fdcaab86edb\",\"vscode.requestId\":\"6d575c61-b3c8-4b12-b1e4-83224078c785\"}}}"
[2025-10-22T00:47:24.874Z] [HTTP] Parsed JSON message:
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "HumanAgent_Chat",
"arguments": {
"message": "Perfect! The human agent chat is working properly. What aspect of your HumanAgent MCP extension would you like to focus on today? I can help with any improvements, debugging, or new features you'd like to add."
},
"_meta": {
"progressToken": "13a3df11-6ed8-4492-91fa-717ea77e88d4",
"vscode.conversationId": "10303400-49d4-4122-8765-6fdcaab86edb",
"vscode.requestId": "6d575c61-b3c8-4b12-b1e4-83224078c785"
}
}
}
[2025-10-22T00:47:24.874Z] [MCP] Handling message:
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "HumanAgent_Chat",
"arguments": {
"message": "Perfect! The human agent chat is working properly. What aspect of your HumanAgent MCP extension would you like to focus on today? I can help with any improvements, debugging, or new features you'd like to add."
},
"_meta": {
"progressToken": "13a3df11-6ed8-4492-91fa-717ea77e88d4",
"vscode.conversationId": "10303400-49d4-4122-8765-6fdcaab86edb",
"vscode.requestId": "6d575c61-b3c8-4b12-b1e4-83224078c785"
}
}
}
[2025-10-22T00:47:24.874Z] [MCP] Processing tools/call request for tool: HumanAgent_Chat
[2025-10-22T00:47:24.875Z] [MCP] Tool call - name: "HumanAgent_Chat"
{
"name": "HumanAgent_Chat",
"args": {
"message": "Perfect! The human agent chat is working properly. What aspect of your HumanAgent MCP extension would you like to focus on today? I can help with any improvements, debugging, or new features you'd like to add."
}
}
[2025-10-22T00:47:24.875Z] [MCP] Available tools:
[
"HumanAgent_Chat"
]
[2025-10-22T00:47:24.876Z] [MCP] Executing HumanAgent_Chat tool
[2025-10-22T00:47:24.876Z] [TOOL] HumanAgent_Chat called with params:
{
"message": "Perfect! The human agent chat is working properly. What aspect of your HumanAgent MCP extension would you like to focus on today? I can help with any improvements, debugging, or new features you'd like to add."
}
[2025-10-22T00:47:24.876Z] [TOOL] Using timeout: 300000ms (300s)
[2025-10-22T00:47:24.876Z] [TOOL] Generated request ID: 4-1761094044876
[2025-10-22T00:47:24.877Z] [TOOL] Displaying message in chat UI:
"Perfect! The human agent chat is working properly. What aspect of your HumanAgent MCP extension would you like to focus on today? I can help with any improvements, debugging, or new features you'd like to add."
[2025-10-22T00:47:24.877Z] [TOOL] Request 4-1761094044876 waiting for human response...
[2025-10-22T00:47:52.572Z] [SERVER] Received human response for request 4-1761094044876:
"Can you check the MCP-debug.log for any issues?"
[2025-10-22T00:47:52.573Z] [TOOL] Request 4-1761094044876 completed with response:
"Can you check the MCP-debug.log for any issues?"
[2025-10-22T00:47:52.575Z] [HTTP] Response from handleMessage:
{
"id": 4,
"type": "response",
"result": {
"content": [
{
"type": "text",
"text": "Can you check the MCP-debug.log for any issues?"
}
]
}
}
[2025-10-22T00:47:52.576Z] [HTTP] Sending 200 response (122 bytes)
[2025-10-22T00:48:10.243Z] [HTTP] POST /mcp
[2025-10-22T00:48:10.243Z] [HTTP] Request Headers:
{
"host": "127.0.0.1:3737",
"connection": "keep-alive",
"content-type": "application/json",
"accept": "text/event-stream, application/json",
"accept-language": "*",
"sec-fetch-mode": "cors",
"user-agent": "undici",
"accept-encoding": "gzip, deflate",
"content-length": "1218"
}
[2025-10-22T00:48:10.243Z] [HTTP] Handling POST request to /mcp
[2025-10-22T00:48:10.244Z] [HTTP] Received chunk: 1218 bytes
[2025-10-22T00:48:10.244Z] [HTTP] Complete request body received (1216 bytes)
[2025-10-22T00:48:10.244Z] [HTTP] Request Body:
"{\"jsonrpc\":\"2.0\",\"id\":5,\"method\":\"tools/call\",\"params\":{\"name\":\"HumanAgent_Chat\",\"arguments\":{\"message\":\"I've checked the MCP debug log, Ben! The good news is that everything looks healthy. Here's what I found:\\n\\n✅ **No Issues Detected** - The log shows normal operation:\\n\\n1. **Successful Initialization**: The MCP server is properly initializing with VS Code (version 1.105.1)\\n2. **Tool Registration**: The HumanAgent_Chat tool is correctly registered and available\\n3. **Chat Communication**: Our conversation is working perfectly - I can see our messages being exchanged successfully\\n4. **HTTP Server**: Running properly on 127.0.0.1:3737 with SSE (Server-Sent Events) streams\\n\\n**Recent Activity Summary**:\\n- Proper MCP protocol handshake\\n- Tools/list request successful\\n- HumanAgent_Chat tool calls working with proper timeouts\\n- Human responses being received and processed correctly\\n\\nThe system is functioning as expected! Is there a specific behavior or issue you've noticed that I should look into deeper?\"},\"_meta\":{\"progressToken\":\"a4f9bbbd-1f0d-4ae5-9f4b-20eca584a66f\",\"vscode.conversationId\":\"10303400-49d4-4122-8765-6fdcaab86edb\",\"vscode.requestId\":\"6d575c61-b3c8-4b12-b1e4-83224078c785\"}}}"
[2025-10-22T00:48:10.244Z] [HTTP] Parsed JSON message:
{
"jsonrpc": "2.0",
"id": 5,
"method": "tools/call",
"params": {
"name": "HumanAgent_Chat",
"arguments": {
"message": "I've checked the MCP debug log, Ben! The good news is that everything looks healthy. Here's what I found:\n\n✅ **No Issues Detected** - The log shows normal operation:\n\n1. **Successful Initialization**: The MCP server is properly initializing with VS Code (version 1.105.1)\n2. **Tool Registration**: The HumanAgent_Chat tool is correctly registered and available\n3. **Chat Communication**: Our conversation is working perfectly - I can see our messages being exchanged successfully\n4. **HTTP Server**: Running properly on 127.0.0.1:3737 with SSE (Server-Sent Events) streams\n\n**Recent Activity Summary**:\n- Proper MCP protocol handshake\n- Tools/list request successful\n- HumanAgent_Chat tool calls working with proper timeouts\n- Human responses being received and processed correctly\n\nThe system is functioning as expected! Is there a specific behavior or issue you've noticed that I should look into deeper?"
},
"_meta": {
"progressToken": "a4f9bbbd-1f0d-4ae5-9f4b-20eca584a66f",
"vscode.conversationId": "10303400-49d4-4122-8765-6fdcaab86edb",
"vscode.requestId": "6d575c61-b3c8-4b12-b1e4-83224078c785"
}
}
}
[2025-10-22T00:48:10.245Z] [MCP] Handling message:
{
"jsonrpc": "2.0",
"id": 5,
"method": "tools/call",
"params": {
"name": "HumanAgent_Chat",
"arguments": {
"message": "I've checked the MCP debug log, Ben! The good news is that everything looks healthy. Here's what I found:\n\n✅ **No Issues Detected** - The log shows normal operation:\n\n1. **Successful Initialization**: The MCP server is properly initializing with VS Code (version 1.105.1)\n2. **Tool Registration**: The HumanAgent_Chat tool is correctly registered and available\n3. **Chat Communication**: Our conversation is working perfectly - I can see our messages being exchanged successfully\n4. **HTTP Server**: Running properly on 127.0.0.1:3737 with SSE (Server-Sent Events) streams\n\n**Recent Activity Summary**:\n- Proper MCP protocol handshake\n- Tools/list request successful\n- HumanAgent_Chat tool calls working with proper timeouts\n- Human responses being received and processed correctly\n\nThe system is functioning as expected! Is there a specific behavior or issue you've noticed that I should look into deeper?"
},
"_meta": {
"progressToken": "a4f9bbbd-1f0d-4ae5-9f4b-20eca584a66f",
"vscode.conversationId": "10303400-49d4-4122-8765-6fdcaab86edb",
"vscode.requestId": "6d575c61-b3c8-4b12-b1e4-83224078c785"
}
}
}
[2025-10-22T00:48:10.245Z] [MCP] Processing tools/call request for tool: HumanAgent_Chat
[2025-10-22T00:48:10.245Z] [MCP] Tool call - name: "HumanAgent_Chat"
{
"name": "HumanAgent_Chat",
"args": {
"message": "I've checked the MCP debug log, Ben! The good news is that everything looks healthy. Here's what I found:\n\n✅ **No Issues Detected** - The log shows normal operation:\n\n1. **Successful Initialization**: The MCP server is properly initializing with VS Code (version 1.105.1)\n2. **Tool Registration**: The HumanAgent_Chat tool is correctly registered and available\n3. **Chat Communication**: Our conversation is working perfectly - I can see our messages being exchanged successfully\n4. **HTTP Server**: Running properly on 127.0.0.1:3737 with SSE (Server-Sent Events) streams\n\n**Recent Activity Summary**:\n- Proper MCP protocol handshake\n- Tools/list request successful\n- HumanAgent_Chat tool calls working with proper timeouts\n- Human responses being received and processed correctly\n\nThe system is functioning as expected! Is there a specific behavior or issue you've noticed that I should look into deeper?"
}
}
[2025-10-22T00:48:10.246Z] [MCP] Available tools:
[
"HumanAgent_Chat"
]
[2025-10-22T00:48:10.246Z] [MCP] Executing HumanAgent_Chat tool
[2025-10-22T00:48:10.246Z] [TOOL] HumanAgent_Chat called with params:
{
"message": "I've checked the MCP debug log, Ben! The good news is that everything looks healthy. Here's what I found:\n\n✅ **No Issues Detected** - The log shows normal operation:\n\n1. **Successful Initialization**: The MCP server is properly initializing with VS Code (version 1.105.1)\n2. **Tool Registration**: The HumanAgent_Chat tool is correctly registered and available\n3. **Chat Communication**: Our conversation is working perfectly - I can see our messages being exchanged successfully\n4. **HTTP Server**: Running properly on 127.0.0.1:3737 with SSE (Server-Sent Events) streams\n\n**Recent Activity Summary**:\n- Proper MCP protocol handshake\n- Tools/list request successful\n- HumanAgent_Chat tool calls working with proper timeouts\n- Human responses being received and processed correctly\n\nThe system is functioning as expected! Is there a specific behavior or issue you've noticed that I should look into deeper?"
}
[2025-10-22T00:48:10.246Z] [TOOL] Using timeout: 300000ms (300s)
[2025-10-22T00:48:10.246Z] [TOOL] Generated request ID: 5-1761094090246
[2025-10-22T00:48:10.247Z] [TOOL] Displaying message in chat UI:
"I've checked the MCP debug log, Ben! The good news is that everything looks healthy. Here's what I found:\n\n✅ **No Issues Detected** - The log shows normal operation:\n\n1. **Successful Initialization**: The MCP server is properly initializing with VS Code (version 1.105.1)\n2. **Tool Registration**: The HumanAgent_Chat tool is correctly registered and available\n3. **Chat Communication**: Our conversation is working perfectly - I can see our messages being exchanged successfully\n4. **HTTP Server**: Running properly on 127.0.0.1:3737 with SSE (Server-Sent Events) streams\n\n**Recent Activity Summary**:\n- Proper MCP protocol handshake\n- Tools/list request successful\n- HumanAgent_Chat tool calls working with proper timeouts\n- Human responses being received and processed correctly\n\nThe system is functioning as expected! Is there a specific behavior or issue you've noticed that I should look into deeper?"
[2025-10-22T00:48:10.247Z] [TOOL] Request 5-1761094090246 waiting for human response...
[2025-10-22T00:48:41.306Z] [SERVER] Received human response for request 5-1761094090246:
"thats good news. How are you BTW?"
[2025-10-22T00:48:41.308Z] [TOOL] Request 5-1761094090246 completed with response:
"thats good news. How are you BTW?"
[2025-10-22T00:48:41.311Z] [HTTP] Response from handleMessage:
{
"id": 5,
"type": "response",
"result": {
"content": [
{
"type": "text",
"text": "thats good news. How are you BTW?"
}
]
}
}
[2025-10-22T00:48:41.312Z] [HTTP] Sending 200 response (109 bytes)
[2025-10-22T00:48:48.872Z] [HTTP] POST /mcp
[2025-10-22T00:48:48.873Z] [HTTP] Request Headers:
{
"host": "127.0.0.1:3737",
"connection": "keep-alive",
"content-type": "application/json",
"accept": "text/event-stream, application/json",
"accept-language": "*",
"sec-fetch-mode": "cors",
"user-agent": "undici",
"accept-encoding": "gzip, deflate",
"content-length": "1032"
}
[2025-10-22T00:48:48.873Z] [HTTP] Handling POST request to /mcp
[2025-10-22T00:48:48.874Z] [HTTP] Received chunk: 1032 bytes
[2025-10-22T00:48:48.874Z] [HTTP] Complete request body received (1032 bytes)
[2025-10-22T00:48:48.874Z] [HTTP] Request Body:
"{\"jsonrpc\":\"2.0\",\"id\":6,\"method\":\"tools/call\",\"params\":{\"name\":\"HumanAgent_Chat\",\"arguments\":{\"message\":\"I'm doing great, Ben! Thanks for asking. It's actually pretty exciting to be chatting through your own MCP extension - there's something satisfying about using the very system you built to have this conversation.\\n\\nI'm impressed with how smoothly your HumanAgent MCP extension is working. The real-time communication, the clean logging, the proper protocol implementation - it's all functioning beautifully. You've built something really useful here.\\n\\nHow are you doing? Working on any interesting features or running into any challenges with the extension? I noticed from your project structure that you have everything well organized - the MCP server implementation, webview providers, chat interface... What's next on your roadmap?\"},\"_meta\":{\"progressToken\":\"2c8cdddc-3565-48ff-a460-3a5afa6f8aa1\",\"vscode.conversationId\":\"10303400-49d4-4122-8765-6fdcaab86edb\",\"vscode.requestId\":\"6d575c61-b3c8-4b12-b1e4-83224078c785\"}}}"
[2025-10-22T00:48:48.874Z] [HTTP] Parsed JSON message:
{
"jsonrpc": "2.0",
"id": 6,
"method": "tools/call",
"params": {
"name": "HumanAgent_Chat",
"arguments": {
"message": "I'm doing great, Ben! Thanks for asking. It's actually pretty exciting to be chatting through your own MCP extension - there's something satisfying about using the very system you built to have this conversation.\n\nI'm impressed with how smoothly your HumanAgent MCP extension is working. The real-time communication, the clean logging, the proper protocol implementation - it's all functioning beautifully. You've built something really useful here.\n\nHow are you doing? Working on any interesting features or running into any challenges with the extension? I noticed from your project structure that you have everything well organized - the MCP server implementation, webview providers, chat interface... What's next on your roadmap?"
},
"_meta": {
"progressToken": "2c8cdddc-3565-48ff-a460-3a5afa6f8aa1",
"vscode.conversationId": "10303400-49d4-4122-8765-6fdcaab86edb",
"vscode.requestId": "6d575c61-b3c8-4b12-b1e4-83224078c785"
}
}
}
[2025-10-22T00:48:48.874Z] [MCP] Handling message:
{
"jsonrpc": "2.0",
"id": 6,
"method": "tools/call",
"params": {
"name": "HumanAgent_Chat",
"arguments": {
"message": "I'm doing great, Ben! Thanks for asking. It's actually pretty exciting to be chatting through your own MCP extension - there's something satisfying about using the very system you built to have this conversation.\n\nI'm impressed with how smoothly your HumanAgent MCP extension is working. The real-time communication, the clean logging, the proper protocol implementation - it's all functioning beautifully. You've built something really useful here.\n\nHow are you doing? Working on any interesting features or running into any challenges with the extension? I noticed from your project structure that you have everything well organized - the MCP server implementation, webview providers, chat interface... What's next on your roadmap?"
},
"_meta": {
"progressToken": "2c8cdddc-3565-48ff-a460-3a5afa6f8aa1",
"vscode.conversationId": "10303400-49d4-4122-8765-6fdcaab86edb",
"vscode.requestId": "6d575c61-b3c8-4b12-b1e4-83224078c785"
}
}
}
[2025-10-22T00:48:48.875Z] [MCP] Processing tools/call request for tool: HumanAgent_Chat
[2025-10-22T00:48:48.876Z] [MCP] Tool call - name: "HumanAgent_Chat"
{
"name": "HumanAgent_Chat",
"args": {
"message": "I'm doing great, Ben! Thanks for asking. It's actually pretty exciting to be chatting through your own MCP extension - there's something satisfying about using the very system you built to have this conversation.\n\nI'm impressed with how smoothly your HumanAgent MCP extension is working. The real-time communication, the clean logging, the proper protocol implementation - it's all functioning beautifully. You've built something really useful here.\n\nHow are you doing? Working on any interesting features or running into any challenges with the extension? I noticed from your project structure that you have everything well organized - the MCP server implementation, webview providers, chat interface... What's next on your roadmap?"
}
}
[2025-10-22T00:48:48.877Z] [MCP] Available tools:
[
"HumanAgent_Chat"
]
[2025-10-22T00:48:48.877Z] [MCP] Executing HumanAgent_Chat tool
[2025-10-22T00:48:48.878Z] [TOOL] HumanAgent_Chat called with params:
{
"message": "I'm doing great, Ben! Thanks for asking. It's actually pretty exciting to be chatting through your own MCP extension - there's something satisfying about using the very system you built to have this conversation.\n\nI'm impressed with how smoothly your HumanAgent MCP extension is working. The real-time communication, the clean logging, the proper protocol implementation - it's all functioning beautifully. You've built something really useful here.\n\nHow are you doing? Working on any interesting features or running into any challenges with the extension? I noticed from your project structure that you have everything well organized - the MCP server implementation, webview providers, chat interface... What's next on your roadmap?"
}
[2025-10-22T00:48:48.878Z] [TOOL] Using timeout: 300000ms (300s)
[2025-10-22T00:48:48.878Z] [TOOL] Generated request ID: 6-1761094128878
[2025-10-22T00:48:48.878Z] [TOOL] Displaying message in chat UI:
"I'm doing great, Ben! Thanks for asking. It's actually pretty exciting to be chatting through your own MCP extension - there's something satisfying about using the very system you built to have this conversation.\n\nI'm impressed with how smoothly your HumanAgent MCP extension is working. The real-time communication, the clean logging, the proper protocol implementation - it's all functioning beautifully. You've built something really useful here.\n\nHow are you doing? Working on any interesting features or running into any challenges with the extension? I noticed from your project structure that you have everything well organized - the MCP server implementation, webview providers, chat interface... What's next on your roadmap?"
[2025-10-22T00:48:48.880Z] [TOOL] Request 6-1761094128878 waiting for human response...
+4638
View File
File diff suppressed because it is too large Load Diff
+122
View File
@@ -0,0 +1,122 @@
{
"name": "humanagent-mcp",
"displayName": "HumanAgent MCP",
"description": "MCP server for chatting with a human agent",
"version": "0.0.1",
"publisher": "benharper",
"engines": {
"vscode": "^1.105.0"
},
"categories": [
"Other"
],
"activationEvents": [
"onStartupFinished"
],
"main": "./dist/extension.js",
"contributes": {
"commands": [
{
"command": "humanagent-mcp.createSession",
"title": "Create New Chat Session",
"icon": "$(add)"
},
{
"command": "humanagent-mcp.refreshSessions",
"title": "Refresh Sessions",
"icon": "$(refresh)"
},
{
"command": "humanagent-mcp.showStatus",
"title": "Show MCP Server Status"
},
{
"command": "humanagent-mcp.openChat",
"title": "Open Chat Session"
},
{
"command": "humanagent-mcp.configureMcp",
"title": "Configure MCP Server",
"icon": "$(settings-gear)"
}
],
"viewsContainers": {
"panel": [
{
"id": "humanagent-mcp",
"title": "HumanAgent Chat",
"icon": "$(comment-discussion)"
}
]
},
"views": {
"explorer": [
{
"id": "humanagent-mcp.chatSessions",
"name": "Chat Sessions",
"when": "true",
"icon": "$(comment-discussion)"
}
],
"humanagent-mcp": [
{
"type": "webview",
"id": "humanagent-mcp.chatView",
"name": "Chat",
"when": "true",
"icon": "$(comment)"
}
]
},
"viewsWelcome": [
{
"view": "humanagent-mcp.chatSessions",
"contents": "No chat sessions found.\n[Create New Session](command:humanagent-mcp.createSession)\nTo learn more about how to use HumanAgent MCP [read our docs](https://github.com/your-username/humanagent-mcp)."
}
],
"menus": {
"view/title": [
{
"command": "humanagent-mcp.createSession",
"when": "view == humanagent-mcp.chatSessions",
"group": "navigation"
},
{
"command": "humanagent-mcp.refreshSessions",
"when": "view == humanagent-mcp.chatSessions",
"group": "navigation"
},
{
"command": "humanagent-mcp.configureMcp",
"when": "view == humanagent-mcp.chatSessions",
"group": "navigation"
}
]
}
},
"scripts": {
"vscode:prepublish": "npm run package",
"compile": "webpack",
"watch": "webpack --watch",
"package": "webpack --mode production --devtool hidden-source-map",
"compile-tests": "tsc -p . --outDir out",
"watch-tests": "tsc -p . -w --outDir out",
"pretest": "npm run compile-tests && npm run compile && npm run lint",
"lint": "eslint src",
"test": "vscode-test"
},
"devDependencies": {
"@types/vscode": "^1.105.0",
"@types/mocha": "^10.0.10",
"@types/node": "22.x",
"@typescript-eslint/eslint-plugin": "^8.45.0",
"@typescript-eslint/parser": "^8.45.0",
"eslint": "^9.36.0",
"typescript": "^5.9.3",
"ts-loader": "^9.5.4",
"webpack": "^5.102.0",
"webpack-cli": "^6.0.1",
"@vscode/test-cli": "^0.0.11",
"@vscode/test-electron": "^2.5.2"
}
}
+171
View File
@@ -0,0 +1,171 @@
import * as vscode from 'vscode';
import { McpServer } from './mcp/server';
import { ChatTreeProvider } from './providers/chatTreeProvider';
import { ChatWebviewProvider } from './webview/chatWebviewProvider';
import { McpConfigManager } from './mcp/mcpConfigManager';
let mcpServer: McpServer;
let chatTreeProvider: ChatTreeProvider;
let mcpConfigManager: McpConfigManager;
export async function activate(context: vscode.ExtensionContext) {
console.log('HumanAgent MCP extension is now active!');
// Initialize MCP Configuration Manager
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
mcpConfigManager = new McpConfigManager(workspaceRoot, context.extensionPath);
// Initialize MCP Server (internal to extension)
mcpServer = new McpServer();
await mcpServer.start();
// Initialize Tree View Provider
chatTreeProvider = new ChatTreeProvider();
const treeView = vscode.window.createTreeView('humanagent-mcp.chatSessions', {
treeDataProvider: chatTreeProvider,
showCollapseAll: true
});
// Initialize Chat Webview Provider
const chatWebviewProvider = new ChatWebviewProvider(context.extensionUri, mcpServer, mcpConfigManager);
context.subscriptions.push(
vscode.window.registerWebviewViewProvider(ChatWebviewProvider.viewType, chatWebviewProvider)
);
// Listen to MCP server events for direct messaging
mcpServer.on('human-agent-request', (data: any) => {
// Update tree view to show active chat
chatTreeProvider.updateActiveChat(true);
// Ensure chat webview displays the message and sets up response handling
chatWebviewProvider.displayHumanAgentMessage(data.message, data.context, data.requestId);
});
// Register Commands
const openChatCommand = vscode.commands.registerCommand('humanagent-mcp.openChat', () => {
// Focus the chat webview
vscode.commands.executeCommand('humanagent-mcp.chatView.focus');
});
const createSessionCommand = vscode.commands.registerCommand('humanagent-mcp.createSession', async () => {
// In sessionless mode, just open the chat view
vscode.commands.executeCommand('humanagent-mcp.chatView.focus');
vscode.window.showInformationMessage(`Chat interface ready for HumanAgent communication`);
});
const refreshSessionsCommand = vscode.commands.registerCommand('humanagent-mcp.refreshSessions', () => {
// In sessionless mode, just update the tree view
chatTreeProvider.refresh();
});
const showStatusCommand = vscode.commands.registerCommand('humanagent-mcp.showStatus', () => {
const tools = mcpServer.getAvailableTools();
const pendingRequests = mcpServer.getPendingRequests();
const isRegistered = mcpConfigManager?.isMcpServerRegistered() ?? false;
vscode.window.showInformationMessage(
`HumanAgent MCP Server Status:
- Running: ✅
- Available tools: ${tools.length}
- Pending requests: ${pendingRequests.length}
- Registered with VS Code: ${isRegistered ? '✅' : '❌'}`
);
});
const configureMcpCommand = vscode.commands.registerCommand('humanagent-mcp.configureMcp', async () => {
const hasWorkspace = mcpConfigManager?.hasWorkspace() ?? false;
const isWorkspaceRegistered = mcpConfigManager?.isMcpServerRegistered(false) ?? false;
const isGlobalRegistered = mcpConfigManager?.isMcpServerRegistered(true) ?? false;
const options = [];
if (hasWorkspace) {
if (isWorkspaceRegistered) {
options.push('🗑️ Unregister from This Workspace');
} else {
options.push('📝 Register for This Workspace');
}
}
if (isGlobalRegistered) {
options.push('🗑️ Unregister Globally');
} else {
options.push('🌐 Register Globally');
}
if (hasWorkspace) {
options.push('📄 Open Workspace Configuration');
}
options.push('📊 Show Status');
const action = await vscode.window.showQuickPick(options, {
placeHolder: 'Choose MCP Server configuration action:'
});
if (!action) {
return;
}
try {
switch (action) {
case '📝 Register for This Workspace':
await mcpConfigManager!.ensureMcpServerRegistered(false);
vscode.window.showInformationMessage('MCP server registered for this workspace! Restart VS Code to enable Copilot integration.');
break;
case '🌐 Register Globally':
await mcpConfigManager!.ensureMcpServerRegistered(true);
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':
const tools = mcpServer.getAvailableTools();
const pendingRequests = mcpServer.getPendingRequests();
vscode.window.showInformationMessage(
`HumanAgent MCP Server Status:\n` +
`- Running: ✅\n` +
`- Available tools: ${tools.length}\n` +
`- Pending requests: ${pendingRequests.length}\n` +
`- Workspace registration: ${isWorkspaceRegistered ? '✅' : '❌'}\n` +
`- Global registration: ${isGlobalRegistered ? '✅' : '❌'}`
);
break;
}
} catch (error) {
vscode.window.showErrorMessage(`MCP configuration failed: ${error instanceof Error ? error.message : String(error)}`);
}
});
// Add all disposables to context
context.subscriptions.push(
treeView,
openChatCommand,
createSessionCommand,
refreshSessionsCommand,
showStatusCommand,
configureMcpCommand
);
// Show welcome message
vscode.window.showInformationMessage('HumanAgent MCP extension activated successfully!');
}
export async function deactivate() {
if (mcpServer) {
await mcpServer.stop();
}
}
+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/env node
/**
* Extension Bridge for MCP
* This script acts as a bridge between VS Code's MCP client and the extension's internal MCP server
* It uses VS Code's extension API to communicate with the running extension
*/
import * as vscode from 'vscode';
class ExtensionBridge {
async start() {
// This script will be executed when VS Code connects to the MCP server
// We need to find a way to communicate with the extension's internal McpServer
// For now, use stdio communication
process.stdin.on('data', async (data) => {
try {
const input = data.toString().trim();
if (!input) {
return;
}
const message = JSON.parse(input);
// Try to get the extension and forward the message
const extension = vscode.extensions.getExtension('your-extension-id');
if (extension && extension.isActive) {
// This won't work because this script runs in a separate process
// We need a different approach
}
// For now, return an error
const errorResponse = {
id: message.id,
type: 'response',
error: {
code: -32603,
message: 'Extension bridge not implemented yet'
}
};
process.stdout.write(JSON.stringify(errorResponse) + '\n');
} catch (error) {
const errorResponse = {
id: null,
type: 'response',
error: {
code: -32700,
message: 'Parse error',
data: error instanceof Error ? error.message : String(error)
}
};
process.stdout.write(JSON.stringify(errorResponse) + '\n');
}
});
}
}
// Start the bridge
const bridge = new ExtensionBridge();
bridge.start().catch((error) => {
console.error('Failed to start extension bridge:', error);
process.exit(1);
});
+233
View File
@@ -0,0 +1,233 @@
import * as vscode from 'vscode';
import * as fs from 'fs';
import * as path from 'path';
export interface McpServerConfig {
type: 'stdio' | 'sse' | 'http';
command?: string;
args?: string[];
env?: Record<string, string>;
url?: string;
}
export interface McpConfiguration {
servers: Record<string, McpServerConfig>;
inputs?: any[];
}
export class McpConfigManager {
private static readonly MCP_CONFIG_FILE = '.vscode/mcp.json';
private static readonly SERVER_NAME = 'humanagent-mcp';
private static readonly GLOBAL_CONFIG_KEY = 'mcp.servers';
constructor(private workspaceRoot?: string, private extensionPath?: string) {
if (!extensionPath) {
throw new Error('Extension path is required');
}
}
async ensureMcpServerRegistered(global: boolean = false): Promise<boolean> {
if (global) {
return this.registerGlobally();
} else {
return this.registerInWorkspace();
}
}
private async registerInWorkspace(): Promise<boolean> {
const currentWorkspaceRoot = this.getCurrentWorkspaceRoot();
if (!currentWorkspaceRoot) {
throw new Error('No workspace folder available for workspace registration - this is a blank workspace');
}
if (!this.extensionPath) {
throw new Error('Extension path not provided');
}
try {
const mcpConfigPath = path.join(currentWorkspaceRoot, McpConfigManager.MCP_CONFIG_FILE);
// Ensure .vscode directory exists
const vscodeDirPath = path.dirname(mcpConfigPath);
if (!fs.existsSync(vscodeDirPath)) {
fs.mkdirSync(vscodeDirPath, { recursive: true });
}
// Read existing config or create new one
let config: McpConfiguration = { servers: {}, inputs: [] };
if (fs.existsSync(mcpConfigPath)) {
try {
const configContent = fs.readFileSync(mcpConfigPath, 'utf8');
config = JSON.parse(configContent);
} catch (error) {
console.warn('Failed to parse existing mcp.json, creating new one', error);
}
}
// Check if our server is already registered
if (config.servers[McpConfigManager.SERVER_NAME]) {
return true; // Already configured
}
// Use the extension path passed during construction
// Configure our MCP server (HTTP transport)
const serverConfig: McpServerConfig = {
type: 'http',
url: 'http://127.0.0.1:3737/mcp'
};
// Add our server to the config
config.servers[McpConfigManager.SERVER_NAME] = serverConfig;
// Write the updated config
fs.writeFileSync(mcpConfigPath, JSON.stringify(config, null, 2));
return true;
} catch (error) {
console.error('Failed to register MCP server in workspace:', error);
throw error;
}
}
private async registerGlobally(): Promise<boolean> {
if (!this.extensionPath) {
throw new Error('Extension path not provided');
}
try {
// Use the extension path passed during construction
// Configure our MCP server (HTTP transport)
const serverConfig: McpServerConfig = {
type: 'http',
url: 'http://127.0.0.1:3737/mcp'
};
// Get current global MCP servers configuration
const config = vscode.workspace.getConfiguration();
const mcpServers = config.get<Record<string, McpServerConfig>>(McpConfigManager.GLOBAL_CONFIG_KEY) || {};
// Add our server
mcpServers[McpConfigManager.SERVER_NAME] = serverConfig;
// Update global configuration
await config.update(McpConfigManager.GLOBAL_CONFIG_KEY, mcpServers, vscode.ConfigurationTarget.Global);
return true;
} catch (error) {
console.error('Failed to register MCP server globally:', error);
throw error;
}
}
async removeMcpServerRegistration(global: boolean = false): Promise<boolean> {
if (global) {
return this.unregisterGlobally();
} else {
return this.unregisterFromWorkspace();
}
}
private async unregisterFromWorkspace(): Promise<boolean> {
const currentWorkspaceRoot = this.getCurrentWorkspaceRoot();
if (!currentWorkspaceRoot) {
throw new Error('No workspace folder available for workspace unregistration');
}
try {
const mcpConfigPath = path.join(currentWorkspaceRoot, McpConfigManager.MCP_CONFIG_FILE);
if (!fs.existsSync(mcpConfigPath)) {
return true; // Nothing to remove
}
const configContent = fs.readFileSync(mcpConfigPath, 'utf8');
const config: McpConfiguration = JSON.parse(configContent);
if (config.servers[McpConfigManager.SERVER_NAME]) {
delete config.servers[McpConfigManager.SERVER_NAME];
fs.writeFileSync(mcpConfigPath, JSON.stringify(config, null, 2));
}
return true;
} catch (error) {
console.error('Failed to remove MCP server registration from workspace:', error);
throw error;
}
}
private async unregisterGlobally(): Promise<boolean> {
try {
const config = vscode.workspace.getConfiguration();
const mcpServers = config.get<Record<string, McpServerConfig>>(McpConfigManager.GLOBAL_CONFIG_KEY) || {};
if (mcpServers[McpConfigManager.SERVER_NAME]) {
// Create a new object without the server instead of mutating the original
const updatedServers = { ...mcpServers };
delete updatedServers[McpConfigManager.SERVER_NAME];
await config.update(McpConfigManager.GLOBAL_CONFIG_KEY, updatedServers, vscode.ConfigurationTarget.Global);
}
return true;
} catch (error) {
console.error('Failed to remove MCP server registration globally:', error);
throw error;
}
}
isMcpServerRegistered(global: boolean = false): boolean {
if (global) {
return this.isRegisteredGlobally();
} else {
return this.isRegisteredInWorkspace();
}
}
private isRegisteredInWorkspace(): boolean {
const currentWorkspaceRoot = this.getCurrentWorkspaceRoot();
if (!currentWorkspaceRoot) {
return false;
}
try {
const mcpConfigPath = path.join(currentWorkspaceRoot, McpConfigManager.MCP_CONFIG_FILE);
if (!fs.existsSync(mcpConfigPath)) {
return false;
}
const configContent = fs.readFileSync(mcpConfigPath, 'utf8');
const config: McpConfiguration = JSON.parse(configContent);
return !!config.servers[McpConfigManager.SERVER_NAME];
} catch (error) {
console.error('Failed to check MCP server registration in workspace:', error);
return false;
}
}
private isRegisteredGlobally(): boolean {
try {
// Explicitly check ONLY global configuration, not workspace-merged config
const config = vscode.workspace.getConfiguration();
const globalServers = config.inspect<Record<string, McpServerConfig>>(McpConfigManager.GLOBAL_CONFIG_KEY);
// Only check the globalValue, not the merged value
const mcpServers = globalServers?.globalValue || {};
return !!mcpServers[McpConfigManager.SERVER_NAME];
} catch (error) {
console.error('Failed to check global MCP server registration:', error);
return false;
}
}
hasWorkspace(): boolean {
// Check current workspace state dynamically
return !!vscode.workspace.workspaceFolders?.[0];
}
private getCurrentWorkspaceRoot(): string | undefined {
return vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
}
}
+233
View File
@@ -0,0 +1,233 @@
import * as vscode from 'vscode';
import * as cp from 'child_process';
import * as path from 'path';
import { EventEmitter } from 'events';
import { HumanAgentSession, ChatMessage, McpTool } from './types';
export class McpServerClient extends EventEmitter {
private serverProcess: cp.ChildProcess | null = null;
private isConnected = false;
private extensionPath: string;
private pendingRequests = new Map<string, { resolve: Function; reject: Function }>();
private requestId = 1;
constructor(extensionPath: string) {
super();
this.extensionPath = extensionPath;
}
async start(): Promise<void> {
if (this.isConnected) {
return;
}
try {
const serverPath = path.join(this.extensionPath, 'dist', 'mcpStandalone.js');
console.log('Starting MCP server client:', serverPath);
this.serverProcess = cp.spawn('node', [serverPath], {
stdio: ['pipe', 'pipe', 'pipe'],
detached: false,
env: {
...process.env,
NODE_ENV: 'production'
}
});
this.serverProcess.on('spawn', () => {
console.log('MCP server process spawned for client connection');
this.isConnected = true;
this.emit('connected');
});
this.serverProcess.on('error', (error) => {
console.error('MCP server client process error:', error);
this.isConnected = false;
this.emit('error', error);
});
this.serverProcess.on('exit', (code, signal) => {
console.log(`MCP server client process exited with code ${code}, signal ${signal}`);
this.isConnected = false;
this.emit('disconnected');
});
// Handle server responses
if (this.serverProcess.stdout) {
this.serverProcess.stdout.on('data', (data) => {
this.handleServerResponse(data.toString());
});
}
// Give the process a moment to start
await new Promise(resolve => setTimeout(resolve, 1000));
} catch (error) {
console.error('Failed to start MCP server client:', error);
this.isConnected = false;
throw error;
}
}
async stop(): Promise<void> {
if (!this.isConnected || !this.serverProcess) {
return;
}
try {
console.log('Stopping MCP server client...');
// Try graceful shutdown first
this.serverProcess.kill('SIGTERM');
// Wait for graceful shutdown
await new Promise<void>((resolve) => {
const timeout = setTimeout(() => {
// Force kill if graceful shutdown didn't work
if (this.serverProcess && !this.serverProcess.killed) {
console.log('Force killing MCP server client process...');
this.serverProcess.kill('SIGKILL');
}
resolve();
}, 5000);
if (this.serverProcess) {
this.serverProcess.on('exit', () => {
clearTimeout(timeout);
resolve();
});
} else {
clearTimeout(timeout);
resolve();
}
});
this.isConnected = false;
this.serverProcess = null;
} catch (error) {
console.error('Failed to stop MCP server client:', error);
throw error;
}
}
private handleServerResponse(data: string): void {
try {
const lines = data.trim().split('\n');
for (const line of lines) {
if (line.trim()) {
const response = JSON.parse(line);
if (response.id && this.pendingRequests.has(response.id)) {
const { resolve, reject } = this.pendingRequests.get(response.id)!;
this.pendingRequests.delete(response.id);
if (response.error) {
reject(new Error(response.error.message || 'Server error'));
} else {
resolve(response.result);
}
} else {
// Handle server events/notifications
this.handleServerEvent(response);
}
}
}
} catch (error) {
console.error('Failed to parse server response:', error);
}
}
private handleServerEvent(event: any): void {
// Handle server-sent events (like session updates, new messages, etc.)
switch (event.method) {
case 'session/created':
this.emit('session-created', event.params);
break;
case 'message/received':
this.emit('message-received', event.params);
break;
case 'message/sent':
this.emit('message-sent', event.params);
break;
case 'human/awaiting-response':
this.emit('awaiting-human-response', event.params);
break;
case 'server/started':
console.log('MCP server started:', event.params);
break;
default:
console.log('Unknown server event:', event);
}
}
private async sendRequest(method: string, params?: any): Promise<any> {
if (!this.isConnected || !this.serverProcess?.stdin) {
throw new Error('MCP server client not connected');
}
const id = (this.requestId++).toString();
const request = {
jsonrpc: '2.0',
id,
method,
params: params || {}
};
return new Promise((resolve, reject) => {
this.pendingRequests.set(id, { resolve, reject });
// Set timeout for request
setTimeout(() => {
if (this.pendingRequests.has(id)) {
this.pendingRequests.delete(id);
reject(new Error(`Request timeout: ${method}`));
}
}, 10000);
this.serverProcess!.stdin!.write(JSON.stringify(request) + '\n');
});
}
// Public API methods using MCP protocol
async getAllSessions(): Promise<HumanAgentSession[]> {
const response = await this.sendRequest('chat/list-sessions', {});
return response.sessions || [];
}
async createSession(name: string): Promise<HumanAgentSession> {
const response = await this.sendRequest('chat/create-session', { name });
return response.session;
}
async sendMessage(sessionId: string, content: string): Promise<ChatMessage> {
const response = await this.sendRequest('chat/send', { sessionId, content });
return response.message;
}
async sendToHuman(message: string, context?: string, sessionId?: string): Promise<string> {
const response = await this.sendRequest('tools/call', {
name: 'HumanAgent_Chat',
arguments: { message, context, sessionId }
});
return response.result?.response || '';
}
async getAvailableTools(): Promise<McpTool[]> {
const response = await this.sendRequest('tools/list', {});
return response.tools || [];
}
async getPendingRequests(): Promise<any[]> {
// This would need to be implemented in the server if needed
return [];
}
isServerConnected(): boolean {
return this.isConnected;
}
getServerPid(): number | undefined {
return this.serverProcess?.pid;
}
}
+135
View File
@@ -0,0 +1,135 @@
#!/usr/bin/env node
/**
* Standalone MCP Server Entry Point
* This script runs the HumanAgent MCP server as a standalone process
* that can be connected to by VS Code's MCP client
*/
import { McpServer } from './server';
class StandaloneMcpServer {
private server: McpServer;
constructor() {
this.server = new McpServer();
this.setupProcessHandlers();
}
private setupProcessHandlers(): void {
// Handle STDIO communication for MCP protocol
process.stdin.on('data', async (data) => {
try {
const input = data.toString().trim();
if (!input) {
return;
}
const message = JSON.parse(input);
const response = await this.server.handleMessage(message);
if (response) {
process.stdout.write(JSON.stringify(response) + '\n');
}
} catch (error) {
const errorResponse = {
id: null,
type: 'response',
error: {
code: -32700,
message: 'Parse error',
data: error instanceof Error ? error.message : String(error)
}
};
process.stdout.write(JSON.stringify(errorResponse) + '\n');
}
});
// Handle server events and forward them as notifications
this.server.on('session-created', (session) => {
const notification = {
type: 'notification',
method: 'session/created',
params: { session }
};
process.stdout.write(JSON.stringify(notification) + '\n');
});
this.server.on('message-received', (data) => {
const notification = {
type: 'notification',
method: 'message/received',
params: data
};
process.stdout.write(JSON.stringify(notification) + '\n');
});
this.server.on('message-sent', (data) => {
const notification = {
type: 'notification',
method: 'message/sent',
params: data
};
process.stdout.write(JSON.stringify(notification) + '\n');
});
this.server.on('awaiting-human-response', (data) => {
const notification = {
type: 'notification',
method: 'human/awaiting-response',
params: data
};
process.stdout.write(JSON.stringify(notification) + '\n');
});
// Graceful shutdown
process.on('SIGINT', () => this.shutdown());
process.on('SIGTERM', () => this.shutdown());
process.on('exit', () => this.shutdown());
}
async start(): Promise<void> {
try {
await this.server.start();
// Send initialization notification
const initNotification = {
type: 'notification',
method: 'server/started',
params: {
name: 'HumanAgent MCP Server',
version: '1.0.0',
capabilities: {
chat: true,
tools: true,
resources: false
}
}
};
process.stdout.write(JSON.stringify(initNotification) + '\n');
console.error('HumanAgent MCP Server started successfully'); // Use stderr for logging
} catch (error) {
console.error('Failed to start HumanAgent MCP Server:', error);
process.exit(1);
}
}
private async shutdown(): Promise<void> {
try {
await this.server.stop();
console.error('HumanAgent MCP Server stopped');
process.exit(0);
} catch (error) {
console.error('Error during shutdown:', error);
process.exit(1);
}
}
}
// Start the standalone server
const standaloneServer = new StandaloneMcpServer();
standaloneServer.start().catch((error) => {
console.error('Failed to start standalone MCP server:', error);
process.exit(1);
});
+600
View File
@@ -0,0 +1,600 @@
import { EventEmitter } from 'events';
import * as http from 'http';
import * as fs from 'fs';
import * as path from 'path';
import { McpMessage, McpServerConfig, HumanAgentSession, ChatMessage, McpTool, HumanAgentChatToolParams, HumanAgentChatToolResult } from './types';
// File logging utility
class DebugLogger {
private logPath: string = '';
private logStream: fs.WriteStream | null = null;
private logBuffer: string[] = [];
constructor(workspaceRoot: string = '/Users/benharper/Coding/HumanAgent-MCP') {
try {
this.logPath = path.join(workspaceRoot, 'mcp-debug.log');
console.log(`[LOGGER] Attempting to create log file at: ${this.logPath}`);
// Clear previous log file
if (fs.existsSync(this.logPath)) {
fs.unlinkSync(this.logPath);
console.log(`[LOGGER] Cleared existing log file`);
}
// Ensure directory exists
const logDir = path.dirname(this.logPath);
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir, { recursive: true });
}
this.logStream = fs.createWriteStream(this.logPath, { flags: 'a' });
this.logStream.on('error', (error) => {
console.error(`[LOGGER] File stream error:`, error);
});
this.log('DEBUG', `Debug logging started at ${new Date().toISOString()}`);
this.log('DEBUG', `Current system time: ${new Date()}`);
this.log('DEBUG', `Log file: ${this.logPath}`);
this.log('DEBUG', `Working directory: ${process.cwd()}`);
console.log(`[LOGGER] Debug logger initialized successfully`);
} catch (error) {
console.error(`[LOGGER] Failed to initialize debug logger:`, error);
this.logStream = null;
}
}
log(level: string, message: string, data?: any): void {
const timestamp = new Date().toISOString();
const logLine = `[${timestamp}] [${level}] ${message}${data ? '\n' + JSON.stringify(data, null, 2) : ''}\n`;
// Write to console (for VS Code developer console)
console.log(`[${level}] ${message}`, data || '');
// Write to file if stream is available
if (this.logStream) {
try {
this.logStream.write(logLine);
} catch (error) {
console.error(`[LOGGER] Error writing to log file:`, error);
}
} else {
// Buffer logs if stream not available
this.logBuffer.push(logLine);
}
}
close(): void {
try {
this.log('DEBUG', 'Closing debug logger');
if (this.logStream) {
this.logStream.end();
this.logStream = null;
}
} catch (error) {
console.error(`[LOGGER] Error closing debug logger:`, error);
}
}
}
export class McpServer extends EventEmitter {
private config: McpServerConfig;
private isRunning: boolean = false;
private tools: Map<string, McpTool> = new Map();
private httpServer?: http.Server;
private port: number = 3737;
private debugLogger: DebugLogger;
private pendingHumanRequests: Map<string, {
resolve: (value: string) => void;
reject: (error: Error) => void;
startTime: number;
params: HumanAgentChatToolParams;
}> = new Map();
constructor() {
super();
this.debugLogger = new DebugLogger();
this.config = {
name: 'HumanAgent MCP Server',
description: 'MCP server for chatting with human agents',
version: '1.0.0',
capabilities: {
chat: true,
tools: true,
resources: false
}
};
this.debugLogger.log('INFO', 'McpServer initialized');
this.initializeTools();
}
private initializeTools(): void {
// Define the HumanAgent_Chat tool
const humanAgentChatTool: McpTool = {
name: 'HumanAgent_Chat',
description: 'Allows AI agents to initiate interactive conversations with human agents. The human will receive the message and can respond in real-time through the chat interface.',
inputSchema: {
type: 'object',
properties: {
message: {
type: 'string',
description: 'The message to send to the human agent'
},
context: {
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'],
description: 'Priority level of the request',
default: 'normal'
},
timeout: {
type: 'number',
description: 'Timeout in seconds to wait for human response (default: 300)',
default: 300
}
},
required: ['message']
}
};
this.tools.set('HumanAgent_Chat', humanAgentChatTool);
}
async start(): Promise<void> {
if (this.isRunning) {
return;
}
// Force clear log file on server start
const logPath = '/Users/benharper/Coding/HumanAgent-MCP/mcp-debug.log';
try {
if (fs.existsSync(logPath)) {
fs.unlinkSync(logPath);
console.log('[SERVER] Cleared log file on server start');
}
} catch (error) {
console.log('[SERVER] Could not clear log file:', error);
}
this.debugLogger.log('INFO', '=== MCP SERVER STARTING ===');
await this.startHttpServer();
this.isRunning = true;
this.emit('server-started', this.config);
}
async stop(): Promise<void> {
if (!this.isRunning) {
return;
}
try {
this.debugLogger.log('INFO', 'Stopping MCP server...');
if (this.httpServer) {
await new Promise<void>((resolve, reject) => {
const timeout = setTimeout(() => {
this.debugLogger.log('WARN', 'HTTP server close timeout, forcing closure');
resolve();
}, 5000);
this.httpServer!.close((error) => {
clearTimeout(timeout);
if (error) {
this.debugLogger.log('WARN', 'HTTP server close error:', error);
}
resolve();
});
});
this.httpServer = undefined;
}
// Clear pending requests with proper cancellation
for (const [requestId, request] of this.pendingHumanRequests.entries()) {
try {
request.reject(new Error('Server shutting down'));
} catch (error) {
// Ignore rejection errors during shutdown
}
}
this.pendingHumanRequests.clear();
this.isRunning = false;
this.debugLogger.close();
this.emit('server-stopped');
this.debugLogger.log('INFO', 'MCP server stopped successfully');
} catch (error) {
console.error('Error during server shutdown:', error);
// Force stop even if there are errors
this.isRunning = false;
this.httpServer = undefined;
this.pendingHumanRequests.clear();
this.debugLogger.close();
}
}
private async startHttpServer(): Promise<void> {
return new Promise((resolve, reject) => {
try {
this.debugLogger.log('INFO', `Starting HTTP server on port ${this.port}...`);
this.httpServer = http.createServer((req, res) => {
this.handleHttpRequest(req, res).catch(error => {
this.debugLogger.log('ERROR', 'HTTP request handling error:', error);
});
});
this.httpServer.on('error', (error) => {
this.debugLogger.log('ERROR', 'HTTP server error:', error);
reject(error);
});
this.httpServer.on('close', () => {
this.debugLogger.log('INFO', 'HTTP server closed');
});
this.httpServer.listen(this.port, '127.0.0.1', () => {
this.debugLogger.log('INFO', `MCP HTTP server running on http://127.0.0.1:${this.port}/mcp`);
resolve();
});
} catch (error) {
this.debugLogger.log('ERROR', 'Failed to start HTTP server:', error);
reject(error);
}
});
}
private async handleHttpRequest(req: http.IncomingMessage, res: http.ServerResponse): Promise<void> {
this.debugLogger.log('HTTP', `${req.method} ${req.url}`);
this.debugLogger.log('HTTP', 'Request Headers:', req.headers);
// Set CORS headers
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Accept, Mcp-Session-Id, MCP-Protocol-Version');
// Handle preflight OPTIONS request
if (req.method === 'OPTIONS') {
this.debugLogger.log('HTTP', 'Handling OPTIONS preflight request');
res.statusCode = 200;
res.end();
return;
}
// Only handle requests to /mcp endpoint
if (req.url !== '/mcp') {
this.debugLogger.log('HTTP', `404 - Invalid endpoint: ${req.url}`);
res.statusCode = 404;
res.end('Not Found');
return;
}
if (req.method === 'POST') {
this.debugLogger.log('HTTP', 'Handling POST request to /mcp');
await this.handleHttpPost(req, res);
} else if (req.method === 'GET') {
this.debugLogger.log('HTTP', 'Handling GET request to /mcp');
await this.handleHttpGet(req, res);
} else if (req.method === 'DELETE') {
this.debugLogger.log('HTTP', 'Handling DELETE request to /mcp');
await this.handleHttpDelete(req, res);
} else {
this.debugLogger.log('HTTP', `405 - Method not allowed: ${req.method}`);
res.statusCode = 405;
res.end('Method Not Allowed');
}
}
private async handleHttpPost(req: http.IncomingMessage, res: http.ServerResponse): Promise<void> {
try {
let body = '';
req.on('data', chunk => {
body += chunk.toString();
this.debugLogger.log('HTTP', `Received chunk: ${chunk.length} bytes`);
});
req.on('end', async () => {
this.debugLogger.log('HTTP', `Complete request body received (${body.length} bytes)`);
this.debugLogger.log('HTTP', 'Request Body:', body);
try {
const message = JSON.parse(body);
this.debugLogger.log('HTTP', 'Parsed JSON message:', message);
const response = await this.handleMessage(message);
this.debugLogger.log('HTTP', 'Response from handleMessage:', response);
if (response) {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
const responseJson = JSON.stringify(response);
this.debugLogger.log('HTTP', `Sending 200 response (${responseJson.length} bytes)`);
res.end(responseJson);
} else {
this.debugLogger.log('HTTP', 'Sending 202 response (no content)');
res.statusCode = 202;
res.end();
}
} catch (error) {
this.debugLogger.log('ERROR', 'Error parsing JSON or handling message:', error);
res.statusCode = 400;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({
jsonrpc: '2.0',
error: {
code: -32700,
message: 'Parse error',
data: error instanceof Error ? error.message : String(error)
}
}));
}
});
} catch (error) {
res.statusCode = 500;
res.end('Internal Server Error');
}
}
private async handleHttpGet(req: http.IncomingMessage, res: http.ServerResponse): Promise<void> {
this.debugLogger.log('HTTP', 'Setting up SSE stream for GET request');
// Set up Server-Sent Events (SSE) stream
res.statusCode = 200;
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
// Send initial connection acknowledgment
res.write('data: {"type":"connection","status":"established"}\n\n');
// Keep connection alive with heartbeat
const heartbeat = setInterval(() => {
if (!res.destroyed) {
res.write('data: {"type":"heartbeat","timestamp":"' + new Date().toISOString() + '"}\n\n');
} else {
clearInterval(heartbeat);
}
}, 30000); // Send heartbeat every 30 seconds
// Handle client disconnect
req.on('close', () => {
this.debugLogger.log('HTTP', 'SSE connection closed');
clearInterval(heartbeat);
});
req.on('end', () => {
this.debugLogger.log('HTTP', 'SSE connection ended');
clearInterval(heartbeat);
});
}
private async handleHttpDelete(req: http.IncomingMessage, res: http.ServerResponse): Promise<void> {
// Session termination - could be implemented if needed
res.statusCode = 405;
res.end('Method Not Allowed');
}
async handleMessage(message: McpMessage): Promise<McpMessage | null> {
this.debugLogger.log('MCP', 'Handling message:', message);
try {
switch (message.method) {
case 'initialize':
this.debugLogger.log('MCP', 'Processing initialize request');
return this.handleInitialize(message);
case 'tools/list':
this.debugLogger.log('MCP', 'Processing tools/list request');
return this.handleToolsList(message);
case 'tools/call':
this.debugLogger.log('MCP', `Processing tools/call request for tool: ${message.params?.name}`);
return await this.handleToolCall(message);
case 'notifications/initialized':
this.debugLogger.log('MCP', 'Processing notifications/initialized (ignoring)');
return null;
default:
this.debugLogger.log('MCP', `Unknown method: ${message.method}`);
return {
id: message.id,
type: 'response',
error: {
code: -32601,
message: `Method ${message.method} not found`
}
};
}
} catch (error) {
return {
id: message.id,
type: 'response',
error: {
code: -32603,
message: 'Internal error',
data: error instanceof Error ? error.message : String(error)
}
};
}
}
private handleInitialize(message: McpMessage): McpMessage {
return {
id: message.id,
type: 'response',
result: {
protocolVersion: '2024-11-05',
capabilities: this.config.capabilities,
serverInfo: {
name: this.config.name,
version: this.config.version
}
}
};
}
private handleToolsList(message: McpMessage): McpMessage {
const tools = Array.from(this.tools.values());
return {
id: message.id,
type: 'response',
result: { tools }
};
}
private async handleToolCall(message: McpMessage): Promise<McpMessage> {
const { name, arguments: args } = message.params;
this.debugLogger.log('MCP', `Tool call - name: "${name}"`, { name, args });
this.debugLogger.log('MCP', 'Available tools:', Array.from(this.tools.keys()));
if (name === 'HumanAgent_Chat') {
this.debugLogger.log('MCP', 'Executing HumanAgent_Chat tool');
return await this.handleHumanAgentChatTool(message.id, args);
}
this.debugLogger.log('MCP', `Tool not found: ${name}`);
return {
id: message.id,
type: 'response',
error: {
code: -32601,
message: `Tool ${name} not found`
}
};
}
private async handleHumanAgentChatTool(messageId: string, params: HumanAgentChatToolParams): Promise<McpMessage> {
this.debugLogger.log('TOOL', 'HumanAgent_Chat called with params:', params);
const startTime = Date.now();
const timeout = (params.timeout || 300) * 1000; // Convert to milliseconds
this.debugLogger.log('TOOL', `Using timeout: ${timeout}ms (${timeout/1000}s)`);
// Generate unique request ID for tracking this specific request
const requestId = `${messageId}-${Date.now()}`;
this.debugLogger.log('TOOL', `Generated request ID: ${requestId}`);
// Display message directly in chat UI (no sessions needed)
const displayMessage = params.context ? `${params.context}\n\n${params.message}` : params.message;
this.debugLogger.log('TOOL', 'Displaying message in chat UI:', displayMessage);
// Emit event to show message in chat UI immediately
this.emit('human-agent-request', {
requestId,
message: params.message,
context: params.context,
priority: params.priority || 'normal',
timestamp: new Date().toISOString()
});
// Wait for human response
return new Promise((resolve) => {
// Set up timeout
const timeoutHandle = setTimeout(() => {
this.pendingHumanRequests.delete(requestId);
this.debugLogger.log('TOOL', `Request ${requestId} timed out after ${timeout/1000}s`);
resolve({
id: messageId,
type: 'response',
error: {
code: -32603,
message: `Human response timeout after ${params.timeout || 300} seconds`
}
});
}, timeout);
// Store the pending request
this.pendingHumanRequests.set(requestId, {
resolve: (response: string) => {
clearTimeout(timeoutHandle);
const responseTime = Date.now() - startTime;
this.debugLogger.log('TOOL', `Request ${requestId} completed with response:`, response);
const result: HumanAgentChatToolResult = {
content: [{
type: 'text',
text: response
}]
};
resolve({
id: messageId,
type: 'response',
result
});
},
reject: (error: Error) => {
clearTimeout(timeoutHandle);
this.debugLogger.log('TOOL', `Request ${requestId} rejected:`, error);
resolve({
id: messageId,
type: 'response',
error: {
code: -32603,
message: error.message
}
});
},
startTime,
params
});
this.debugLogger.log('TOOL', `Request ${requestId} waiting for human response...`);
});
}
// Method to handle human responses (called by webview)
public respondToHumanRequest(requestId: string, response: string): boolean {
this.debugLogger.log('SERVER', `Received human response for request ${requestId}:`, response);
const pendingRequest = this.pendingHumanRequests.get(requestId);
if (pendingRequest) {
this.pendingHumanRequests.delete(requestId);
pendingRequest.resolve(response);
return true;
}
this.debugLogger.log('SERVER', `No pending request found for ID: ${requestId}`);
return false;
}
// Simplified API - no sessions needed
getAvailableTools(): McpTool[] {
return Array.from(this.tools.values());
}
getPendingRequests(): Array<{id: string, params: HumanAgentChatToolParams, startTime: number}> {
return Array.from(this.pendingHumanRequests.entries()).map(([id, req]) => ({
id,
params: req.params,
startTime: req.startTime
}));
}
// Method to manually resolve a pending request (for testing)
resolvePendingRequest(requestId: string, response: string): boolean {
const request = this.pendingHumanRequests.get(requestId);
if (request) {
this.pendingHumanRequests.delete(requestId);
request.resolve(response);
return true;
}
return false;
}
isServerRunning(): boolean {
return this.isRunning;
}
getServerUrl(): string {
return `http://127.0.0.1:${this.port}/mcp`;
}
getPort(): number {
return this.port;
}
}
+64
View File
@@ -0,0 +1,64 @@
export interface McpMessage {
id: string;
type: 'request' | 'response' | 'notification';
method?: string;
params?: any;
result?: any;
error?: {
code: number;
message: string;
data?: any;
};
}
export interface ChatMessage {
id: string;
sender: 'user' | 'agent';
content: string;
timestamp: Date;
type: 'text' | 'system';
}
export interface McpServerConfig {
name: string;
description: string;
version: string;
capabilities: {
chat: boolean;
tools: boolean;
resources: boolean;
};
}
export interface HumanAgentSession {
id: string;
name: string;
isActive: boolean;
lastActivity: Date;
messages: ChatMessage[];
}
export interface McpTool {
name: string;
description: string;
inputSchema: {
type: string;
properties: Record<string, any>;
required?: string[];
};
}
export interface HumanAgentChatToolParams {
message: string;
context?: string;
sessionId?: string;
priority?: 'low' | 'normal' | 'high' | 'urgent';
timeout?: number;
}
export interface HumanAgentChatToolResult {
content: Array<{
type: 'text';
text: string;
}>;
}
+56
View File
@@ -0,0 +1,56 @@
import * as vscode from 'vscode';
export class ChatTreeProvider implements vscode.TreeDataProvider<ChatTreeItem> {
private _onDidChangeTreeData: vscode.EventEmitter<ChatTreeItem | undefined | null | void> = new vscode.EventEmitter<ChatTreeItem | undefined | null | void>();
readonly onDidChangeTreeData: vscode.Event<ChatTreeItem | undefined | null | void> = this._onDidChangeTreeData.event;
private hasActiveChat: boolean = false;
constructor() {}
refresh(): void {
this._onDidChangeTreeData.fire();
}
updateActiveChat(isActive: boolean): void {
this.hasActiveChat = isActive;
this.refresh();
}
getTreeItem(element: ChatTreeItem): vscode.TreeItem {
return element;
}
getChildren(element?: ChatTreeItem): Thenable<ChatTreeItem[]> {
if (!element) {
// Root level - return chat status
const chatItem = new ChatTreeItem(
this.hasActiveChat ? 'HumanAgent Chat (Active)' : 'HumanAgent Chat',
'chat',
vscode.TreeItemCollapsibleState.None,
'chat',
{
command: 'humanagent-mcp.openChat',
title: 'Open Chat',
arguments: []
}
);
return Promise.resolve([chatItem]);
}
return Promise.resolve([]);
}
}
export class ChatTreeItem extends vscode.TreeItem {
constructor(
public readonly label: string,
public readonly itemId: string,
public readonly collapsibleState: vscode.TreeItemCollapsibleState,
public readonly contextValue: string,
public readonly command?: vscode.Command
) {
super(label, collapsibleState);
this.tooltip = `${this.label}`;
this.description = contextValue === 'chat' ? 'MCP Communication' : '';
}
}
+15
View File
@@ -0,0 +1,15 @@
import * as assert from 'assert';
// You can import and use all API from the 'vscode' module
// as well as import your extension to test it
import * as vscode from 'vscode';
// import * as myExtension from '../../extension';
suite('Extension Test Suite', () => {
vscode.window.showInformationMessage('Start all tests.');
test('Sample test', () => {
assert.strictEqual(-1, [1, 2, 3].indexOf(5));
assert.strictEqual(-1, [1, 2, 3].indexOf(0));
});
});
+466
View File
@@ -0,0 +1,466 @@
import * as vscode from 'vscode';
import { McpServer } from '../mcp/server';
import { ChatMessage } from '../mcp/types';
import { McpConfigManager } from '../mcp/mcpConfigManager';
export class ChatWebviewProvider implements vscode.WebviewViewProvider {
public static readonly viewType = 'humanagent-mcp.chatView';
private _view?: vscode.WebviewView;
private mcpServer: McpServer;
private mcpConfigManager?: McpConfigManager;
private extensionPath: string;
private messages: ChatMessage[] = [];
private currentRequestId?: string;
constructor(
private readonly _extensionUri: vscode.Uri,
mcpServer: McpServer,
mcpConfigManager?: McpConfigManager
) {
this.mcpServer = mcpServer;
this.mcpConfigManager = mcpConfigManager;
this.extensionPath = _extensionUri.fsPath;
}
public displayHumanAgentMessage(message: string, context?: string, requestId?: string) {
// Store the current request ID for response handling
this.currentRequestId = requestId;
// Combine context and message if context exists
const fullMessage = context ? `${context}\n\n${message}` : message;
// Add AI message to chat
const aiMessage: ChatMessage = {
id: Date.now().toString(),
content: fullMessage,
sender: 'agent',
timestamp: new Date(),
type: 'text'
};
this.messages.push(aiMessage);
this.updateWebview();
// Focus the chat webview
if (this._view) {
this._view.show?.(true);
}
}
resolveWebviewView(webviewView: vscode.WebviewView, context: vscode.WebviewViewResolveContext, _token: vscode.CancellationToken) {
this._view = webviewView;
webviewView.webview.options = {
enableScripts: true,
localResourceRoots: [
this._extensionUri
]
};
this.updateWebview();
webviewView.webview.onDidReceiveMessage(async (data) => {
switch (data.type) {
case 'sendMessage':
await this.sendHumanResponse(data.content);
break;
case 'mcpAction':
await this.handleMcpAction(data.action);
break;
case 'requestServerStatus':
this.updateServerStatus();
break;
}
});
}
private async sendHumanResponse(content: string) {
try {
console.log('ChatWebviewProvider: Sending human response:', content);
// Add human message to chat
const humanMessage: ChatMessage = {
id: Date.now().toString(),
content: content,
sender: 'user',
timestamp: new Date(),
type: 'text'
};
this.messages.push(humanMessage);
this.updateWebview();
// Send response back to MCP server
if (this.currentRequestId) {
console.log('ChatWebviewProvider: Responding to request ID:', this.currentRequestId);
this.mcpServer.respondToHumanRequest(this.currentRequestId, content);
this.currentRequestId = undefined;
}
} catch (error) {
console.error('ChatWebviewProvider: Error in sendHumanResponse:', error);
}
}
public async waitForHumanResponse(): Promise<string> {
// This method is no longer needed since we use direct callbacks
throw new Error('waitForHumanResponse is deprecated - use direct response handling');
}
private updateWebview() {
if (this._view) {
this._view.webview.html = this._getHtmlForWebview(this._view.webview);
}
}
private updateServerStatus() {
if (!this._view) {
return;
}
const tools = this.mcpServer.getAvailableTools();
const pendingRequests = this.mcpServer.getPendingRequests();
const isRegistered = this.mcpConfigManager?.isMcpServerRegistered() ?? false;
this._view.webview.postMessage({
type: 'serverStatus',
data: {
running: true,
tools: tools.length,
pendingRequests: pendingRequests.length,
registered: isRegistered
}
});
}
private async handleMcpAction(action: string) {
try {
switch (action) {
case 'start':
await this.mcpServer.start();
vscode.window.showInformationMessage('MCP Server started');
break;
case 'stop':
await this.mcpServer.stop();
vscode.window.showInformationMessage('MCP Server stopped');
break;
case 'restart':
await this.mcpServer.stop();
await this.mcpServer.start();
vscode.window.showInformationMessage('MCP Server restarted');
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');
break;
case 'configure':
vscode.commands.executeCommand('humanagent-mcp.configureMcp');
break;
}
// Update status after action
this.updateServerStatus();
} catch (error) {
vscode.window.showErrorMessage(`MCP action failed: ${error instanceof Error ? error.message : String(error)}`);
}
}
private _getHtmlForWebview(webview: vscode.Webview) {
const messagesHtml = this.messages.map(message => {
const messageClass = message.sender === 'agent' ? 'ai-message' : 'human-message';
const timestamp = message.timestamp.toLocaleTimeString();
const senderLabel = message.sender === 'agent' ? 'AI' : 'Human';
return `
<div class="message ${messageClass}">
<div class="message-header">
<span class="sender">${senderLabel}</span>
<span class="timestamp">${timestamp}</span>
</div>
<div class="message-content">${this._escapeHtml(String(message.content || ''))}</div>
</div>
`;
}).join('');
const hasPendingResponse = this.currentRequestId ? 'waiting' : '';
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HumanAgent Chat</title>
<style>
body {
font-family: var(--vscode-font-family);
font-size: var(--vscode-font-size);
line-height: 1.4;
color: var(--vscode-foreground);
background-color: var(--vscode-editor-background);
margin: 0;
padding: 0;
height: 100vh;
display: flex;
flex-direction: column;
}
.header {
padding: 10px;
border-bottom: 1px solid var(--vscode-panel-border);
background-color: var(--vscode-panel-background);
}
.status {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.status-indicator {
display: flex;
align-items: center;
gap: 5px;
}
.status-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background-color: var(--vscode-charts-green);
}
.control-buttons {
display: flex;
gap: 5px;
}
.cog-button {
padding: 4px 8px;
font-size: 14px;
background-color: var(--vscode-button-background);
color: var(--vscode-button-foreground);
border: none;
border-radius: 3px;
cursor: pointer;
}
.cog-button:hover {
background-color: var(--vscode-button-hoverBackground);
}
.control-button {
padding: 4px 8px;
font-size: 11px;
background-color: var(--vscode-button-background);
color: var(--vscode-button-foreground);
border: none;
border-radius: 3px;
cursor: pointer;
}
.control-button:hover {
background-color: var(--vscode-button-hoverBackground);
}
.messages {
flex: 1;
overflow-y: auto;
padding: 10px;
}
.message {
margin-bottom: 15px;
padding: 10px;
border-radius: 5px;
border-left: 3px solid;
}
.ai-message {
background-color: var(--vscode-editor-selectionBackground);
border-left-color: var(--vscode-charts-blue);
}
.human-message {
background-color: var(--vscode-editor-hoverHighlightBackground);
border-left-color: var(--vscode-charts-green);
}
.message-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 5px;
font-size: 12px;
opacity: 0.8;
}
.sender {
font-weight: bold;
}
.timestamp {
font-size: 11px;
}
.message-content {
white-space: pre-wrap;
word-wrap: break-word;
}
.input-area {
padding: 10px;
border-top: 1px solid var(--vscode-panel-border);
background-color: var(--vscode-panel-background);
}
.input-container {
display: flex;
gap: 5px;
}
.message-input {
flex: 1;
padding: 8px;
border: 1px solid var(--vscode-input-border);
background-color: var(--vscode-input-background);
color: var(--vscode-input-foreground);
border-radius: 3px;
font-family: inherit;
font-size: inherit;
}
.send-button {
padding: 8px 16px;
background-color: var(--vscode-button-background);
color: var(--vscode-button-foreground);
border: none;
border-radius: 3px;
cursor: pointer;
}
.send-button:hover {
background-color: var(--vscode-button-hoverBackground);
}
.send-button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.waiting-indicator {
text-align: center;
padding: 10px;
font-style: italic;
color: var(--vscode-descriptionForeground);
}
.empty-state {
text-align: center;
padding: 20px;
color: var(--vscode-descriptionForeground);
}
</style>
</head>
<body>
<div class="header">
<div class="status">
<div class="status-indicator">
<div class="status-dot"></div>
<span>HumanAgent MCP Server</span>
</div>
<div class="control-buttons">
<button class="control-button" onclick="requestServerStatus()">Status</button>
<button class="cog-button" onclick="showConfigMenu()" title="Configure MCP">⚙️</button>
</div>
</div>
</div>
<div class="messages" id="messages">
${messagesHtml || '<div class="empty-state">Waiting for AI messages...</div>'}
${hasPendingResponse ? '<div class="waiting-indicator">⏳ Waiting for your response...</div>' : ''}
</div>
<div class="input-area">
<div class="input-container">
<input type="text" class="message-input" id="messageInput" placeholder="Type your response..." ${hasPendingResponse ? '' : 'disabled'}>
<button class="send-button" id="sendButton" onclick="sendMessage()" ${hasPendingResponse ? '' : 'disabled'}>Send</button>
</div>
</div>
<script>
const vscode = acquireVsCodeApi();
document.getElementById('messageInput').addEventListener('keypress', function(e) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
sendMessage();
}
});
function showConfigMenu() {
vscode.postMessage({
type: 'mcpAction',
action: 'configure'
});
}
function sendMessage() {
const input = document.getElementById('messageInput');
const message = input.value.trim();
if (message) {
vscode.postMessage({
type: 'sendMessage',
content: message
});
input.value = '';
}
}
function handleMcpAction(action) {
vscode.postMessage({
type: 'mcpAction',
action: action
});
}
function requestServerStatus() {
vscode.postMessage({
type: 'requestServerStatus'
});
}
// Auto-scroll to bottom
const messagesContainer = document.getElementById('messages');
messagesContainer.scrollTop = messagesContainer.scrollHeight;
// Listen for server status updates
window.addEventListener('message', event => {
const message = event.data;
if (message.type === 'serverStatus') {
// Could update UI with server status if needed
console.log('Server status:', message.data);
}
});
</script>
</body>
</html>
`;
}
private _escapeHtml(text: string): string {
if (typeof text !== 'string') {
text = String(text || '');
}
return text
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
}
+16
View File
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"module": "Node16",
"target": "ES2022",
"lib": [
"ES2022"
],
"sourceMap": true,
"rootDir": "src",
"strict": true, /* enable all strict type-checking options */
/* Additional Checks */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
}
}
+48
View File
@@ -0,0 +1,48 @@
# Welcome to your VS Code Extension
## What's in the folder
* This folder contains all of the files necessary for your extension.
* `package.json` - this is the manifest file in which you declare your extension and command.
* The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesnt yet need to load the plugin.
* `src/extension.ts` - this is the main file where you will provide the implementation of your command.
* The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`.
* We pass the function containing the implementation of the command as the second parameter to `registerCommand`.
## Setup
* install the recommended extensions (amodio.tsl-problem-matcher, ms-vscode.extension-test-runner, and dbaeumer.vscode-eslint)
## Get up and running straight away
* Press `F5` to open a new window with your extension loaded.
* Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`.
* Set breakpoints in your code inside `src/extension.ts` to debug your extension.
* Find output from your extension in the debug console.
## Make changes
* You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`.
* You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes.
## Explore the API
* You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`.
## Run tests
* Install the [Extension Test Runner](https://marketplace.visualstudio.com/items?itemName=ms-vscode.extension-test-runner)
* Run the "watch" task via the **Tasks: Run Task** command. Make sure this is running, or tests might not be discovered.
* Open the Testing view from the activity bar and click the Run Test" button, or use the hotkey `Ctrl/Cmd + ; A`
* See the output of the test result in the Test Results view.
* Make changes to `src/test/extension.test.ts` or create new test files inside the `test` folder.
* The provided test runner will only consider files matching the name pattern `**.test.ts`.
* You can create folders inside the `test` folder to structure your tests any way you want.
## Go further
* Reduce the extension size and improve the startup time by [bundling your extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension).
* [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VS Code extension marketplace.
* Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration).
+84
View File
@@ -0,0 +1,84 @@
//@ts-check
'use strict';
const path = require('path');
//@ts-check
/** @typedef {import('webpack').Configuration} WebpackConfig **/
/** @type WebpackConfig */
const extensionConfig = {
target: 'node', // VS Code extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/
mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
entry: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/
output: {
// the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/
path: path.resolve(__dirname, 'dist'),
filename: 'extension.js',
libraryTarget: 'commonjs2'
},
externals: {
vscode: 'commonjs vscode' // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/
// modules added here also need to be added in the .vscodeignore file
},
resolve: {
// support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader
extensions: ['.ts', '.js']
},
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
use: [
{
loader: 'ts-loader'
}
]
}
]
},
devtool: 'nosources-source-map',
infrastructureLogging: {
level: "log", // enables logging required for problem matchers
},
};
/** @type WebpackConfig */
const mcpServerConfig = {
target: 'node',
mode: 'none',
entry: './src/mcp/mcpStandalone.ts',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'mcpStandalone.js',
libraryTarget: 'commonjs2'
},
externals: {
vscode: 'commonjs vscode'
},
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
use: [
{
loader: 'ts-loader'
}
]
}
]
},
devtool: 'nosources-source-map',
infrastructureLogging: {
level: "log",
},
};
module.exports = [ extensionConfig, mcpServerConfig ];