feat(mcp): add ragflow_list_datasets and ragflow_list_chats tools (#15384)

## Summary

Add two new MCP tools to the RAGFlow MCP server:

1. **ragflow_list_datasets** - List all accessible datasets with IDs,
names, descriptions
2. **ragflow_list_chats** - List all accessible chat assistants with
IDs, names, descriptions

### Implementation
- Added `list_chats()` method to `RAGFlowConnector`
- Registered both tools in `list_tools()` and `call_tool()`
- Follows existing `ragflow_retrieval` pattern for error handling

### Usage via langchain-mcp-adapters

---------

Co-authored-by: saltsalt123 <saltsalt123@users.noreply.github.com>
Co-authored-by: yzc <yuzhichang@gmail.com>
This commit is contained in:
saltsalt123
2026-07-01 09:36:52 +08:00
committed by GitHub
parent 06b07bbfd6
commit f60245f199

View File

@@ -163,6 +163,33 @@ class RAGFlowConnector:
return res_json
async def list_chats(self, *, api_key: str, page: int = 1, page_size: int = 30, orderby: str = "create_time", desc: bool = True):
"""Return accessible chat assistants as newline-delimited JSON for MCP tool descriptions."""
logging.info("Listing chat assistants via MCP (page=%s, page_size=%s)", page, page_size)
params = {"page": page, "page_size": page_size, "orderby": orderby, "desc": json.dumps(desc)}
res = await self._get("/chats", params, api_key=api_key)
if not res or res.status_code != 200:
error_message = None
if res is not None:
try:
error_message = res.json().get("message")
logging.warning("list_chats request failed: status=%s message=%s", res.status_code, error_message)
except Exception:
error_message = None
logging.warning("list_chats request failed: status=%s (parse error)", res.status_code)
raise Exception([types.TextContent(type="text", text=error_message or "Cannot list chats.")])
res_json = res.json()
if res_json.get("code") != 0:
logging.warning("list_chats API error: code=%s message=%s", res_json.get("code"), res_json.get("message"))
raise Exception([types.TextContent(type="text", text=res_json.get("message", "Cannot list chats."))])
chat_count = len(res_json.get("data", []))
logging.info("list_chats returned %d chat(s)", chat_count)
result_list = []
for data in res_json.get("data", []):
d = {"id": data.get("id"), "name": data.get("name"), "description": data.get("description", "")}
result_list.append(json.dumps(d, ensure_ascii=False))
return "\n".join(result_list)
async def _fetch_all_datasets(
self,
*,
@@ -506,6 +533,7 @@ def with_api_key(required: bool = True):
@with_api_key(required=True)
async def list_tools(*, connector: RAGFlowConnector, api_key: str) -> list[types.Tool]:
dataset_description = await connector.list_datasets(api_key=api_key)
chat_description = await connector.list_chats(api_key=api_key)
return [
types.Tool(
@@ -570,6 +598,52 @@ async def list_tools(*, connector: RAGFlowConnector, api_key: str) -> list[types
"required": ["question"],
},
),
types.Tool(
name="ragflow_list_datasets",
description="List all accessible datasets (knowledge bases) in RAGFlow. Returns dataset IDs, names, and descriptions. Use this tool to discover which datasets are available before performing retrieval."
+ dataset_description,
inputSchema={
"type": "object",
"properties": {
"page": {
"type": "integer",
"description": "Page number",
"default": 1,
"minimum": 1,
},
"page_size": {
"type": "integer",
"description": "Results per page",
"default": 100,
"minimum": 1,
"maximum": 1000,
},
},
},
),
types.Tool(
name="ragflow_list_chats",
description="List all accessible chat assistants in RAGFlow. Returns chat assistant IDs, names, and descriptions. Use this tool to discover available chat assistants that can be used for conversations."
+ chat_description,
inputSchema={
"type": "object",
"properties": {
"page": {
"type": "integer",
"description": "Page number",
"default": 1,
"minimum": 1,
},
"page_size": {
"type": "integer",
"description": "Results per page",
"default": 30,
"minimum": 1,
"maximum": 100,
},
},
},
),
]
@@ -609,6 +683,19 @@ async def call_tool(
rerank_id=rerank_id,
force_refresh=force_refresh,
)
if name == "ragflow_list_datasets":
page = arguments.get("page", 1)
page_size = arguments.get("page_size", 100)
result = await connector.list_datasets(api_key=api_key, page=page, page_size=page_size)
return [types.TextContent(type="text", text=result)]
if name == "ragflow_list_chats":
page = arguments.get("page", 1)
page_size = arguments.get("page_size", 30)
result = await connector.list_chats(api_key=api_key, page=page, page_size=page_size)
return [types.TextContent(type="text", text=result)]
raise ValueError(f"Tool not found: {name}")