Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,8 @@ data/minio/
minio-data/
backend/minio-data/

# Test data (generated samples)
test_data/

# Legacy S3 Mock Storage (deprecated)
mocks/s3-mock/s3-mock-storage/
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ A modern LLM chat interface with MCP (Model Context Protocol) integration.
* **Multi-LLM Support**: Connect to various LLM providers.
* **MCP Integration**: Extend the AI's capabilities with custom tools.
* **RAG Support**: Enhance responses with Retrieval-Augmented Generation.
* **3D Visualization**: Render engineering and scientific files with VTK.js (STL, VTK, OBJ, PLY, and more).
* **Secure and Configurable**: Features group-based access control, compliance levels, and a tool approval system.
* **Modern Stack**: Built with React 19, FastAPI, and WebSockets.

Expand All @@ -33,6 +34,8 @@ We have created a set of comprehensive guides to help you get the most out of At

* **[Developer's Guide](./docs/03_developer_guide.md)**: For developers who want to contribute to the project. It provides an overview of the architecture and instructions for creating new MCP servers.

* **[VTK Visualization Guide](./docs/VTK_VISUALIZATION.md)**: Learn about the 3D visualization capabilities using VTK.js. This guide covers supported file formats (VTK, STL, OBJ, PLY, etc.) and interactive features.

## For AI Agent Contributors

If you are an AI agent working on this repository, please refer to the following documents for the most current and concise guidance:
Expand Down
7 changes: 6 additions & 1 deletion backend/application/chat/utilities/tool_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,15 @@ async def execute_single_tool(
edited_args = response["arguments"]
# Check if arguments actually changed by comparing with what we sent (display_args)
# Use json comparison to avoid false positives from dict ordering
if json.dumps(edited_args, sort_keys=True) != json.dumps(original_display_args, sort_keys=True):
original_json = json.dumps(original_display_args, sort_keys=True, separators=(',', ':'))
edited_json = json.dumps(edited_args, sort_keys=True, separators=(',', ':'))

if original_json != edited_json:
arguments_were_edited = True
filtered_args = edited_args
logger.info(f"User edited arguments for tool {tool_call.function.name}")
logger.debug(f"Original: {original_json}")
logger.debug(f"Edited: {edited_json}")
else:
# No actual changes, but response included arguments - keep original filtered_args
logger.debug(f"Arguments returned unchanged for tool {tool_call.function.name}")
Expand Down
12 changes: 12 additions & 0 deletions backend/mcp/vtk-example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Generated sample files
samples/
test_output/
*.vtk
*.stl
*.obj
*.ply

# Python cache
__pycache__/
*.pyc
*.pyo
171 changes: 171 additions & 0 deletions backend/mcp/vtk-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# VTK Example MCP Server

A demonstration MCP server that generates 3D geometric shapes in VTK and STL formats for visualization in the Atlas UI canvas panel.

## Overview

This MCP server showcases how to create and return VTK-compatible 3D files that will be automatically rendered using VTK.js in the Atlas UI canvas. It's perfect for testing the 3D visualization capabilities and serves as a reference implementation for other tools that need to generate 3D content.

## Features

- **Multiple Shape Generation**: Create cubes, spheres, pyramids, cylinders, and tori
- **Format Support**: Generate files in VTK legacy ASCII or STL format
- **Progress Reporting**: Real-time feedback during generation
- **Artifact System**: Files automatically appear in canvas with 3D viewer
- **Batch Generation**: Create multiple sample files at once

## Tools

### `generate_3d_shape`

Generate a single 3D geometric shape.

**Parameters:**
- `shape` (string): The shape to generate
- `"cube"` - Simple 1x1x1 unit cube
- `"sphere"` - Parametric sphere (radius 1.0)
- `"pyramid"` - Four-sided pyramid
- `"cylinder"` - Circular cylinder (radius 0.5, height 2.0)
- `"torus"` - Donut shape (major radius 1.0, minor radius 0.3)
- `return_format` (string): Output format
- `"vtk"` - VTK legacy ASCII format (default)
- `"stl"` - STereoLithography ASCII format (pyramid only)

**Example Usage:**
```
Generate a sphere in VTK format
Generate a torus and display it
Create a cylinder for visualization
```

**Returns:**
The generated file as an artifact that automatically opens in the canvas panel with the VTK.js 3D viewer.

### `generate_sample_files`

Generate a collection of sample 3D files for testing.

**Parameters:**
None

**Example Usage:**
```
Generate sample 3D files
Show me some VTK examples
Create test shapes for visualization
```

**Returns:**
Five different 3D shapes (cube, sphere, pyramid, cylinder, torus) as artifacts. The sphere is displayed first, and you can navigate between files using the canvas panel controls.

## Technical Details

### File Formats

**VTK Legacy Format (.vtk)**
- ASCII text format
- Human-readable
- Widely compatible with scientific visualization tools
- Supports polygonal data (POLYDATA)

**STL Format (.stl)**
- ASCII text format
- Common in 3D printing and CAD
- Represents surfaces as triangular meshes
- Includes surface normals

### Shape Generation

All shapes are generated programmatically using parametric equations:

- **Sphere**: Uses spherical coordinates (u, v) with configurable resolution
- **Cylinder**: Combines circular profiles with side quads and triangle caps
- **Torus**: Uses toroidal coordinates for donut shape
- **Cube/Pyramid**: Simple vertex and face definitions

### Integration with Canvas

The server uses the MCP artifact system to return files:

```python
{
"artifacts": [
{
"name": "sphere.vtk",
"b64": base64_encoded_content,
"mime": "application/octet-stream",
"viewer": "vtk"
}
],
"display": {
"open_canvas": True,
"primary_file": "sphere.vtk",
"viewer_hint": "vtk"
}
}
```

This automatically:
1. Opens the canvas panel
2. Decodes the base64 content
3. Detects the file type based on extension
4. Renders in the VTK.js viewer with interactive controls

## Configuration

To add this server to Atlas UI, add an entry to your MCP configuration:

```json
{
"name": "vtk-example",
"transport": "stdio",
"command": "python",
"args": ["backend/mcp/vtk-example/main.py"],
"cwd": "backend/mcp/vtk-example",
"groups": ["user"],
"description": "Generate 3D shapes for VTK visualization"
}
```

## Development

### Running Standalone

```bash
python main.py
```

### Testing

You can test the server using the FastMCP inspector:

```bash
fastmcp inspect main.py
```

### Adding New Shapes

To add a new shape:

1. Create a generator function that returns VTK or STL format string
2. Add the shape to the `shape` parameter's Literal type
3. Add a case in the `generate_3d_shape` function
4. Update documentation

Example:
```python
def generate_cone_vtk(radius: float = 1.0, height: float = 2.0) -> str:
# Implementation here
pass
```

## References

- [VTK File Formats](https://vtk.org/wp-content/uploads/2015/04/file-formats.pdf)
- [STL Format Specification](https://en.wikipedia.org/wiki/STL_(file_format))
- [FastMCP Documentation](https://github.com/jlowin/fastmcp)
- [VTK.js Documentation](https://kitware.github.io/vtk-js/)

## License

Same as Atlas UI project (MIT License)
168 changes: 168 additions & 0 deletions backend/mcp/vtk-example/generate_samples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#!/usr/bin/env python3
"""
Simple script to generate sample VTK files for testing the VTK viewer.

This script creates basic 3D shapes in VTK legacy ASCII and STL formats
that can be used to test the VTK.js rendering capabilities.

Usage:
python generate_samples.py [output_directory]

If no output directory is specified, files are created in a 'samples' folder.
"""

def generate_simple_cube_vtk():
"""Generate a simple cube in VTK legacy format."""
vtk_content = """# vtk DataFile Version 3.0
Simple Cube for Testing
ASCII
DATASET POLYDATA
POINTS 8 float
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 1.0
1.0 0.0 1.0
1.0 1.0 1.0
0.0 1.0 1.0

POLYGONS 6 30
4 0 1 2 3
4 4 5 6 7
4 0 1 5 4
4 2 3 7 6
4 0 3 7 4
4 1 2 6 5
"""
return vtk_content


def generate_simple_sphere_vtk():
"""Generate a simple sphere using parametric equations."""
import math

# Sphere parameters
radius = 1.0
u_resolution = 20
v_resolution = 20

points = []
polygons = []

# Generate points
for i in range(u_resolution + 1):
u = (i / u_resolution) * 2 * math.pi
for j in range(v_resolution + 1):
v = (j / v_resolution) * math.pi
x = radius * math.sin(v) * math.cos(u)
y = radius * math.sin(v) * math.sin(u)
z = radius * math.cos(v)
points.append(f"{x:.6f} {y:.6f} {z:.6f}")

# Generate polygons (quads)
for i in range(u_resolution):
for j in range(v_resolution):
p0 = i * (v_resolution + 1) + j
p1 = (i + 1) * (v_resolution + 1) + j
p2 = (i + 1) * (v_resolution + 1) + (j + 1)
p3 = i * (v_resolution + 1) + (j + 1)
polygons.append(f"4 {p0} {p1} {p2} {p3}")

vtk_content = f"""# vtk DataFile Version 3.0
Simple Sphere for Testing
ASCII
DATASET POLYDATA
POINTS {len(points)} float
{chr(10).join(points)}

POLYGONS {len(polygons)} {len(polygons) * 5}
{chr(10).join(polygons)}
"""
return vtk_content


def generate_sample_stl():
"""Generate a simple pyramid in STL ASCII format."""
stl_content = """solid SimplePyramid
facet normal 0.0 -0.8944271909999159 0.4472135954999579
outer loop
vertex 0.0 0.0 0.0
vertex 1.0 0.0 0.0
vertex 0.5 0.5 1.0
endloop
endfacet
facet normal 0.8944271909999159 0.0 0.4472135954999579
outer loop
vertex 1.0 0.0 0.0
vertex 1.0 1.0 0.0
vertex 0.5 0.5 1.0
endloop
endfacet
facet normal 0.0 0.8944271909999159 0.4472135954999579
outer loop
vertex 1.0 1.0 0.0
vertex 0.0 1.0 0.0
vertex 0.5 0.5 1.0
endloop
endfacet
facet normal -0.8944271909999159 0.0 0.4472135954999579
outer loop
vertex 0.0 1.0 0.0
vertex 0.0 0.0 0.0
vertex 0.5 0.5 1.0
endloop
endfacet
facet normal 0.0 0.0 -1.0
outer loop
vertex 0.0 0.0 0.0
vertex 1.0 1.0 0.0
vertex 1.0 0.0 0.0
endloop
endfacet
facet normal 0.0 0.0 -1.0
outer loop
vertex 0.0 0.0 0.0
vertex 0.0 1.0 0.0
vertex 1.0 1.0 0.0
endloop
endfacet
endsolid SimplePyramid
"""
return stl_content


if __name__ == "__main__":
import sys
import os

# Allow output directory to be specified
output_dir = sys.argv[1] if len(sys.argv) > 1 else "samples"

# Create output directory if it doesn't exist
os.makedirs(output_dir, exist_ok=True)

# Generate cube
cube_file = os.path.join(output_dir, "cube.vtk")
with open(cube_file, "w") as f:
f.write(generate_simple_cube_vtk())
print(f"Generated: {cube_file}")

# Generate sphere
sphere_file = os.path.join(output_dir, "sphere.vtk")
with open(sphere_file, "w") as f:
f.write(generate_simple_sphere_vtk())
print(f"Generated: {sphere_file}")

# Generate pyramid STL
pyramid_file = os.path.join(output_dir, "pyramid.stl")
with open(pyramid_file, "w") as f:
f.write(generate_sample_stl())
print(f"Generated: {pyramid_file}")

print("\nSample VTK files generated successfully!")
print(f"Files are located in: {output_dir}")
print("\nYou can use these files to test the VTK viewer:")
print("1. Upload via chat interface")
print("2. Ask the AI to visualize them in the canvas")
print("3. Use the vtk-example MCP server to generate them dynamically")
Loading
Loading