Skip to content

Commit db87dc9

Browse files
committed
Change default MCP transport from stdio to driver. (#38)
Fresh installs now use in-process Bolt without the neo4j-mcp binary. Update setup messaging, env example, changelog, and README with a table of contents for quicker navigation.
1 parent f70dd9e commit db87dc9

8 files changed

Lines changed: 68 additions & 25 deletions

File tree

.env.example

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ APP_DEBUG=true
77
APP_KEY=
88

99
# Neo4j MCP transport mode:
10-
# - stdio (default): runs the local neo4j-mcp binary.
10+
# - driver (default): in-process Bolt via laudis/neo4j-php-client — no neo4j-mcp binary required.
11+
# - stdio: runs the local neo4j-mcp binary (set NEO4J_MCP_TRANSPORT=stdio).
1112
# - http: use when the MCP server runs elsewhere and NEO4J_MCP_URL points to it.
12-
NEO4J_MCP_TRANSPORT=stdio
13+
# NEO4J_MCP_TRANSPORT=driver
1314

14-
# Neo4j database credentials (required for STDIO mode — passed to the neo4j-mcp subprocess)
15+
# Neo4j database credentials (used by driver, stdio, and container:graph)
1516
NEO4J_URI=bolt://localhost:7687
1617
NEO4J_USERNAME=neo4j
1718
NEO4J_PASSWORD=

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- Default `NEO4J_MCP_TRANSPORT` is now **`driver`** (in-process Bolt) instead of `stdio`. Set `NEO4J_MCP_TRANSPORT=stdio` explicitly to use the `neo4j-mcp` binary.
13+
1014
## [1.0.0] - 2026-07-06
1115

1216
### Added

config/neo4j-boost.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@
88
|
99
| How this package talks to the Neo4j MCP server:
1010
|
11-
| - http : Connect to a remote MCP server over HTTP (e.g. a separate
12-
| neo4j-mcp process or container). Set NEO4J_MCP_TRANSPORT=http
13-
| and configure the "http" section below.
11+
| - driver : Run MCP tools in PHP via laudis/neo4j-php-client (Bolt). No
12+
| neo4j-mcp binary required. This is the default. Set
13+
| NEO4J_URI / NEO4J_USERNAME / NEO4J_PASSWORD (or DSN).
1414
|
1515
| - stdio : Run the MCP server as a subprocess and talk over stdin/stdout.
1616
| Set NEO4J_MCP_TRANSPORT=stdio and configure the "stdio" section.
1717
| The subprocess receives NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD
1818
| from transport.stdio.env so it can connect to Neo4j.
1919
|
20-
| - driver : Run MCP tools in PHP via laudis/neo4j-php-client (Bolt). No
21-
| neo4j-mcp binary required. Set NEO4J_MCP_TRANSPORT=driver and
22-
| NEO4J_URI / NEO4J_USERNAME / NEO4J_PASSWORD (or DSN).
20+
| - http : Connect to a remote MCP server over HTTP (e.g. a separate
21+
| neo4j-mcp process or container). Set NEO4J_MCP_TRANSPORT=http
22+
| and configure the "http" section below.
2323
|
2424
*/
2525
'transport' => [

resources/boost/guidelines/core.blade.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,18 @@
22

33
This package integrates the official [Neo4j MCP](https://github.com/neo4j/mcp/releases) server into Laravel so you can use Neo4j tools from MCP clients (Cursor, Claude, etc.).
44

5+
### Index
6+
7+
- [Transport modes](#transport-modes)
8+
- [Cursor config](#cursor-config)
9+
- [Run the MCP server](#run-the-mcp-server)
10+
- [Config](#config)
11+
- [Container graph POC](#container-graph-poc)
12+
- [Cursor: "Loading tools" stuck or HTTP 404](#cursor-loading-tools-stuck-or-http-404)
13+
514
### Transport modes
615

7-
The package supports **STDIO** (default — local `neo4j-mcp` binary), **HTTP** (remote MCP server), and **driver** (in-process Bolt via `NEO4J_MCP_TRANSPORT=driver`). For HTTP-only setups, run the Neo4j MCP server elsewhere (e.g. Docker) with HTTP transport, then set in `.env`:
16+
The package supports **driver** (default — in-process Bolt via `laudis/neo4j-php-client`, no `neo4j-mcp` binary), **STDIO** (`NEO4J_MCP_TRANSPORT=stdio` — local `neo4j-mcp` binary), and **HTTP** (remote MCP server). For HTTP-only setups, run the Neo4j MCP server elsewhere (e.g. Docker) with HTTP transport, then set in `.env`:
817

918
```env
1019
NEO4J_MCP_URL=http://localhost:8080/mcp
@@ -24,7 +33,7 @@
2433

2534
### Run the MCP server
2635

27-
- **With Laravel Boost:** Use a single MCP server: run `php artisan boost:mcp`. This package adds the official Neo4j tools (get-schema, read-cypher, write-cypher, list-gds-procedures, **get-class-dependency-graph**, **contribute-graph-knowledge**) to Boost’s server automatically. Tools call the HTTP MCP URL from `config/neo4j-boost.http` except **get-class-dependency-graph** and **contribute-graph-knowledge**, which read/write the container graph directly from Neo4j using `config/neo4j-boost.container_graph`.
36+
- **With Laravel Boost:** Use a single MCP server: run `php artisan boost:mcp`. This package adds the official Neo4j tools (get-schema, read-cypher, write-cypher, list-gds-procedures, **get-class-dependency-graph**, **contribute-graph-knowledge**) to Boost’s server automatically. By default, tools use **driver** transport (Bolt in PHP). Set `NEO4J_MCP_TRANSPORT=http` or `stdio` to change that. **get-class-dependency-graph** and **contribute-graph-knowledge** always read/write the container graph directly from Neo4j using `config/neo4j-boost.container_graph`.
2837
- **Without Boost:** Add the Neo4j MCP server to Cursor as an HTTP server. Run `php artisan neo4j-boost:cursor-config` so `.cursor/mcp.json` includes the `neo4j-boost` server with the configured URL.
2938

3039
Set `NEO4J_URI`, `NEO4J_USERNAME`, and `NEO4J_PASSWORD` where the Neo4j MCP server runs (and in Laravel if you use the Neo4j driver).
@@ -74,4 +83,4 @@
7483
- Open your **Laravel app folder** (the project where you ran `composer require neo4j/laravel-boost`) as the Cursor workspace, not the neo4j-boost package folder.
7584
- If `.cursor/mcp.json` is missing, run `php artisan neo4j-boost:cursor-config` to create it.
7685
- Ensure the Neo4j MCP server is running at the URL set in `NEO4J_MCP_URL` and that it is started with HTTP transport.
77-
- If you see **404 "This server only handles requests to /mcp"**: Cursor may send GET requests (e.g. for SSE); the Neo4j MCP server only accepts POST on `/mcp`. Using **Boost** (one server: `boost:mcp`) avoids this—Cursor uses stdio and this package calls Neo4j MCP over HTTP. Otherwise ensure the URL ends with `/mcp` and the server is running with HTTP transport.
86+
- If you see **404 "This server only handles requests to /mcp"**: Cursor may send GET requests (e.g. for SSE); the Neo4j MCP server only accepts POST on `/mcp`. Using **Boost** (one server: `boost:mcp`) avoids this—Cursor uses stdio to Laravel and this package talks to Neo4j via driver (default), HTTP, or STDIO. Otherwise ensure the URL ends with `/mcp` and the server is running with HTTP transport.

src/Console/SetupCommand.php

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class SetupCommand extends Command
1313
{--skip-mcp : Skip Neo4j MCP binary installation}
1414
{--no-cursor-config : Skip running neo4j-boost:cursor-config}';
1515

16-
protected $description = 'Interactive setup for Neo4j Laravel Boost (Cursor config, optional STDIO binary). Use -n/--no-interaction for manual steps only.';
16+
protected $description = 'Interactive setup for Neo4j Laravel Boost (Neo4j, optional MCP binary, Cursor config). Use -n/--no-interaction for manual steps only.';
1717

1818
public function handle(): int
1919
{
@@ -60,6 +60,14 @@ public function handle(): int
6060

6161
$this->newLine();
6262

63+
$transport = Neo4jMcpConfig::transport();
64+
65+
if ($transport === 'driver' && Neo4jMcpConfig::hasNeo4jPassword()) {
66+
$this->components->info('Neo4j Laravel Boost setup complete. Driver transport is ready (Bolt — no neo4j-mcp binary required).');
67+
68+
return self::SUCCESS;
69+
}
70+
6371
if ($installer->isInstalled() && Neo4jMcpConfig::hasNeo4jPassword()) {
6472
$this->components->info('Neo4j Laravel Boost setup complete. STDIO transport is ready with the local neo4j-mcp binary.');
6573

@@ -81,33 +89,36 @@ protected function printProxyModelDescription(): void
8189
{
8290
$this->newLine();
8391
$this->components->info('Neo4j Laravel Boost setup');
84-
$this->line('Default proxy path: <fg=cyan>Boost MCP -> driver -> laudis/neo4j-php-client (Bolt)</>');
85-
$this->line('Driver transport is the default — no neo4j-mcp binary required.');
92+
$this->line('Default path: <fg=cyan>Boost MCP -> driver transport (in-process Bolt)</>');
93+
$this->line('No neo4j-mcp binary is required unless you set <fg=cyan>NEO4J_MCP_TRANSPORT=stdio</>.');
8694
$this->newLine();
8795
$this->line('Add these lines to your <fg=cyan>.env</> (reminder):');
8896
$this->line(' <fg=gray>NEO4J_URI=bolt://localhost:7687</>');
8997
$this->line(' <fg=gray>NEO4J_USERNAME=neo4j</>');
9098
$this->line(' <fg=gray>NEO4J_PASSWORD=password</>');
91-
$this->line(' <fg=gray># Optional: set NEO4J_MCP_TRANSPORT=stdio to use the neo4j-mcp binary instead</>');
9299
$this->newLine();
93100
}
94101

95102
protected function printManualInstructions(): void
96103
{
97104
$this->components->warn('Non-interactive mode: run these steps manually.');
98105
$this->newLine();
99-
$this->line(' 1. Ensure .env contains:');
106+
$this->line(' 1. Install the Neo4j MCP binary:');
107+
$this->line(' <fg=gray>php artisan neo4j-boost:install-mcp</>');
108+
$this->newLine();
109+
$this->line(' 2. Start local Neo4j:');
110+
$this->line(' <fg=gray>php artisan neo4j-boost:start-neo4j</>');
111+
$this->newLine();
112+
$this->line(' 3. Ensure .env contains:');
100113
$this->line(' <fg=gray>NEO4J_URI=bolt://localhost:7687</>');
101114
$this->line(' <fg=gray>NEO4J_USERNAME=neo4j</>');
102115
$this->line(' <fg=gray>NEO4J_PASSWORD=password</>');
103116
$this->newLine();
104-
$this->line(' 2. Configure Cursor MCP:');
105-
$this->line(' <fg=gray>php artisan neo4j-boost:cursor-config</>');
117+
$this->line(' 4. (Optional) For STDIO transport, also run install-mcp and set:');
118+
$this->line(' <fg=gray>NEO4J_MCP_TRANSPORT=stdio</>');
106119
$this->newLine();
107-
$this->line(' Optional (STDIO transport only):');
108-
$this->line(' <fg=gray>php artisan neo4j-boost:install-mcp</>');
109-
$this->line(' <fg=gray>php artisan neo4j-boost:start-neo4j</>');
110-
$this->line(' Set NEO4J_MCP_TRANSPORT=stdio in .env');
120+
$this->line(' 5. Configure Cursor MCP:');
121+
$this->line(' <fg=gray>php artisan neo4j-boost:cursor-config</>');
111122
$this->newLine();
112123
}
113124

@@ -125,6 +136,13 @@ protected function shouldInstallMcpBinary(): bool
125136
return false;
126137
}
127138

139+
if (Neo4jMcpConfig::transport() === 'driver') {
140+
return $this->confirm(
141+
'Install the official Neo4j MCP server binary? (only required for NEO4J_MCP_TRANSPORT=stdio)',
142+
false
143+
);
144+
}
145+
128146
return $this->confirm(
129147
'Install the official Neo4j MCP server binary for this project?',
130148
true

src/Neo4jBoostServiceProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function register(): void
5454
$this->app->singleton(BoltExecutorInterface::class, Neo4jBoltExecutor::class);
5555

5656
$this->app->singleton(Neo4jMcpClientInterface::class, function ($app) {
57-
$driver = strtolower((string) config('neo4j-boost.neo4j_mcp.transport', 'stdio'));
57+
$driver = strtolower((string) config('neo4j-boost.neo4j_mcp.transport', 'driver'));
5858

5959
return match ($driver) {
6060
'driver' => new Neo4jDriverClient($app->make(BoltExecutorInterface::class)),

src/Support/Neo4jMcpConfig.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public static function transport(): string
1111
$transport = config('neo4j-boost.neo4j_mcp.transport');
1212

1313
if (! is_string($transport) || $transport === '') {
14-
$transport = config('neo4j-boost.transport.driver', 'stdio');
14+
$transport = config('neo4j-boost.transport.driver', 'driver');
1515
}
1616

1717
return strtolower((string) $transport);

tests/Integration/Neo4jBoostServiceProviderTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Neo4j\LaravelBoost\Contracts\Neo4jMcpClientInterface;
77
use Neo4j\LaravelBoost\Neo4jDriverClient;
88
use Neo4j\LaravelBoost\Neo4jHttpClient;
9+
use Neo4j\LaravelBoost\Neo4jStdioClient;
910
use Neo4j\LaravelBoost\Support\ContainerGraphConnection;
1011
use Neo4j\LaravelBoost\Support\Neo4jBoltClient;
1112
use Neo4j\LaravelBoost\Tests\TestCase;
@@ -19,6 +20,16 @@ public function test_resolves_neo4j_mcp_client_as_driver_by_default(): void
1920
$this->assertInstanceOf(Neo4jDriverClient::class, $client);
2021
}
2122

23+
public function test_resolves_neo4j_mcp_client_as_stdio_when_transport_is_stdio(): void
24+
{
25+
config(['neo4j-boost.neo4j_mcp.transport' => 'stdio']);
26+
27+
$this->app->forgetInstance(Neo4jMcpClientInterface::class);
28+
$client = $this->app->make(Neo4jMcpClientInterface::class);
29+
30+
$this->assertInstanceOf(Neo4jStdioClient::class, $client);
31+
}
32+
2233
public function test_resolves_neo4j_mcp_client_as_http_when_transport_is_http(): void
2334
{
2435
config(['neo4j-boost.neo4j_mcp.transport' => 'http']);

0 commit comments

Comments
 (0)