* Upgrade bundled Laravel from 12 to 13 (#220)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(mcp): add Model Context Protocol server implementation
- Add MCP server with connection manager and router for handling protocol requests
- Implement execution history tracking with SQLite database migration
- Add MCP tools: execute-php, execute-with-loader, get-execution-history, get-php-info, switch-connection
- Create comprehensive MCP documentation: API, configuration, setup guide, troubleshooting, and implementation summary
- Add error handling and logging infrastructure for MCP operations
- Integrate MCP settings UI component in SettingsView
- Add @modelcontextprotocol/sdk dependency (^1.22.0)
- Update build configuration to externalize cpu-features dependency
- Add .kiro directory to .gitignore
- Include test-mcp-connection.js for connection validation
- Enable AI assistants to execute PHP code and manage database connections through standardized protocol
* chore(mcp): remove MCP documentation files
- Delete API.md documentation file
- Delete CONFIGURATION.md documentation file
- Delete ERROR_HANDLING.md documentation file
- Delete IMPLEMENTATION_SUMMARY.md documentation file
- Delete INDEX.md documentation file
- Delete README.md documentation file
- Delete SETUP_GUIDE.md documentation file
- Delete TROUBLESHOOTING.md documentation file
- Update test-mcp-connection.js with latest changes
- Consolidate MCP documentation into main project documentation
* fix(mcp): replace custom HTTP server with official MCP SDK transport
The previous implementation used a custom {tool, parameters} HTTP
protocol incompatible with MCP JSON-RPC 2.0. Clients were also
instructed to connect via `command: node -e <script>`, which fails
on machines without system Node.js installed.
- Replace server.ts with McpServer + StreamableHTTPServerTransport
from @modelcontextprotocol/sdk (already in dependencies)
- Register all 5 tools using mcpServer.tool() with Zod schemas
- Use stateless transport mode (no session management needed)
- Delete router.ts (replaced by SDK tool registration)
- Delete example-usage.ts (unused)
- Trim MCPToolRequest/MCPToolResponse from types.ts (no longer needed)
- Update MCPSettings.vue to show correct HTTP URL config snippet
Clients now connect with no system Node required:
{ "url": "http://127.0.0.1:3000/mcp", "type": "http" }
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(mcp): correct stateless transport pattern per SDK spec
- Create fresh McpServer + StreamableHTTPServerTransport per POST request
(matches the SDK stateless example - per-request lifecycle)
- Pre-parse request body and pass as third arg to transport.handleRequest
- GET/DELETE /mcp now return 405 (no SSE stream in stateless mode)
- Shared state (ConnectionManager, ExecutionHistoryDB, handlers) stays on
MCPServerImpl and is accessed via closure from each per-request server
- Call closeAllConnections() on stop() to prevent EADDRINUSE on restart
- Clean up transport + server on res.close
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(mcp): fix three bugs blocking execute_php and execute_with_loader
1. PHP version/phar mismatch: getLocalPharClient() now falls back to the
highest available phar (client-8.4.phar) when the exact version for
the installed PHP (e.g. 8.5) doesn't exist.
2. Loader arg sent to phar: standard loader names ('laravel', 'symfony')
were passed as --loader=<base64> to the phar, causing it to eval the
decoded string as PHP and fail with a parse error. The phar auto-detects
laravel/symfony from the project path — only custom loaders need --loader.
3. SQLite object binding: phar output is TWEAKPHP_RESULT:{...json...}.
After JSON.parse() the result becomes a JS object, which better-sqlite3
cannot bind (RangeError: Too few parameter values were provided). Fixed
by stringifying the output before the DB insert in both handlers.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: regenerate package-lock.json after rebase on main
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: regenerate package-lock.json after rebase on upstream/main
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(mcp): address Copilot review comments
- CORS: restrict Access-Control-Allow-Origin to /health only; /mcp
should not be callable from arbitrary websites (CSRF risk)
- switch-connection: align kubectl validation with actual type (pod,
not pod_name/deployment_name); require container_name for Docker
- server: register res.on('close') cleanup before handleRequest to
avoid missing early close events
- server: clear timeout flag on clean shutdown to prevent spurious
'Forcing shutdown' log on normal stop
- error-handler: only treat objects as MCPError when code is a known
MCPErrorCode value (prevents Node EADDRINUSE etc. from bypassing
error classification)
- MCPSettings: coerce mcpPort to number with bounds check; send
mcp.settings-changed on port change so server restarts with new port
- index: restart running server on settings-changed to pick up config
changes (e.g. port)
- local.ts: use path.join for baseDir (cross-platform path separators)
- test-mcp-connection.js: fix payload to use JSON-RPC tools/call format
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(mcp): implement deferred Copilot review items
- execute-php/execute-with-loader: type output as unknown in result
interfaces and local variable — JSON.parse can return any type
- execute-with-loader: detectFramework and validateFrameworkPath now
skip local fs.existsSync checks for non-local connections (docker,
ssh, kubectl, vapor) where the path refers to a remote filesystem
- execute-with-loader: pass params.projectPath to client.execute() so
an explicit project path is honoured rather than silently ignored
- client.base/local/docker/ssh/kubectl/vapor: add optional projectPath
param to execute() — each client uses it to override the connection's
default project path when provided
- server: enforce 1 MB body size limit on POST /mcp requests (413
response + req.destroy() on overflow)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(client): add projectPath param to Client interface
Keeps the interface in sync with the updated execute() signature in
client.base.ts and all concrete implementations.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: address remaining Copilot review items
preload.ts:
- Store IPC listener wrappers in a Map keyed by original callback so
that removeListener(channel, callback) can find and remove the
correct wrapper function — previously the wrapper was a fresh
anonymous function each time so removeListener was a no-op
- Remove duplicate invoke property from IpcRenderer interface and
implementation (caused TS2300 duplicate identifier errors)
settings.ts / MCPSettings.vue:
- Add ipcMain.handle('settings.save') — awaitable counterpart to the
fire-and-forget 'settings.store' channel
- mcpEnabled setter now awaits invoke('settings.save') before sending
'mcp.settings-changed', guaranteeing settings are written to disk
before the main process reads them to start/stop the MCP server
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(mcp): send 413 response before destroying socket; fix test Accept header
server.ts: req.destroy() was called before res.end(), so the 413
response never reached the client. Now the response is flushed first
and req.destroy() is called in the res.end() callback.
test-mcp-connection.js: add Accept: application/json, text/event-stream
header — required by StreamableHTTPServerTransport (SDK enforces this
on POST /mcp requests).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix code style issues with Prettier
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: implement tab close request handling and add CloseTabModal component
* feat(mcp): add list_connections tool to MCP server
* fix(mcp): use settings.laravelPath for local connection default path
* fix(mcp): ensure project path falls back to settings.laravelPath across tool handlers
* style: apply prettier formatting to codebase
* fix(ci): add rollup linux binaries to optionalDependencies for CI build compatibility
* fix(ci): add rollup windows binaries to optionalDependencies
---------
Co-authored-by: Saeed Vaziry <61919774+saeedvaziry@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: David Galet <davidgalet@gmail.com>
Summary
🤖 Generated with Claude Code