Skip to content

Add Gephi AI plugin 1.5.1 - #337

Open
MattArtzAnthro wants to merge 6 commits into
gephi:master-forgefrom
MattArtzAnthro:gephi-mcp-1.2.17
Open

MattArtzAnthro wants to merge 6 commits into
gephi:master-forgefrom
MattArtzAnthro:gephi-mcp-1.2.17

Conversation

@MattArtzAnthro

@MattArtzAnthro MattArtzAnthro commented Aug 28, 2026 •

Copy link
Copy Markdown

New plugin or plugin update?

  • New Plugin
  • Update

What is the purpose of this plugin?

Gephi AI adds a local HTTP API to Gephi Desktop so an AI assistant can drive a
running Gephi: build and edit graphs, run layouts and statistics, style, filter,
export, and read the analyst's on-canvas selection. The assistant connects
through a separate Model Context Protocol server, distributed independently; this
plugin does not require it to build, install, or be reviewed.

The API listens on 127.0.0.1 only. It refuses any request whose Host header is
not a loopback address, which blocks DNS rebinding, and any request carrying
Origin or Sec-Fetch-Site, which blocks a page the user is merely visiting
from driving the API with a cross-origin fetch. Browsers set those headers and
page JavaScript cannot forge them; local clients send neither.

Beyond that the API is not authenticated: it trusts every local process, the same posture as
the Graph Streaming plugin's server. That is deliberate, because the client is a local MCP
server, and the module README states it plainly for users.

Companion server and documentation: https://github.com/MattArtzAnthro/gephi-ai

How to test your plugin in Gephi?

  1. Build and launch: mvn clean package, then
    mvn org.gephi:gephi-maven-plugin:run from the repository root.
  2. Open Tools > Gephi AI Server. The dialog shows the state (running or
    stopped) and the listening URL. The server starts automatically, so it should
    read running on http://127.0.0.1:8080.
  3. Confirm the API answers: curl http://127.0.0.1:8080/health. Expect JSON with
    "service": "Gephi AI API" and "status": "running".
  4. Confirm a browser cannot drive it:
    curl -i http://127.0.0.1:8080/graph/stats -H "Origin: https://example.com".
    Expect 403 Forbidden. Without the header the same call succeeds.
  5. Exercise it end to end without an assistant. Create a project, add two nodes
    and an edge, then read the graph back:
    curl -X POST http://127.0.0.1:8080/project/new -H 'Content-Type: application/json' -d '{"name":"demo"}'
    curl -X POST http://127.0.0.1:8080/graph/nodes/add -H 'Content-Type: application/json' -d '{"nodes":[{"id":"a","label":"A"},{"id":"b","label":"B"}]}'
    curl -X POST http://127.0.0.1:8080/graph/edges/add -H 'Content-Type: application/json' -d '{"edges":[{"source":"a","target":"b"}]}'
    curl http://127.0.0.1:8080/graph/stats
    
    The nodes and the edge appear in the Gephi window as they are added.
  6. In the dialog, click Stop. curl http://127.0.0.1:8080/health should now
    fail to connect. Click Start to bring it back, then repeat step 5 to confirm the
    restarted server still serves requests. Changing the port in the dialog takes effect
    on the next start.

Checklist before submission

  • Did you merge with the master branch to get the latest updates?
    Rebased onto master-forge at 2a6232e and built against gephi-plugin-parent
    0.11.3. The diff is the module plus its <modules> entry in the root POM, with the
    name, origin and status comments described in CONTRIBUTING.md.
  • Did you build and test the plugin successfully locally?
    mvn -pl modules/GephiAI clean package in this checkout: the module builds against
    gephi-plugin-parent 0.11.3 and its 181 JUnit tests pass. The plugin was also run in
    Gephi 0.11.3 and exercised end to end over its HTTP API.
  • Did you include metadata (author, license) in the pom.xml?
    Apache 2.0, with licenseFile so the text is shown at install, plus author,
    homepage, and source URL. Every source file carries the licence header.
  • Did you make sure NOT to include any unnecessary files in your PR?
    51 files: the module and its <modules> entry. No deletions.
  • Did you write unit tests to test your plugin functionalities?
    181 tests, including the loopback and browser-origin guards checked over a real
    connection to the server as well as in isolation, request-body and query decoding,
    graph operations, colouring that touches only what a filter leaves visible,
    lock behaviour under real two-thread contention, a smoke test that boots the
    server on an ephemeral port and exercises it over HTTP, a GEXF and GraphML
    import round trip that keeps node positions and sizes, the deadline that stops a
    statistic that never finishes, and reporting of layout settings that match no
    property. SourceRulesTest checks that every graph lock is released in a finally, that
    no loop runs over a live graph iterator, and that interface-thread blocks neither change
    projects nor read the graph. The source follows Gephi core's checkstyle configuration.

Notes for reviewers

Architecture. The plugin registers no Layout, Statistics, or Filter service, because there
is no extension point for a background service, so a reviewer scanning the diff will not find a
@ServiceProvider. The module declares an OpenIDE-Module-Install lifecycle hook instead,
which starts and stops the listener with the module and gives closing() for an orderly
shutdown, plus a Tools menu action so the user can see and control it. The Graph Streaming
plugin is this repository's precedent for an embedded HTTP server inside Gephi. The server is
the JDK's own com.sun.net.httpserver, so the module bundles no HTTP library; Gson is its
only bundled dependency.

Gephi's own controllers. Colouring and sizing go through AppearanceController, layouts
through LayoutController, statistics through the Statistics panel's controller, and PNG, PDF
and screenshot export through Gephi's exporters and ScreenshotController, so the Appearance,
Layout and Statistics panels show what the plugin did.

Reflection. Three field lookups in GephiControlService reach the
ReentrantReadWriteLock behind GraphLock. GraphLock exposes no timed
acquisition, and without a timeout a leaked read hold wedges the session. Each
lookup is cached, wrapped, and falls back to the public blocking API on any
failure, and a unit test fails loudly if graphstore renames the field rather than
letting the plugin degrade silently. The workaround is removed once
gephi/graphstore#294 lands, which adds tryReadLock and
tryWriteLock to the public API. Reflection is also used to set statistic parameters and read
their results, since the Statistics SPI has no generic property API. All of it is wrapped, and every path degrades to a no-op or an honest
error rather than failing the request.

Threading. Requests are served on HTTP threads. Graph mutations, file import, exports,
screenshots, and project and workspace changes run there, as Gephi 0.11.3's own interface runs
project changes off the event dispatch thread. Only Swing work hops to it: updating the
Appearance, Layout and Statistics panels, switching perspective, opening a project, reading
project and workspace details, and emptying the Filters panel before a project closes.

Style and structure changes are welcome. Edits from maintainers are enabled, so
please push directly to the branch rather than routing changes through me.


The plugin, its tests and this update were worked out together with Claude, Anthropic's AI assistant. I built, ran, and verified everything on my own machine, and I am happy to re-run any of it.

@MattArtzAnthro
MattArtzAnthro force-pushed the gephi-mcp-1.2.17 branch 3 times, most recently from b8ea350 to 339ed5a Compare August 29, 2026 16:01
@MattArtzAnthro MattArtzAnthro changed the title Add Gephi AI (MCP) plugin 1.2.17 Add Gephi AI plugin 1.3.0 Aug 29, 2026
@mbastian
mbastian self-requested a review September 12, 2026 13:47
@MattArtzAnthro

Copy link
Copy Markdown
Author

@mbastian need anything from me on this?

@MattArtzAnthro MattArtzAnthro changed the title Add Gephi AI plugin 1.3.0 Add Gephi AI plugin 1.3.3 Sep 26, 2026
Requires Gephi 0.11.3. Appearance, layout, screenshot and PNG/PDF export go
through Gephi's controllers and exporters. The JDK HTTP server replaces
NanoHTTPD. PDFs are US Letter. 160 tests.
@MattArtzAnthro MattArtzAnthro changed the title Add Gephi AI plugin 1.3.3 Add Gephi AI plugin 1.5.0 Sep 27, 2026
Writes no longer pause the renderer; measured on Gephi 0.11.3 the pause
made no difference. The busy message names a running statistic rather
than the renderer. Source reformatted to Gephi core's checkstyle, with
SourceRulesTest for lock release, live iterators and the interface
thread. README states the Gephi 0.11.3 requirement. 170 tests.
@MattArtzAnthro MattArtzAnthro changed the title Add Gephi AI plugin 1.5.0 Add Gephi AI plugin 1.5.1 Sep 28, 2026
NetBeans runs the module's installer inside the test JVM, which started
the API server on 8080. With a Gephi on the same machine holding that
port, the bind failure opened an error dialog mid-run. Surefire now sets
java.awt.headless=true and gephi.mcp.port=0, pinned by TestEnvironmentTest.
172 tests.
…ailures

A second request for a statistic already running is refused. The degree
and edge-weight filters choose what to remove after taking the write lock.
Requests that fail with an exception log the stack trace. 181 tests.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant