Skip to content

Add Gephi AI plugin 1.6.1 - #337

Merged
mbastian merged 17 commits into
gephi:master-forgefrom
MattArtzAnthro:gephi-mcp-1.2.17
Nov 8, 2026
Merged

mbastian merged 17 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?
    Merged with master-forge at e9fc1f2 and built against gephi-plugin-parent
    0.11.4, which the plugin requires. The diff is the module plus its <modules> entry in
    the root POM, with the name, origin and status comments described in CONTRIBUTING.md. It
    also shows the root POM and ARCHITECTURE.md lines of the 0.11.4 upgrade (Upgrade to Gephi 0.11.4 and gephi-maven-plugin 1.4.1 #355), which is
    on master but not yet on master-forge.
  • 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.4 and its 379 JUnit tests pass. The plugin was also run in
    Gephi 0.11.4 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?
    57 files: the module, its <modules> entry, and the Upgrade to Gephi 0.11.4 and gephi-maven-plugin 1.4.1 #355 lines above. The only
    deletions are the five version lines Upgrade to Gephi 0.11.4 and gephi-maven-plugin 1.4.1 #355 changes.
  • Did you write unit tests to test your plugin functionalities?
    379 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. Read locks use the public GraphLock.tryReadLock, new in graphstore 0.8.12
(Gephi 0.11.4). One field lookup in GephiControlService still reaches the
ReentrantReadWriteLock behind GraphLock, for a timed write acquisition, because
graphstore 0.8.12 has tryReadLock but no tryWriteLock; without a timeout a leaked read
hold wedges the session. The 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. 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.4'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.
Statistics no longer hang when the Statistics window has not set up the
workspace; the column and new-workspace filter actions do what they report;
node ids work after importing integer ids; preview settings report unknown
and unapplied names; GML and Pajek export work; regex columns warn when
nothing matches. Adds API routing and workspace tool tests (296 in all),
with io-exporter-plugin and preview-plugin as test dependencies.
@MattArtzAnthro MattArtzAnthro changed the title Add Gephi AI plugin 1.5.1 Add Gephi AI plugin 1.5.2 Oct 12, 2026
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
mbastian and others added 5 commits November 7, 2026 17:23
@MattArtzAnthro MattArtzAnthro changed the title Add Gephi AI plugin 1.5.2 Add Gephi AI plugin 1.6.1 Nov 8, 2026
@MattArtzAnthro

Copy link
Copy Markdown
Author

@mbastian Updated to Gephi AI 1.6.1, built on 0.11.4. Reads now use the public tryReadLock from graphstore#294; writes keep one reflected timed acquisition, since tryWriteLock was dropped. The merge conflict is resolved and the PR is mergeable again.

MattArtzAnthro and others added 2 commits November 8, 2026 11:29
* Upgrade to Gephi 0.11.4 and gephi-maven-plugin 1.4.1

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Run gephi-plugins-tests SPI contract tests in CI

Adds a standalone harness (.github/contract-tests) that runs gephi-plugins-tests' contract tests against installed plugin modules, without plugins or gephi-plugin-parent having to declare anything. build.yml tests every module of the branch, pr.yml (moved here from master-forge) tests the modules a master-forge PR changes, and test-generation.yml checks the harness still resolves for the current gephi.version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Pin Surefire 3.6.1 in the contract-test harness and keep docs SPI-agnostic

gephi-plugins-tests will cover more SPIs than layouts, so the docs describe the contract tests generically instead of naming LayoutContractTest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Harden the SPI contract-test harness

- pr.yml tests every module when the root pom.xml or the harness changes, and passes changed folders as a quoted array (no word splitting, no path quoting)
- run.sh fails loudly when listing the reactor fails or gephi.version can't be read, warns about folders that aren't reactor modules, refuses to test a module that isn't installed or was rebuilt since its install, and fails if no contract test class ran at all
- the harness only tests implementations from the plugin's own jar (gephi.plugins.tests.jar, honored by gephi-plugins-tests 1.1.0) and runs headless with the module access Gephi's launcher grants
- test-generation.yml adds a positive control against core layout-plugin so a harness that silently tests nothing fails
- build.yml skips the contract-test step on branches without plugin modules

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Use gephi-plugins-tests 1.1.0 in the contract-test harness

1.1.0 only tests the implementations from the plugin's own jar (the
harness already passes gephi.plugins.tests.jar), and adds the Statistics
and Layout lifecycle contract tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
mbastian and others added 2 commits November 8, 2026 20:19
…phi#375)

Checks that only warn (a layout adding nodes, a statistics without a user interface...) don't fail the run: run.sh turns the warnings the tests write to contract-warnings.tsv into ::warning:: annotations and, on GitHub Actions, a table in the job summary. The jars of the modules that depend on the tested one are put on the test classpath, so a plugin whose user interface is in another module (e.g. BoundingDiameters) has it found.

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Brings the contract-test harness of master (gephi#354, gephi#375). .github/workflows/pr.yml existed on both sides, take master's copy.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@mbastian
mbastian merged commit 97d8f7a into gephi:master-forge Nov 8, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants