Skip to content

Conversation

spmallette
Copy link
Contributor

After #3196 was offered, it was pulled to the "gremlin-mcp" branch for refinements.

  • Integrated it with the maven build
  • Some minor refactoring/improvemnts
  • Added documentation
  • Lots of manual testing

Once merged, this is likely ready for 3.8.0.alpha1 release in preparation for the official release with the actual 3.8.0.

VOTE +1

Copy link

@kmcginnes kmcginnes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, this seems mostly in good shape. I think most of my comments are nits.

valid queries, generating meaningful filters, and explaining results in natural language. For operators, it offers safer
and more efficient interactions by avoiding blind exploratory scans, enabling caching and change detection, and
providing hooks to steer what should or shouldn’t be surfaced (for example, excluding sensitive or non‑categorical
fields). In short, schema discovery turns an opaque dataset into an actionable contract between your graph and the tools

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

excluding sensitive or non‑categorical fields

How does it make that determination? It might be worth adding examples, such as id.

* `GREMLIN_ENUM_PROPERTY_DENYLIST` — comma-separated property names to exclude from enum detection (default: `id,pk,name,description,startDate,endDate,timestamp,createdAt,updatedAt`)
* `GREMLIN_SCHEMA_MAX_ENUM_VALUES` — limit the number of enum values returned per property in the schema (default: `10`)
* `GREMLIN_SCHEMA_INCLUDE_SAMPLE_VALUES` — include small example values for properties in the schema (default: `false`)
* `GREMLIN_SCHEMA_INCLUDE_COUNTS` — include approximate vertex/edge label counts in the schema (default: `true`)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be the costliest query to run and potentially the least useful to an LLM. Perhaps we should default this to false?

Alternatively, we could make the counts a separate MCP tool exposed to the agents.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

making this simple change, kicked open a wide world of issues i had to investigate. fixed logging and configuration setup as part of making that change.

"verbatimModuleSyntax": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "tests"],

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the tests being excluded from the TypeScript config, they are not compiled in to the dist/ folder (good) but also don't get any of the tsconfig settings above (bad). In Kiro (and I suspect VSCode) I ran in to a lot of typing issues in the tests. Mostly with Jest types that should be global, but aren't. Also, the Node process instance could not be found, leading to type errors in the editor.

The only solution I can think of is not a great one. You would need to have two separate tsconfig files, one for building the distribution artifacts and one for the tests that doesn't emit. Then your build script in the package.json would need to target the correct build tsconfig file. It's more complicated, but should resolve the issue.

It's worth noting that running npm test works perfectly. It's just in the editor that I ran in to issues.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eh, intellij is not super happy either so perhaps this is the reason why? not sure i know what to do with this exactly even with your suggestion. might need to talk about it after this merges.

Comment on lines 135 to 137
const result = await Effect.runPromiseExit(generateEdgePatterns(mockTraversalSource));

expect(result._tag).toBe('Failure');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const result = await Effect.runPromiseExit(generateEdgePatterns(mockTraversalSource));
expect(result._tag).toBe('Failure');
await expect(() => Effect.runPromise(generateEdgePatterns(mockTraversalSource))).rejects.toEqual(error);

Comment on lines 115 to 119
const result = await Effect.runPromiseExit(
analyzeSingleProperty(mockTraversalSource, 'person', 'name', mockConfig, true)
);

expect(result._tag).toBe('Failure');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const result = await Effect.runPromiseExit(
analyzeSingleProperty(mockTraversalSource, 'person', 'name', mockConfig, true)
);
expect(result._tag).toBe('Failure');
await expect(() => Effect.runPromise(
analyzeSingleProperty(mockTraversalSource, 'person', 'name', mockConfig, true)
)).rejects.toEqual(error);

Comment on lines 84 to 88
const result = await Effect.runPromiseExit(
executeGremlinQuery(mockQuery, 'Test query failed', 'test query')
);

expect(result._tag).toBe('Failure');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const result = await Effect.runPromiseExit(
executeGremlinQuery(mockQuery, 'Test query failed', 'test query')
);
expect(result._tag).toBe('Failure');
await expect(() => Effect.runPromise(processBatched(items, 2, processor))).rejects.toThrow();

Comment on lines 182 to 184
const result = await Effect.runPromiseExit(validateVertices(invalidVertices));

expect(result._tag).toBe('Failure');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const result = await Effect.runPromiseExit(validateVertices(invalidVertices));
expect(result._tag).toBe('Failure');
await expect(() =>
Effect.runPromise(validateVertices(invalidVertices))
).rejects.toBeDefined();

This might be a nit pick and subjective, but testing an internal _tag property for a particular string seems like a smell.

I much prefer leaning on typical Promise behavior and Jest Promise support, which avoids the extra Exit wrapping and makes these tests a bit more consistent with the success tests.

There are many tests in this file that fit this pattern, but I had a hell of time getting the code suggestion stuff working, so I'm going to give you this one example.

It would be even nicer if these tests validated which error is thrown.

kpritam and others added 19 commits October 17, 2025 10:00
Docs about unexpected mutations by gremlin-mcp
We could bring this back later. Currently feels a little tricky to use in testing and release of 3.8.0 is looming.
Allows for the basic plain text authentication with Gremlin Server.
The export tool isn't working consistently enough for release. Can bring it back later.
Fixed problems with that setting - it was not having any effect. Also fixed logging to stderr setup for Effect.
@kmcginnes
Copy link

VOTE +1 (non-binding)

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.

4 participants