|
| 1 | +--- |
| 2 | +sidebar_position: 7 |
| 3 | +slug: /MCP server |
| 4 | +--- |
| 5 | + |
| 6 | +# Overview of RAGFlow Model Context Protocol (MCP) Server |
| 7 | + |
| 8 | +The RAGFlow MCP server operates as an independent component that complements the RAGFlow server. However, it requires a RAGFlow server to work functionally well, meaning, the MCP client and server communicate with each other in MCP HTTP+SSE mode (once the connection is established, server pushes messages to client only), and responses are expected from RAGFlow server. |
| 9 | + |
| 10 | +The MCP server currently offers a specific tool to assist users in searching for relevant information powered by RAGFlow DeepDoc technology: |
| 11 | + |
| 12 | +• **retrieve**: Fetches relevant chunks from specified `dataset_ids` and optional `document_ids` using the RAGFlow retrieve interface, based on a given question. Details of all available datasets, namely, `id` and `description`, are provided within the tool description for each individual dataset. |
| 13 | + |
| 14 | +## Launching the MCP Server |
| 15 | + |
| 16 | +Similar to launching the RAGFlow server, the MCP server can be started either from source code or via Docker. |
| 17 | + |
| 18 | +### Launching from Source Code |
| 19 | + |
| 20 | +All you need to do is stand on the right place and strike out command, assuming you are on the project working directory. |
| 21 | + |
| 22 | +```bash |
| 23 | +uv run mcp/server/server.py --host=127.0.0.1 --port=9382 --base_url=http://127.0.0.1:9380 |
| 24 | +``` |
| 25 | + |
| 26 | +For testing purposes, there is an [MCP client example](#example_mcp_client) provided, free to take! |
| 27 | + |
| 28 | +#### Required Arguments |
| 29 | + |
| 30 | +• **`host`**: Specifies the server's host address. |
| 31 | +• **`port`**: Defines the server's listening port. |
| 32 | +• **`base_url`**: The address of the RAGFlow server that is already running and ready to handle tasks. |
| 33 | + |
| 34 | +Here are three augments required, the first two,`host` and `port`, are self-explained. The`base_url` is the address of the ready-to-serve RAGFlow server to actually perform the task. |
| 35 | + |
| 36 | +### Launching from Docker |
| 37 | + |
| 38 | +Building a standalone MCP server image is straightforward and easy, so we just proposed a way to launch it with RAGFlow server here. |
| 39 | + |
| 40 | +#### Alongside RAGFlow |
| 41 | + |
| 42 | +As MCP server is an extra and optional component of RAGFlow server, we consume that not everybody going to use it. Thus, it is disable by default. |
| 43 | +To enable it, simply find `docker/docker-compose.yml` to uncomment `services.ragflow.command` section. |
| 44 | + |
| 45 | +```yaml |
| 46 | +services: |
| 47 | + ragflow: |
| 48 | + ... |
| 49 | + image: ${RAGFLOW_IMAGE} |
| 50 | + # example to setup MCP server |
| 51 | + command: |
| 52 | + - --enable-mcpserver |
| 53 | + - --mcp-host=0.0.0.0 |
| 54 | + - --mcp-port=9382 |
| 55 | + - --mcp-base-url=http://127.0.0.1:9380 |
| 56 | + - --mcp-script-path=/ragflow/mcp/server/server.py |
| 57 | +``` |
| 58 | +
|
| 59 | +Then launch it normally `docker compose -f docker-compose.yml`. |
| 60 | + |
| 61 | +```bash |
| 62 | +ragflow-server | Starting MCP Server on 0.0.0.0:9382 with base URL http://127.0.0.1:9380... |
| 63 | +ragflow-server | Starting 1 task executor(s) on host 'dd0b5e07e76f'... |
| 64 | +ragflow-server | 2025-04-18 15:41:18,816 INFO 27 ragflow_server log path: /ragflow/logs/ragflow_server.log, log levels: {'peewee': 'WARNING', 'pdfminer': 'WARNING', 'root': 'INFO'} |
| 65 | +ragflow-server | |
| 66 | +ragflow-server | __ __ ____ ____ ____ _____ ______ _______ ____ |
| 67 | +ragflow-server | | \/ |/ ___| _ \ / ___|| ____| _ \ \ / / ____| _ \ |
| 68 | +ragflow-server | | |\/| | | | |_) | \___ \| _| | |_) \ \ / /| _| | |_) | |
| 69 | +ragflow-server | | | | | |___| __/ ___) | |___| _ < \ V / | |___| _ < |
| 70 | +ragflow-server | |_| |_|\____|_| |____/|_____|_| \_\ \_/ |_____|_| \_\ |
| 71 | +ragflow-server | |
| 72 | +ragflow-server | MCP host: 0.0.0.0 |
| 73 | +ragflow-server | MCP port: 9382 |
| 74 | +ragflow-server | MCP base_url: http://127.0.0.1:9380 |
| 75 | +ragflow-server | INFO: Started server process [26] |
| 76 | +ragflow-server | INFO: Waiting for application startup. |
| 77 | +ragflow-server | INFO: Application startup complete. |
| 78 | +ragflow-server | INFO: Uvicorn running on http://0.0.0.0:9382 (Press CTRL+C to quit) |
| 79 | +ragflow-server | 2025-04-18 15:41:20,469 INFO 27 found 0 gpus |
| 80 | +ragflow-server | 2025-04-18 15:41:23,263 INFO 27 init database on cluster mode successfully |
| 81 | +ragflow-server | 2025-04-18 15:41:25,318 INFO 27 load_model /ragflow/rag/res/deepdoc/det.onnx uses CPU |
| 82 | +ragflow-server | 2025-04-18 15:41:25,367 INFO 27 load_model /ragflow/rag/res/deepdoc/rec.onnx uses CPU |
| 83 | +ragflow-server | ____ ___ ______ ______ __ |
| 84 | +ragflow-server | / __ \ / | / ____// ____// /____ _ __ |
| 85 | +ragflow-server | / /_/ // /| | / / __ / /_ / // __ \| | /| / / |
| 86 | +ragflow-server | / _, _// ___ |/ /_/ // __/ / // /_/ /| |/ |/ / |
| 87 | +ragflow-server | /_/ |_|/_/ |_|\____//_/ /_/ \____/ |__/|__/ |
| 88 | +ragflow-server | |
| 89 | +ragflow-server | |
| 90 | +ragflow-server | 2025-04-18 15:41:29,088 INFO 27 RAGFlow version: v0.17.2-285-gb2c299fa full |
| 91 | +ragflow-server | 2025-04-18 15:41:29,088 INFO 27 project base: /ragflow |
| 92 | +ragflow-server | 2025-04-18 15:41:29,088 INFO 27 Current configs, from /ragflow/conf/service_conf.yaml: |
| 93 | +ragflow-server | ragflow: {'host': '0.0.0.0', 'http_port': 9380} |
| 94 | +... |
| 95 | +ragflow-server | * Running on all addresses (0.0.0.0) |
| 96 | +ragflow-server | * Running on http://127.0.0.1:9380 |
| 97 | +ragflow-server | * Running on http://172.19.0.6:9380 |
| 98 | +ragflow-server | ______ __ ______ __ |
| 99 | +ragflow-server | /_ __/___ ______/ /__ / ____/ _____ _______ __/ /_____ _____ |
| 100 | +ragflow-server | / / / __ `/ ___/ //_/ / __/ | |/_/ _ \/ ___/ / / / __/ __ \/ ___/ |
| 101 | +ragflow-server | / / / /_/ (__ ) ,< / /____> </ __/ /__/ /_/ / /_/ /_/ / / |
| 102 | +ragflow-server | /_/ \__,_/____/_/|_| /_____/_/|_|\___/\___/\__,_/\__/\____/_/ |
| 103 | +ragflow-server | |
| 104 | +ragflow-server | 2025-04-18 15:41:34,501 INFO 32 TaskExecutor: RAGFlow version: v0.17.2-285-gb2c299fa full |
| 105 | +ragflow-server | 2025-04-18 15:41:34,501 INFO 32 Use Elasticsearch http://es01:9200 as the doc engine. |
| 106 | +... |
| 107 | +``` |
| 108 | + |
| 109 | +You are ready to brew🍺! |
| 110 | + |
| 111 | +## Testing and Usage |
| 112 | + |
| 113 | +Typically, there are various ways to utilize an MCP server. You can integrate it with LLMs or use it as a standalone tool. You find the way. |
| 114 | + |
| 115 | +### Example MCP Client {#example_mcp_client} |
| 116 | + |
| 117 | +```python |
| 118 | +# |
| 119 | +# Copyright 2025 The InfiniFlow Authors. All Rights Reserved. |
| 120 | +# |
| 121 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 122 | +# you may not use this file except in compliance with the License. |
| 123 | +# You may obtain a copy of the License at |
| 124 | +# |
| 125 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 126 | +# |
| 127 | +# Unless required by applicable law or agreed to in writing, software |
| 128 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 129 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 130 | +# See the License for the specific language governing permissions and |
| 131 | +# limitations under the License. |
| 132 | +# |
| 133 | +from mcp.client.session import ClientSession |
| 134 | +from mcp.client.sse import sse_client |
| 135 | + |
| 136 | + |
| 137 | +async def main(): |
| 138 | + try: |
| 139 | + async with sse_client("http://localhost:9382/sse", headers={"api_key": "ragflow-IyMGI1ZDhjMTA2ZTExZjBiYTMyMGQ4Zm"}) as streams: |
| 140 | + async with ClientSession( |
| 141 | + streams[0], |
| 142 | + streams[1], |
| 143 | + ) as session: |
| 144 | + await session.initialize() |
| 145 | + tools = await session.list_tools() |
| 146 | + print(f"{tools.tools=}") |
| 147 | + response = await session.call_tool(name="ragflow_retrival", arguments={"dataset_ids": ["ce3bb17cf27a11efa69751e139332ced"], "document_ids": [], "question": "How to install neovim?"}) |
| 148 | + print(f"Tool response: {response.model_dump()}") |
| 149 | + |
| 150 | + except Exception as e: |
| 151 | + print(e) |
| 152 | + |
| 153 | + |
| 154 | +if __name__ == "__main__": |
| 155 | + from anyio import run |
| 156 | + |
| 157 | + run(main) |
| 158 | +``` |
| 159 | + |
| 160 | +## Security and Concerns |
| 161 | + |
| 162 | +Since MCP technology is still in booming age and there are still no official Authentication and Authorization best practices to follow, RAGFlow uses `api_key` to validate the identification, and it is required to perform any operations mentioned in the preview section. Obviously, this is not a premium solution to do so, thus this RAGFlow MCP server is not expected to exposed to public use as it could be highly venerable to be attacked. For local SSE server, bind only to localhost (127.0.0.1) instead of all interfaces (0.0.0.0). For additional guidance, you can refer to [MCP official website](https://modelcontextprotocol.io/docs/concepts/transports#security-considerations). |
0 commit comments