merge
Update specific fields in database records without affecting other data. Perform partial updates by modifying only the provided fields while preserving all other record information.
Instructions
Merge data into a specific record, updating only the specified fields.
This tool performs a partial update, only modifying the fields provided in the data parameter. All other fields remain unchanged. This is useful when you want to:
Update specific fields without affecting others
Add new fields to an existing record
Modify nested properties without replacing the entire object
Args: thing: The full record ID to merge data into in format "table:id" (e.g., "user:john") data: Dictionary containing only the fields to update. Examples: - {"email": "newemail@example.com"} - updates only email - {"profile": {"bio": "New bio"}} - updates nested field - {"tags": ["python", "mcp"]} - replaces the tags array
Returns: A dictionary containing: - success: Boolean indicating if merge was successful - data: The complete record after merging, with all fields - modified_fields: List of field names that were modified - error: Error message if merge failed (only present on failure)
Examples: >>> await merge("user:john", {"email": "john.new@example.com", "verified": true}) { "success": true, "data": {"id": "user:john", "name": "John Doe", "email": "john.new@example.com", "verified": true, "age": 30}, "modified_fields": ["email", "verified"] }
Note: This is equivalent to the 'patch' tool but uses object merging syntax instead of JSON Patch.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | ||
| thing | Yes |
Implementation Reference
- surreal_mcp/server.py:422-495 (handler)The handler function implementing the 'merge' tool logic. Registered as an MCP tool via @mcp.tool(). Performs partial update by calling repo_upsert with MERGE semantics, preserving unmodified fields.@mcp.tool() async def merge( thing: str, data: Dict[str, Any], namespace: Optional[str] = None, database: Optional[str] = None, ) -> Dict[str, Any]: """ Merge data into a specific record, updating only the specified fields. This tool performs a partial update, only modifying the fields provided in the data parameter. All other fields remain unchanged. This is useful when you want to: - Update specific fields without affecting others - Add new fields to an existing record - Modify nested properties without replacing the entire object Args: thing: The full record ID to merge data into in format "table:id" (e.g., "user:john") data: Dictionary containing only the fields to update. Examples: - {"email": "newemail@example.com"} - updates only email - {"profile": {"bio": "New bio"}} - updates nested field - {"tags": ["python", "mcp"]} - replaces the tags array namespace: Optional SurrealDB namespace override. If not provided, uses SURREAL_NAMESPACE env var. database: Optional SurrealDB database override. If not provided, uses SURREAL_DATABASE env var. Returns: A dictionary containing: - success: Boolean indicating if merge was successful - data: The complete record after merging, with all fields - modified_fields: List of field names that were modified - error: Error message if merge failed (only present on failure) Examples: >>> await merge("user:john", {"email": "john.new@example.com", "verified": true}) { "success": true, "data": {"id": "user:john", "name": "John Doe", "email": "john.new@example.com", "verified": true, "age": 30}, "modified_fields": ["email", "verified"] } Note: This is equivalent to the 'patch' tool but uses object merging syntax instead of JSON Patch. """ try: ns, db = resolve_namespace_database(namespace, database) # Validate thing format if ":" not in thing: raise ValueError(f"Invalid record ID format: {thing}. Must be 'table:id'") logger.info(f"Merging data into {thing}") # Track which fields we're modifying modified_fields = list(data.keys()) # Extract table name for repo_upsert table = thing.split(":", 1)[0] # Use repo_upsert which does a MERGE operation - pass full record ID result = await repo_upsert( table=table, id=thing, data=data, add_timestamp=True, namespace=ns, database=db ) # Get the first result merged_record = result[0] if result else {} return { "success": True, "data": merged_record, "modified_fields": modified_fields } except Exception as e: logger.error(f"Merge failed for {thing}: {str(e)}") raise Exception(f"Failed to merge data into {thing}: {str(e)}")
- Core helper function executing the SurrealQL 'UPSERT ... MERGE $data' query, which performs the partial merge update used by the 'merge' tool.async def repo_upsert( table: str, id: Optional[str], data: Dict[str, Any], add_timestamp: bool = False, namespace: Optional[str] = None, database: Optional[str] = None, ) -> List[Dict[str, Any]]: """Create or update a record in the specified table. Args: table: The table name id: Optional record ID (if provided, upserts that specific record) data: The record data to upsert add_timestamp: Whether to add/update the 'updated' timestamp namespace: Optional namespace override (uses env var if not provided) database: Optional database override (uses env var if not provided) Returns: The upserted record(s) """ data.pop("id", None) if add_timestamp: data["updated"] = datetime.now(timezone.utc) query = f"UPSERT {id if id else table} MERGE $data;" return await repo_query(query, {"data": data}, namespace=namespace, database=database)
- surreal_mcp/server.py:422-422 (registration)The @mcp.tool() decorator registers the merge function as an MCP tool.@mcp.tool()