Skip to content

Commit 80527d7

Browse files
committed
Fix bugs and enhance vector tools
1 parent b8029df commit 80527d7

16 files changed

Lines changed: 1565 additions & 526 deletions

pyTigerGraph/mcp/MCP_README.md

Lines changed: 96 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,10 @@ These operations manage individual graphs within the TigerGraph database. A data
147147
- `tigergraph__clear_graph_data` - Clear all data from a graph (keeps schema structure)
148148

149149
### Schema Operations (Graph Level)
150-
These operations work with the schema of a specific graph. Each graph has its own independent schema.
150+
These operations work with the schema and objects of a specific graph.
151151

152-
- `tigergraph__get_graph_schema` - Get the schema of a specific graph (raw JSON)
153-
- `tigergraph__describe_graph` - Get a human-readable description of a specific graph's schema
154-
- `tigergraph__get_graph_metadata` - Get metadata about a specific graph (vertex types, edge types, queries, loading jobs)
152+
- `tigergraph__get_graph_schema` - Get the schema of a specific graph as structured JSON (vertex/edge types and attributes only)
153+
- `tigergraph__show_graph_details` - Show details of a graph: schema, queries, loading jobs, data sources. Use `detail_type` to filter (`schema`, `query`, `loading_job`, `data_source`) or omit for all
155154

156155
### Node Operations
157156
- `tigergraph__add_node` - Add a single node
@@ -196,15 +195,20 @@ These operations work with the schema of a specific graph. Each graph has its ow
196195
- `tigergraph__get_node_degree` - Get the degree (number of edges) of a node
197196

198197
### GSQL Operations
199-
- `tigergraph__gsql` - Execute GSQL command
198+
- `tigergraph__gsql` - Execute raw GSQL command
199+
- `tigergraph__generate_gsql` - Generate a GSQL query from a natural language description (requires LLM configuration)
200+
- `tigergraph__generate_cypher` - Generate an openCypher query from a natural language description (requires LLM configuration)
200201

201202
### Vector Schema Operations
202203
- `tigergraph__add_vector_attribute` - Add a vector attribute to a vertex type (DIMENSION, METRIC: COSINE/L2/IP)
203204
- `tigergraph__drop_vector_attribute` - Drop a vector attribute from a vertex type
205+
- `tigergraph__list_vector_attributes` - List vector attributes (name, dimension, index type, data type, metric) by parsing `LS` output; optionally filter by vertex type
204206
- `tigergraph__get_vector_index_status` - Check vector index rebuild status (Ready_for_query/Rebuild_processing)
205207

206208
### Vector Data Operations
207209
- `tigergraph__upsert_vectors` - Upsert multiple vertices with vector data using REST API (batch support)
210+
- `tigergraph__load_vectors_from_csv` - Bulk-load vectors from a CSV/delimited file via a GSQL loading job (creates job, runs with file, drops job)
211+
- `tigergraph__load_vectors_from_json` - Bulk-load vectors from a JSON Lines (.jsonl) file via a GSQL loading job with `JSON_FILE="true"` (creates job, runs with file, drops job)
208212
- `tigergraph__search_top_k_similarity` - Perform vector similarity search using `vectorSearch()` function
209213
- `tigergraph__fetch_vector` - Fetch vertices with vector data using GSQL `PRINT WITH VECTOR`
210214

@@ -219,6 +223,11 @@ These operations work with the schema of a specific graph. Each graph has its ow
219223
- `tigergraph__drop_all_data_sources` - Drop all data sources
220224
- `tigergraph__preview_sample_data` - Preview sample data from a file
221225

226+
### Discovery & Navigation
227+
- `tigergraph__discover_tools` - Search for tools by description, use case, or keywords
228+
- `tigergraph__get_workflow` - Get step-by-step workflow templates for common tasks (e.g., `data_loading`, `schema_creation`, `graph_exploration`)
229+
- `tigergraph__get_tool_info` - Get detailed information about a specific tool (parameters, examples, related tools)
230+
222231
## Backward Compatibility
223232

224233
All existing pyTigerGraph APIs continue to work as before. MCP support is completely optional and does not affect existing code. The MCP functionality is only available when:
@@ -294,12 +303,91 @@ asyncio.run(call_tool())
294303

295304
**Note:** When using `MultiServerMCPClient` or similar MCP clients with stdio transport, the `args` parameter is required. For the `tigergraph-mcp` command (which is a standalone entry point), set `args` to an empty list `[]`. If you need to pass arguments to the command, include them in the list (e.g., `["-v"]` for verbose mode, `["-vv"]` for debug mode).
296305

306+
## LLM-Friendly Features
307+
308+
The MCP server is designed to help AI agents work effectively with TigerGraph.
309+
310+
### Structured Responses
311+
312+
Every tool response follows a consistent JSON structure:
313+
314+
```json
315+
{
316+
"success": true,
317+
"operation": "get_node",
318+
"summary": "Found vertex 'p123' of type 'Person'",
319+
"data": { ... },
320+
"suggestions": [
321+
"View connected edges: get_node_edges(...)",
322+
"Find neighbors: get_neighbors(...)"
323+
],
324+
"metadata": { "graph_name": "MyGraph" }
325+
}
326+
```
327+
328+
Error responses include actionable recovery hints:
329+
330+
```json
331+
{
332+
"success": false,
333+
"operation": "get_node",
334+
"error": "Vertex not found",
335+
"suggestions": [
336+
"Verify the vertex_id is correct",
337+
"Check vertex type with show_graph_details()"
338+
]
339+
}
340+
```
341+
342+
### Rich Tool Descriptions
343+
344+
Each tool includes detailed descriptions with:
345+
- **Use cases** — when to call this tool
346+
- **Common workflows** — step-by-step patterns
347+
- **Tips** — best practices and gotchas
348+
- **Warnings** — safety notes for destructive operations
349+
- **Related tools** — what to call next
350+
351+
### Token Optimization
352+
353+
Responses are designed for efficient LLM token usage:
354+
- No echoing of input parameters (the LLM already knows what it sent)
355+
- Only returns new information (results, counts, boolean answers)
356+
- Clean text output with no decorative formatting
357+
358+
## Tool Discovery Workflow
359+
360+
The MCP server includes discovery tools to help AI agents find the right tool for a task:
361+
362+
```python
363+
# 1. Discover tools for a task
364+
result = await session.call_tool(
365+
"tigergraph__discover_tools",
366+
arguments={"query": "how to add data to the graph"}
367+
)
368+
# Returns: ranked list of relevant tools with use cases
369+
370+
# 2. Get a workflow template
371+
result = await session.call_tool(
372+
"tigergraph__get_workflow",
373+
arguments={"workflow_type": "data_loading"}
374+
)
375+
# Returns: step-by-step guide with tool calls
376+
377+
# 3. Get detailed tool info
378+
result = await session.call_tool(
379+
"tigergraph__get_tool_info",
380+
arguments={"tool_name": "tigergraph__add_node"}
381+
)
382+
# Returns: full documentation, examples, related tools
383+
```
384+
297385
## Notes
298386

299387
- **Async APIs**: All MCP tools use pyTigerGraph's async APIs (`AsyncTigerGraphConnection`) for optimal performance
300388
- **Transport**: The MCP server uses stdio transport by default
301-
- **Tool Responses**: All tools are async and return `TextContent` responses
302-
- **Error Handling**: Error handling is built into each tool
389+
- **Structured Responses**: All tools return structured JSON responses with `success`, `operation`, `summary`, `data`, `suggestions`, and `metadata` fields. Error responses include recovery hints and contextual suggestions
390+
- **Error Detection**: GSQL operations include error detection for syntax and semantic errors (since `conn.gsql()` does not raise Python exceptions for GSQL failures)
303391
- **Connection Management**: The connection manager automatically creates async connections from environment variables
304-
- **Performance**: Using async APIs ensures non-blocking I/O operations, making the MCP server more efficient for concurrent requests
392+
- **Performance**: Async APIs for non-blocking I/O; `v.outdegree()` for O(1) degree counting; batch operations for multiple vertices/edges
305393

pyTigerGraph/mcp/response_formatter.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,15 +171,15 @@ def format_error(
171171
if any(term in error_lower for term in ["vertex type", "edge type", "type not found"]):
172172
suggestions.extend([
173173
"The specified type may not exist in the schema",
174-
"Call 'describe_graph' to see available vertex and edge types",
174+
"Call 'show_graph_details' to see available vertex and edge types",
175175
"Call 'list_graphs' to ensure you're using the correct graph"
176176
])
177177

178178
# Attribute errors
179179
elif any(term in error_lower for term in ["attribute", "column", "field"]):
180180
suggestions.extend([
181181
"One or more attributes may not match the schema definition",
182-
"Call 'describe_graph' to see required attributes and their types",
182+
"Call 'show_graph_details' to see required attributes and their types",
183183
"Check that attribute names are spelled correctly"
184184
])
185185

@@ -207,7 +207,7 @@ def format_error(
207207
"Query syntax error detected",
208208
"For GSQL: Use 'INTERPRET QUERY () FOR GRAPH <name> { ... }'",
209209
"For Cypher: Use 'INTERPRET OPENCYPHER QUERY () FOR GRAPH <name> { ... }'",
210-
"Call 'describe_graph' to understand the schema before writing queries"
210+
"Call 'show_graph_details' to understand the schema before writing queries"
211211
])
212212

213213
# Vector errors
@@ -216,14 +216,14 @@ def format_error(
216216
"Vector operation error",
217217
"Ensure vector dimensions match the attribute definition",
218218
"Call 'get_vector_index_status' to check if index is ready",
219-
"Verify vector attribute exists with 'describe_graph'"
219+
"Verify vector attribute exists with 'show_graph_details'"
220220
])
221221

222222
# Generic suggestions
223223
if len(suggestions) == 0:
224224
suggestions.extend([
225225
"Check the error message for specific details",
226-
"Call 'describe_graph' to understand the current graph structure",
226+
"Call 'show_graph_details' to understand the current graph structure",
227227
"Verify all required parameters are provided correctly"
228228
])
229229

@@ -253,6 +253,27 @@ def format_error(
253253
)
254254

255255

256+
def gsql_has_error(result_str: str) -> bool:
257+
"""Check whether a GSQL result string indicates a failure.
258+
259+
``conn.gsql()`` does **not** raise an exception when a GSQL command fails;
260+
instead, the error message is returned as a plain string. This helper
261+
inspects the result for well-known error patterns so callers can
262+
distinguish success from failure.
263+
"""
264+
error_patterns = [
265+
"Encountered \"",
266+
"SEMANTIC ERROR",
267+
"Syntax Error",
268+
"Failed to create",
269+
"does not exist",
270+
"is not a valid",
271+
"already exists",
272+
"Invalid syntax",
273+
]
274+
return any(p in result_str for p in error_patterns)
275+
276+
256277
def format_list_response(
257278
operation: str,
258279
items: List[Any],

pyTigerGraph/mcp/server.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626
clear_graph_data,
2727
# Schema operations (graph level)
2828
get_graph_schema,
29-
describe_graph,
30-
get_graph_metadata,
29+
show_graph_details,
3130
# Node tools
3231
add_node,
3332
add_nodes,
@@ -72,9 +71,12 @@
7271
# Vector schema tools
7372
add_vector_attribute,
7473
drop_vector_attribute,
74+
list_vector_attributes,
7575
get_vector_index_status,
7676
# Vector data tools
7777
upsert_vectors,
78+
load_vectors_from_csv,
79+
load_vectors_from_json,
7880
search_top_k_similarity,
7981
fetch_vector,
8082
# Data Source tools
@@ -130,10 +132,8 @@ async def call_tool(name: str, arguments: Dict) -> List[TextContent]:
130132
# Schema operations (graph level)
131133
case TigerGraphToolName.GET_GRAPH_SCHEMA:
132134
return await get_graph_schema(**arguments)
133-
case TigerGraphToolName.DESCRIBE_GRAPH:
134-
return await describe_graph(**arguments)
135-
case TigerGraphToolName.GET_GRAPH_METADATA:
136-
return await get_graph_metadata(**arguments)
135+
case TigerGraphToolName.SHOW_GRAPH_DETAILS:
136+
return await show_graph_details(**arguments)
137137
# Node operations
138138
case TigerGraphToolName.ADD_NODE:
139139
return await add_node(**arguments)
@@ -215,11 +215,17 @@ async def call_tool(name: str, arguments: Dict) -> List[TextContent]:
215215
return await add_vector_attribute(**arguments)
216216
case TigerGraphToolName.DROP_VECTOR_ATTRIBUTE:
217217
return await drop_vector_attribute(**arguments)
218+
case TigerGraphToolName.LIST_VECTOR_ATTRIBUTES:
219+
return await list_vector_attributes(**arguments)
218220
case TigerGraphToolName.GET_VECTOR_INDEX_STATUS:
219221
return await get_vector_index_status(**arguments)
220222
# Vector data operations
221223
case TigerGraphToolName.UPSERT_VECTORS:
222224
return await upsert_vectors(**arguments)
225+
case TigerGraphToolName.LOAD_VECTORS_FROM_CSV:
226+
return await load_vectors_from_csv(**arguments)
227+
case TigerGraphToolName.LOAD_VECTORS_FROM_JSON:
228+
return await load_vectors_from_json(**arguments)
223229
case TigerGraphToolName.SEARCH_TOP_K_SIMILARITY:
224230
return await search_top_k_similarity(**arguments)
225231
case TigerGraphToolName.FETCH_VECTOR:

pyTigerGraph/mcp/tool_metadata.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,26 +38,26 @@ class ToolMetadata(BaseModel):
3838
# Define metadata for each tool
3939
TOOL_METADATA: Dict[str, ToolMetadata] = {
4040
# Schema Operations
41-
"tigergraph__describe_graph": ToolMetadata(
41+
"tigergraph__show_graph_details": ToolMetadata(
4242
category=ToolCategory.SCHEMA,
4343
prerequisites=[],
44-
related_tools=["tigergraph__get_graph_schema", "tigergraph__get_graph_metadata"],
44+
related_tools=["tigergraph__get_graph_schema"],
4545
common_next_steps=["tigergraph__add_node", "tigergraph__add_edge", "tigergraph__run_query"],
4646
use_cases=[
47+
"Getting a full listing of a graph (schema, queries, jobs)",
4748
"Understanding the structure of a graph before writing queries",
4849
"Discovering available vertex and edge types",
49-
"Learning the attributes of each vertex/edge type",
5050
"First step in any graph interaction workflow"
5151
],
5252
complexity="basic",
53-
keywords=["schema", "structure", "describe", "understand", "explore"],
53+
keywords=["schema", "structure", "show", "understand", "explore", "queries", "jobs"],
5454
examples=[
5555
{
56-
"description": "Get schema for default graph",
56+
"description": "Show everything under default graph",
5757
"parameters": {}
5858
},
5959
{
60-
"description": "Get schema for specific graph",
60+
"description": "Show everything under a specific graph",
6161
"parameters": {"graph_name": "SocialGraph"}
6262
}
6363
]
@@ -66,8 +66,8 @@ class ToolMetadata(BaseModel):
6666
"tigergraph__list_graphs": ToolMetadata(
6767
category=ToolCategory.SCHEMA,
6868
prerequisites=[],
69-
related_tools=["tigergraph__describe_graph", "tigergraph__create_graph"],
70-
common_next_steps=["tigergraph__describe_graph"],
69+
related_tools=["tigergraph__show_graph_details", "tigergraph__create_graph"],
70+
common_next_steps=["tigergraph__show_graph_details"],
7171
use_cases=[
7272
"Discovering what graphs exist in the database",
7373
"First step when connecting to a new TigerGraph instance",
@@ -81,8 +81,8 @@ class ToolMetadata(BaseModel):
8181
"tigergraph__create_graph": ToolMetadata(
8282
category=ToolCategory.SCHEMA,
8383
prerequisites=[],
84-
related_tools=["tigergraph__list_graphs", "tigergraph__describe_graph"],
85-
common_next_steps=["tigergraph__describe_graph", "tigergraph__add_node"],
84+
related_tools=["tigergraph__list_graphs", "tigergraph__show_graph_details"],
85+
common_next_steps=["tigergraph__show_graph_details", "tigergraph__add_node"],
8686
use_cases=[
8787
"Creating a new graph from scratch",
8888
"Setting up a graph with specific vertex and edge types",
@@ -119,7 +119,7 @@ class ToolMetadata(BaseModel):
119119
"tigergraph__get_graph_schema": ToolMetadata(
120120
category=ToolCategory.SCHEMA,
121121
prerequisites=[],
122-
related_tools=["tigergraph__describe_graph"],
122+
related_tools=["tigergraph__show_graph_details"],
123123
common_next_steps=["tigergraph__add_node", "tigergraph__run_query"],
124124
use_cases=[
125125
"Getting raw JSON schema for programmatic processing",
@@ -133,7 +133,7 @@ class ToolMetadata(BaseModel):
133133
# Node Operations
134134
"tigergraph__add_node": ToolMetadata(
135135
category=ToolCategory.DATA,
136-
prerequisites=["tigergraph__describe_graph"],
136+
prerequisites=["tigergraph__show_graph_details"],
137137
related_tools=["tigergraph__add_nodes", "tigergraph__get_node", "tigergraph__delete_node"],
138138
common_next_steps=["tigergraph__get_node", "tigergraph__add_edge", "tigergraph__get_node_edges"],
139139
use_cases=[
@@ -165,7 +165,7 @@ class ToolMetadata(BaseModel):
165165

166166
"tigergraph__add_nodes": ToolMetadata(
167167
category=ToolCategory.DATA,
168-
prerequisites=["tigergraph__describe_graph"],
168+
prerequisites=["tigergraph__show_graph_details"],
169169
related_tools=["tigergraph__add_node", "tigergraph__get_nodes"],
170170
common_next_steps=["tigergraph__get_vertex_count", "tigergraph__add_edges"],
171171
use_cases=[
@@ -239,7 +239,7 @@ class ToolMetadata(BaseModel):
239239
# Edge Operations
240240
"tigergraph__add_edge": ToolMetadata(
241241
category=ToolCategory.DATA,
242-
prerequisites=["tigergraph__add_node", "tigergraph__describe_graph"],
242+
prerequisites=["tigergraph__add_node", "tigergraph__show_graph_details"],
243243
related_tools=["tigergraph__add_edges", "tigergraph__get_edge"],
244244
common_next_steps=["tigergraph__get_node_edges", "tigergraph__get_neighbors"],
245245
use_cases=[
@@ -266,7 +266,7 @@ class ToolMetadata(BaseModel):
266266

267267
"tigergraph__add_edges": ToolMetadata(
268268
category=ToolCategory.DATA,
269-
prerequisites=["tigergraph__add_nodes", "tigergraph__describe_graph"],
269+
prerequisites=["tigergraph__add_nodes", "tigergraph__show_graph_details"],
270270
related_tools=["tigergraph__add_edge"],
271271
common_next_steps=["tigergraph__get_edge_count"],
272272
use_cases=[
@@ -282,7 +282,7 @@ class ToolMetadata(BaseModel):
282282
# Query Operations
283283
"tigergraph__run_query": ToolMetadata(
284284
category=ToolCategory.QUERY,
285-
prerequisites=["tigergraph__describe_graph"],
285+
prerequisites=["tigergraph__show_graph_details"],
286286
related_tools=["tigergraph__run_installed_query", "tigergraph__get_neighbors"],
287287
common_next_steps=[],
288288
use_cases=[
@@ -336,7 +336,7 @@ class ToolMetadata(BaseModel):
336336
# Vector Operations
337337
"tigergraph__add_vector_attribute": ToolMetadata(
338338
category=ToolCategory.VECTOR,
339-
prerequisites=["tigergraph__describe_graph"],
339+
prerequisites=["tigergraph__show_graph_details"],
340340
related_tools=["tigergraph__drop_vector_attribute", "tigergraph__get_vector_index_status"],
341341
common_next_steps=["tigergraph__get_vector_index_status", "tigergraph__upsert_vectors"],
342342
use_cases=[
@@ -426,7 +426,7 @@ class ToolMetadata(BaseModel):
426426
# Loading Operations
427427
"tigergraph__create_loading_job": ToolMetadata(
428428
category=ToolCategory.LOADING,
429-
prerequisites=["tigergraph__describe_graph"],
429+
prerequisites=["tigergraph__show_graph_details"],
430430
related_tools=["tigergraph__run_loading_job_with_file", "tigergraph__run_loading_job_with_data"],
431431
common_next_steps=["tigergraph__run_loading_job_with_file", "tigergraph__get_loading_jobs"],
432432
use_cases=[

0 commit comments

Comments
 (0)