Server Introduction
In a typical RAG system, the overall workflow usually consists of multiple functional modules, such as the Retriever and the Generator. Each module is responsible for a specific task, and they work together through pipeline orchestration to complete complex question-answering and reasoning processes. In UR-2.0, we adopt the MCP (Model Context Protocol) architecture to standardize and encapsulate these functional modules into a unified implementation—Server.A Server is essentially an independent RAG module component with a specific function.
Server Development
To help you better understand how to use Servers, this section demonstrates a complete workflow for developing a custom Server from scratch.Step 1: Create the Server File
First, create a new folder namedsayhello under the servers directory, and then create a source folder sayhello/src inside it. Next, create a file named sayhello.py in the src directory—this will serve as the main entry point for the Server.
In UR-2.0, all Servers are instantiated via the UltraRAG_MCP_Server base class. Example:
servers/sayhello/src/sayhello.py
Step 2: Implement Tool Functions
Use the@app.tool decorator to register tool functions (Tools). These functions are invoked during Pipeline execution to perform specific logic.
For example, the following code defines a simple greeting function greet, which takes a name as input and returns a greeting message:
servers/sayhello/src/sayhello.py
Step 3: Configure Parameter File
Next, create a parameter configuration file namedparameter.yaml under the sayhello folder.This file declares the input parameters required by each Tool and their default values, allowing automatic loading and passing during Pipeline execution. Example:
name with the default value "UltraRAG 2.0".
Parameter Registration Mechanism
If different Prompt Tools have conflicting parameter names, refer to the “Multiple Prompt Tool Invocation” section in the Prompt Server documentation for resolution.
parameter.yaml file to detect and register the parameters required by its Tool functions.When using this mechanism, keep the following points in mind:
- Parameter Sharing: When multiple Tools need to share a parameter (e.g.,
template,model_name_or_path), you only need to declare it once inparameter.yaml, and it can be reused across Tools. - Field Overriding Risks: If multiple Tools use the same parameter name but with different meanings or default values, you should explicitly distinguish them by using different field names to prevent unintentional overwriting in the automatically generated configuration file.
- Automatic Context Inference: If a Tool’s input parameter is not defined in
parameter.yaml, UR-2.0 will attempt to infer its value from the runtime context (i.e., from the output of upstream Tools). Therefore, only explicitly define parameters inparameter.yamlwhen they cannot be automatically inferred.
Encapsulating Shared Variables with Classes
In some scenarios, you may want to maintain shared states or variables within the same Server—for example, model instances, cache objects, or configuration settings.In such cases, you can encapsulate the Server as a class and define shared variables and Tool registrations during initialization. The following example shows how to encapsulate the
sayhello Server as a class to share internal variables:
servers/sayhello/src/sayhello.py
self.sen simulates a shared variable that can be accessed by different Tools within the same Server.This approach is especially useful when loading models or maintaining configurations that are reused across multiple functions.