Skip to content

Commit b6d6c24

Browse files
committed
feat: add MCP tools for update data source, get/drop all data sources, run gsql, and list metadata
1 parent a877535 commit b6d6c24

17 files changed

+516
-23
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
### 0.1.5
55
- feat: add example using LangGraph LLM and agents to call TigerGraph-MCP
66
- feat: upgrade TigerGraphX to v0.2.9 with new TigerGraphDatabase class integration
7+
- feat: add run algorithm subgraph to onboarding workflow
8+
- feat: add MCP tools for update data source, get/drop all data sources, run gsql, and list metadata
79

810
### 0.1.4
911
- feat: enable multi-turn human-in-the-loop schema confirmation for iterative refinement

poetry.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ requires-python = ">=3.10,<3.13"
1010

1111
dependencies = [
1212
"mcp (>=1.9.2,<2.0.0)",
13-
"tigergraphx (>=0.2.9,<0.3.0)",
13+
"tigergraphx (>=0.2.10,<0.3.0)",
1414
]
1515

1616
[tool.poetry.group.dev.dependencies]

tests/integration/tools/db/data_source_tools_test.py

Lines changed: 96 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,67 @@
99

1010
class TestDataSourceTools(BaseFixture):
1111
@pytest.mark.asyncio
12-
async def test_data_source_tools(self):
13-
SAMPLE_PATH = "s3a://tigergraph-solution-kits/connected_customer/customer_360/data/Session.csv" # Replace with actual path
12+
async def test_data_source_tools_basic(self):
13+
SAMPLE_PATH = "s3a://tigergraph-solution-kits/connected_customer/customer_360/data/Session.csv"
1414

1515
async with stdio_client(self.server_params) as (read, write):
1616
async with ClientSession(read, write) as session:
1717
await session.initialize()
1818

19-
# Create the data source
20-
create_result = await session.call_tool(
21-
TigerGraphToolName.CREATE_DATA_SOURCE,
22-
arguments={
23-
"name": "data_source_1",
24-
"data_source_type": "s3",
25-
"access_key": "",
26-
"secret_key": "",
27-
"extra_config": {
28-
"file.reader.settings.fs.s3a.aws.credentials.provider": "org.apache.hadoop.fs.s3a.AnonymousAWSCredentialsProvider"
19+
try:
20+
# Create the data source
21+
create_result = await session.call_tool(
22+
TigerGraphToolName.CREATE_DATA_SOURCE,
23+
arguments={
24+
"name": "data_source_1",
25+
"data_source_type": "s3",
26+
"access_key": "",
27+
"secret_key": "",
28+
"extra_config": {
29+
"file.reader.settings.fs.s3a.aws.credentials.provider": "org.apache.hadoop.fs.s3a.AnonymousAWSCredentialsProvider"
30+
},
2931
},
30-
},
31-
)
32-
assert "✅ Successfully created data source" in str(create_result)
32+
)
33+
assert "✅ Successfully created data source" in str(create_result)
3334

34-
try:
3535
# Get the data source
3636
get_result = await session.call_tool(
3737
TigerGraphToolName.GET_DATA_SOURCE,
38+
arguments={"name": "data_source_1"},
39+
)
40+
get_result_text = str(get_result)
41+
assert (
42+
"✅ Successfully retrieved configuration for data source"
43+
in get_result_text
44+
)
45+
46+
# Update the data source
47+
update_result = await session.call_tool(
48+
TigerGraphToolName.UPDATE_DATA_SOURCE,
3849
arguments={
3950
"name": "data_source_1",
51+
"data_source_type": "s3",
52+
"access_key": "updated-key",
53+
"secret_key": "updated-secret",
54+
"extra_config": {
55+
"file.reader.settings.fs.s3a.aws.credentials.provider": "org.apache.hadoop.fs.s3a.AnonymousAWSCredentialsProvider"
56+
},
4057
},
4158
)
42-
get_result_text = str(get_result)
43-
assert "✅ Successfully retrieved configuration for data source" in get_result_text
59+
assert "✅ Successfully updated data source" in str(update_result)
60+
61+
# Get the updated data source to verify
62+
get_updated_result = await session.call_tool(
63+
TigerGraphToolName.GET_DATA_SOURCE,
64+
arguments={"name": "data_source_1"},
65+
)
66+
get_updated_text = str(get_updated_result)
67+
assert (
68+
"✅ Successfully retrieved configuration for data source"
69+
in get_updated_text
70+
)
71+
assert "updated-key" in get_updated_text
72+
assert "updated-secret" in get_updated_text
4473

4574
# Preview sample data
4675
preview_result = await session.call_tool(
@@ -66,3 +95,52 @@ async def test_data_source_tools(self):
6695
arguments={"name": "data_source_1"},
6796
)
6897
assert "Successfully dropped data source" in str(drop_result)
98+
99+
@pytest.mark.asyncio
100+
async def test_data_source_list_and_drop_all(self):
101+
async with stdio_client(self.server_params) as (read, write):
102+
async with ClientSession(read, write) as session:
103+
await session.initialize()
104+
105+
# Create two data sources
106+
try:
107+
for i in [1, 2]:
108+
result = await session.call_tool(
109+
TigerGraphToolName.CREATE_DATA_SOURCE,
110+
arguments={
111+
"name": f"tmp_data_source_{i}",
112+
"data_source_type": "s3",
113+
"access_key": "",
114+
"secret_key": "",
115+
"extra_config": {
116+
"file.reader.settings.fs.s3a.aws.credentials.provider": "org.apache.hadoop.fs.s3a.AnonymousAWSCredentialsProvider"
117+
},
118+
},
119+
)
120+
assert (
121+
f"✅ Successfully created data source 'tmp_data_source_{i}'"
122+
in str(result)
123+
)
124+
125+
# Get all data sources
126+
get_all_result = await session.call_tool(
127+
TigerGraphToolName.GET_ALL_DATA_SOURCES,
128+
arguments={},
129+
)
130+
get_all_text = str(get_all_result)
131+
assert (
132+
"✅ Successfully retrieved all data sources:"
133+
in get_all_text
134+
)
135+
assert "tmp_data_source_1" in get_all_text
136+
assert "tmp_data_source_2" in get_all_text
137+
138+
finally:
139+
# Drop all data sources
140+
drop_all_result = await session.call_tool(
141+
TigerGraphToolName.DROP_ALL_DATA_SOURCES,
142+
arguments={},
143+
)
144+
assert "✅ All data sources is dropped successfully." in str(
145+
drop_all_result
146+
)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import pytest
2+
3+
from mcp import ClientSession
4+
from mcp.client.stdio import stdio_client
5+
6+
from tests.integration.base_graph_fixture import BaseFixture
7+
from tigergraph_mcp import TigerGraphToolName
8+
9+
10+
class TestGSQLTool(BaseFixture):
11+
@pytest.mark.asyncio
12+
async def test_gsql_tool(self):
13+
async with stdio_client(self.server_params) as (read, write):
14+
async with ClientSession(read, write) as session:
15+
await session.initialize()
16+
17+
result = await session.call_tool(
18+
TigerGraphToolName.GSQL,
19+
arguments={"command": "LS"},
20+
)
21+
22+
result_text = str(result)
23+
assert "✅ GSQL Response" in result_text
24+
assert "Graphs" in result_text or "Vertex Types" in result_text
25+
26+
@pytest.mark.asyncio
27+
async def test_list_metadata_tool(self):
28+
async with stdio_client(self.server_params) as (read, write):
29+
async with ClientSession(read, write) as session:
30+
await session.initialize()
31+
32+
# Test global metadata listing (no graph_name)
33+
result = await session.call_tool(
34+
TigerGraphToolName.LIST_METADATA,
35+
arguments={},
36+
)
37+
result_text = str(result)
38+
assert "✅ Successfully listed metadata" in result_text
39+
assert "Graphs" in result_text or "Vertex Types" in result_text

tigergraph_mcp/server.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,14 @@
4545
search,
4646
search_multi_vector_attributes,
4747
search_top_k_similar_nodes,
48+
gsql,
49+
list_metadata,
4850
create_data_source,
51+
update_data_source,
4952
get_data_source,
5053
drop_data_source,
54+
get_all_data_sources,
55+
drop_all_data_sources,
5156
preview_sample_data,
5257
)
5358

@@ -134,12 +139,22 @@ async def call_tool(name: str, arguments: Dict) -> List[TextContent]:
134139
return await search_multi_vector_attributes(**arguments)
135140
case TigerGraphToolName.SEARCH_TOP_K_SIMILAR_NODES:
136141
return await search_top_k_similar_nodes(**arguments)
142+
case TigerGraphToolName.GSQL:
143+
return await gsql(**arguments)
144+
case TigerGraphToolName.LIST_METADATA:
145+
return await list_metadata(**arguments)
137146
case TigerGraphToolName.CREATE_DATA_SOURCE:
138147
return await create_data_source(**arguments)
148+
case TigerGraphToolName.UPDATE_DATA_SOURCE:
149+
return await update_data_source(**arguments)
139150
case TigerGraphToolName.GET_DATA_SOURCE:
140151
return await get_data_source(**arguments)
141152
case TigerGraphToolName.DROP_DATA_SOURCE:
142153
return await drop_data_source(**arguments)
154+
case TigerGraphToolName.GET_ALL_DATA_SOURCES:
155+
return await get_all_data_sources(**arguments)
156+
case TigerGraphToolName.DROP_ALL_DATA_SOURCES:
157+
return await drop_all_data_sources(**arguments)
143158
case TigerGraphToolName.PREVIEW_SAMPLE_DATA:
144159
return await preview_sample_data(**arguments)
145160
case _:

tigergraph_mcp/tools/__init__.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,14 @@
4141
search_top_k_similar_nodes,
4242
)
4343
from .db import (
44+
gsql,
45+
list_metadata,
4446
create_data_source,
47+
update_data_source,
4548
get_data_source,
4649
drop_data_source,
50+
get_all_data_sources,
51+
drop_all_data_sources,
4752
preview_sample_data,
4853
)
4954

@@ -91,9 +96,15 @@
9196
"search",
9297
"search_multi_vector_attributes",
9398
"search_top_k_similar_nodes",
99+
# Tools for GSQL Operations
100+
"gsql",
101+
"list_metadata",
94102
# Tools for Data Source Operations
95103
"create_data_source",
104+
"update_data_source",
96105
"get_data_source",
97106
"drop_data_source",
107+
"get_all_data_sources",
108+
"drop_all_data_sources",
98109
"preview_sample_data",
99110
]

tigergraph_mcp/tools/db/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,27 @@
55
# Permission is granted to use, copy, modify, and distribute this software
66
# under the License. The software is provided "AS IS", without warranty.
77

8+
from .gsql import gsql, list_metadata
89
from .data_source import (
910
create_data_source,
11+
update_data_source,
1012
get_data_source,
1113
drop_data_source,
14+
get_all_data_sources,
15+
drop_all_data_sources,
1216
preview_sample_data,
1317
)
1418

1519
__all__ = [
20+
# Tools for GSQL Operations
21+
"gsql",
22+
"list_metadata",
1623
# Tools for Data Source Operations
1724
"create_data_source",
25+
"update_data_source",
1826
"get_data_source",
1927
"drop_data_source",
28+
"get_all_data_sources",
29+
"drop_all_data_sources",
2030
"preview_sample_data",
2131
]

tigergraph_mcp/tools/db/data_source/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,20 @@
66
# under the License. The software is provided "AS IS", without warranty.
77

88
from .create_data_source_tool import create_data_source
9+
from .update_data_source_tool import update_data_source
910
from .get_data_source_tool import get_data_source
1011
from .drop_data_source_tool import drop_data_source
12+
from .get_all_data_sources_tool import get_all_data_sources
13+
from .drop_all_data_sources_tool import drop_all_data_sources
1114
from .preview_sample_data_tool import preview_sample_data
1215

1316

1417
__all__ = [
1518
"create_data_source",
19+
"update_data_source",
1620
"get_data_source",
1721
"drop_data_source",
22+
"get_all_data_sources",
23+
"drop_all_data_sources",
1824
"preview_sample_data",
1925
]
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Copyright 2025 TigerGraph Inc.
2+
# Licensed under the Apache License, Version 2.0.
3+
# See the LICENSE file or https://www.apache.org/licenses/LICENSE-2.0
4+
#
5+
# Permission is granted to use, copy, modify, and distribute this software
6+
# under the License. The software is provided "AS IS", without warranty.
7+
8+
from typing import Optional, List
9+
from pydantic import Field, BaseModel
10+
from mcp.types import Tool, TextContent
11+
12+
from tigergraphx import TigerGraphDatabase
13+
from tigergraph_mcp.tools import TigerGraphToolName
14+
15+
16+
class DropAllDataSourcesToolInput(BaseModel):
17+
"""Input schema for dropping all data sources."""
18+
19+
graph_name: Optional[str] = Field(
20+
default=None,
21+
description="Optional graph name to scope the data source removal.",
22+
)
23+
24+
25+
tools = [
26+
Tool(
27+
name=TigerGraphToolName.DROP_ALL_DATA_SOURCES,
28+
description="""Drops all data sources in TigerGraph using TigerGraphX.
29+
30+
You may optionally scope the drop operation to a specific graph.
31+
32+
Example:
33+
```python
34+
graph_name = "MyGraph"
35+
```""",
36+
inputSchema=DropAllDataSourcesToolInput.model_json_schema(),
37+
)
38+
]
39+
40+
41+
async def drop_all_data_sources(
42+
graph_name: Optional[str] = None,
43+
) -> List[TextContent]:
44+
try:
45+
db = TigerGraphDatabase()
46+
result = db.drop_all_data_sources(graph_name=graph_name)
47+
48+
if "is dropped" in result or "is dropped successfully" in result:
49+
message = f"✅ {result}"
50+
else:
51+
message = f"⚠️ Attempted to drop all data sources but got unexpected response:\n{result}"
52+
53+
except Exception as e:
54+
message = f"❌ Error dropping all data sources: {str(e)}"
55+
56+
return [TextContent(type="text", text=message)]

0 commit comments

Comments
 (0)