| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Sorry, something went wrong.
|
Thanks for the PR. I believe the MD files can be on the documentation instead of the code |
Sorry, something went wrong.
Documentation PR: tweakphp/docs#7 |
Sorry, something went wrong.
|
Thank you very much for your work. As soon as I have a free moment, I'll get started on the review! |
Sorry, something went wrong.
2025-12-06T11:51:14.084Z [tweakphp] [info] Initializing server... { metadata: undefined }
2025-12-06T11:51:14.090Z [tweakphp] [info] Using MCP server command: node with args and path: {
metadata: {
args: [
'-e',
"require('http').request({host:'127.0.0.1',port:3000,method:'POST',path:'/mcp'},r=>{let d='';r.on('data',c=>d+=c);r.on('end',()=>console.log(d))}).end(JSON.stringify(process.argv[2]))",
[length]: 2
],
paths: [
'/usr/local/bin',
'/opt/homebrew/bin',
'/usr/bin',
'/bin',
'/usr/sbin',
'/sbin',
[length]: 6
]
}
} %o
2025-12-06T11:51:14.091Z [tweakphp] [info] Server started and connected successfully { metadata: undefined }
Failed to spawn process: No such file or directory
2025-12-06T11:51:14.094Z [tweakphp] [info] Server transport closed { metadata: undefined }
2025-12-06T11:51:14.094Z [tweakphp] [info] Client transport closed { metadata: undefined }
2025-12-06T11:51:14.095Z [tweakphp] [info] Server transport closed unexpectedly, this is likely due to the process exiting early. If you are developing this MCP server you can add output to stderr (i.e. `console.error('...')` in JavaScript, `print('...', file=sys.stderr)` in python) and it will appear in this log. { metadata: undefined }
2025-12-06T11:51:14.095Z [tweakphp] [error] Server disconnected. For troubleshooting guidance, please visit our [debugging documentation](https://modelcontextprotocol.io/docs/tools/debugging) { metadata: { context: 'connection', stack: undefined } }
2025-12-06T11:51:14.095Z [tweakphp] [info] Client transport closed { metadata: undefined }
|
Sorry, something went wrong.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause analysis & fixesAfter testing on a machine with PHP 8.5, three bugs were found and fixed in feature/mcp-server: Bug 1 — PHP version / phar mismatch (src/main/client/local.ts)getLocalPharClient() was constructing the phar path as client-{phpVersion}.phar and returning it unconditionally. On PHP 8.5 client-8.5.phar doesn't exist (only client-8.4.phar ships), so execution failed silently. Fix: check whether the exact-version phar exists first; if not, fall back to the highest-versioned phar available in the public/ directory. Bug 2 — Standard loader name passed as --loader arg (src/main/mcp/tools/execute-with-loader.ts)execute_with_loader was calling client.execute(params.code, params.loader) which forwarded 'laravel' or 'symfony' as --loader=bGFyYXZlbA== (base64) to the phar. The phar's --loader flag expects a base64-encoded PHP class for custom loaders — it decodes and evals the value. Evaluating the string "laravel" as PHP caused a parse error. The phar already auto-detects Laravel/Symfony by checking for artisan / bin/console in the project path, so --loader should not be passed for standard frameworks. Fix: only forward the loader arg for non-standard (custom) loaders: const standardLoaders = ['laravel', 'symfony']
const loaderArg = standardLoaders.includes(params.loader) ? undefined : params.loader
client.execute(params.code, loaderArg)Bug 3 — SQLite object binding (execute-php.ts and execute-with-loader.ts)Phar output format is TWEAKPHP_RESULT:{...json...}. After JSON.parse() the output variable becomes a JavaScript object. better-sqlite3 only accepts null / number / string / Buffer as bound parameters — passing a JS object throws: RangeError: Too few parameter values were provided This surfaced as execute_php always returning {"error":"Too few parameter values were provided"}. Fix: stringify before the DB insert: output: typeof output === 'string' ? output : JSON.stringify(output)TestingAfter all three fixes, end-to-end MCP tests pass on PHP 8.5 (local connection):
|
Sorry, something went wrong.
- 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
- 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
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>
- 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>
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>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Adds a Model Context Protocol (MCP) HTTP server inside the Electron main process, plus a renderer settings UI to enable/monitor it, and an execution-history SQLite table to persist tool runs.
Changes:
Copilot reviewed 26 out of 27 changed files in this pull request and generated 19 comments.
Show a summary per file| File | Description |
|---|---|
| test-mcp-connection.js | Adds a local script intended to validate MCP connectivity. |
| src/types/settings.type.ts | Extends app settings with MCP enablement + port fields. |
| src/renderer/views/settings/MCPSettings.vue | Adds settings UI for enabling MCP server, configuring port, and displaying status. |
| src/renderer/views/SettingsView.vue | Wires MCP settings tab into Settings view. |
| src/renderer/stores/settings.ts | Adds defaults for MCP settings in renderer store. |
| src/renderer/components/Container.vue | Adjusts container scrolling behavior. |
| src/renderer/assets/main.css | Adds global scrollbar styling and some react-flow control styles. |
| src/preload/preload.ts | Extends exposed IPC bridge with invoke. |
| src/main/settings.ts | Adds MCP fields to main-process settings defaults and persistence. |
| src/main/mcp/types.ts | Introduces MCP types (config/status/errors). |
| src/main/mcp/tools/schemas.ts | Defines parameter types for MCP tools. |
| src/main/mcp/tools/index.ts | Exports MCP tool handlers/schemas. |
| src/main/mcp/tools/execute-php.ts | Implements PHP execution tool with history tracking and error handling. |
| src/main/mcp/tools/execute-with-loader.ts | Implements framework-loader execution tool with history tracking and error handling. |
| src/main/mcp/tools/get-execution-history.ts | Implements querying execution history via MCP. |
| src/main/mcp/tools/get-php-info.ts | Implements PHP info retrieval via MCP. |
| src/main/mcp/tools/switch-connection.ts | Implements switching/creating execution connections via MCP. |
| src/main/mcp/server.ts | Implements HTTP MCP server endpoint + per-request MCP server instances. |
| src/main/mcp/index.ts | Adds Electron IPC handlers and auto-start/stop behavior driven by settings. |
| src/main/mcp/execution-history-db.ts | Adds SQLite helper for execution history CRUD/querying. |
| src/main/mcp/error-logger.ts | Adds log file writer/rotation for MCP errors/info/warnings. |
| src/main/mcp/error-handler.ts | Adds MCP error classification, retry, timeout, and troubleshooting helpers. |
| src/main/mcp/connection-manager.ts | Adds MCP-focused connection manager mapping to existing clients. |
| src/main/main.ts | Initializes MCP module and stops MCP server during app shutdown. |
| src/main/client/local.ts | Updates local client phar resolution and fallback logic. |
| package.json | Adds @modelcontextprotocol/sdk dependency; bumps glob. |
| package-lock.json | Locks new dependency graph for MCP SDK + updated packages. |
| migrations/002_create_execution_history_table.sql | Adds execution history schema + indexes. |
| build.js | Externalizes cpu-features in the build bundle. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
- 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>
- 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>
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>
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>
… 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>
|
@escapeboy I see you're boosting a server for the MCP which means the app needs to be open to work. I was thinking to make it a command based MCP so user doesn't need to have tweakphp open to interact with the mcp. |
Sorry, something went wrong.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Probably it is solution but I had some issues with Cursor and Kiro with their command way but using the MCP server was working perfectly without crashing. I had moved to Claude and don't have such issues anymore, but still decided to implement it for the community. |
Sorry, something went wrong.
|
@luanfreitasdev Hi! I've updated this branch with the latest changes from the main branch. I've also added a new tool called list-connections. I've included some additional fixes and moved the logging logic. Do you have the time and opportunity to give it a test run? I tried connecting it to Antigravity, and it works without any problems. Tks! A big thank you also to @escapeboy. |
Sorry, something went wrong.
There was a problem hiding this comment.
Sorry, something went wrong.
|
Okay, great! So I'll try building this branch directly from the workflow. Then I'll push it to main. Thanks, everyone! |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Documentation PR: tweakphp/docs#7