How to Chain the MCP 3D-Relief Tool with Other Model Context Protocol Servers

You can chain the MCP 3D-Relief tool with other Model Context Protocol servers by leveraging its stdio transport and FastMCP wrapper, which enables subprocess-based piping of JSON-RPC messages between discrete processing units.

The bigchx/mcp_3d_relief repository implements a Model Context Protocol (MCP) tool that converts 2D images into 3D relief STL files using FastAPI and FastMCP. Because it communicates via standard input and output using JSON-RPC, you can chain this MCP tool with other Model Context Protocol servers to build complex, multi-stage processing pipelines that treat each tool as a composable transformation step.

Understanding the MCP Architecture in 3D-Relief

The core MCP integration resides in server.py, where the application wraps a FastAPI service with FastMCP to expose stdio-based JSON-RPC communication.

FastAPI to MCP Conversion

The file defines a /convert endpoint (lines 16-55) that accepts image parameters and delegates processing to the relief coroutine from relief.py. After defining routes, the application converts the FastAPI instance into an MCP tool using:

mcp = FastMCP.from_fastapi(app, "mcp_3d_relief")
mcp.run(transport="stdio")

This pattern (lines 58-61) registers all FastAPI routes as MCP methods and initiates the stdio transport, enabling the tool to read JSON-RPC requests from stdin and write responses to stdout.

Chaining MCP Servers via Standard I/O

Because the 3D-Relief tool uses stdio transport, you can chain it with other Model Context Protocol servers by managing subprocesses and piping their standard streams. This architecture treats each MCP server as a composable unit in a larger pipeline.

Sequential Processing Pipeline

To chain the 3D-Relief tool with a downstream MCP server (such as a mesh simplifier), launch both as subprocesses and forward the output from the first to the second:

import subprocess
import json
import sys

# Launch 3D-Relief MCP server

relief_proc = subprocess.Popen(
    [sys.executable, "server.py"],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    text=True
)

# Launch second MCP server (e.g., mesh simplifier)

simplify_proc = subprocess.Popen(
    [sys.executable, "mesh_simplify.py"],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    text=True
)

def mcp_call(process, method, params, req_id=1):
    request = json.dumps({
        "jsonrpc": "2.0",
        "method": method,
        "params": params,
        "id": req_id
    })
    process.stdin.write(request + "\n")
    process.stdin.flush()
    return json.loads(process.stdout.readline())

# Step 1: Generate STL with 3D-Relief

relief_result = mcp_call(
    relief_proc,
    "convert",
    {
        "image_path": "https://example.com/image.jpg",
        "model_width": 80,
        "model_thickness": 6,
        "base_thickness": 3,
        "detail_level": 1.2
    }
)

# Step 2: Simplify the resulting mesh

simplify_result = mcp_call(
    simplify_proc,
    "simplify",
    {"stl_path": relief_result["stl_path"], "target_faces": 5000}
)

print(f"Final output: {simplify_result['stl_path']}")

This pattern allows you to chain this MCP tool with other Model Context Protocol servers by treating the JSON-RPC responses as transferable payloads between process boundaries.

HTTP Gateway Pattern

For integration with HTTP-based services, create a FastAPI gateway that bridges the stdio MCP tool to HTTP endpoints:

from fastapi import FastAPI, Request
import asyncio
import json
import subprocess

app = FastAPI()

# Start MCP tool as subprocess

relief_proc = subprocess.Popen(
    ["python", "server.py"],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    text=True
)

async def forward_to_relief(method: str, params: dict):
    req = json.dumps({
        "jsonrpc": "2.0",
        "method": method,
        "params": params,
        "id": 1
    })
    relief_proc.stdin.write(req + "\n")
    relief_proc.stdin.flush()
    # Async read from stdout

    resp = await asyncio.to_thread(relief_proc.stdout.readline)
    return json.loads(resp)

@app.post("/relief")
async def relay(request: Request):
    payload = await request.json()
    result = await forward_to_relief(
        payload.get("method", "convert"),
        payload.get("params", {})
    )
    return result

This approach enables you to chain this MCP tool with other Model Context Protocol servers that may use different transport mechanisms, acting as a protocol translator.

Key Integration Points for MCP Chaining

When building pipelines with the 3D-Relief tool, target these specific integration points in the source code:

  • server.py lines 58-59: FastMCP.from_fastapi(app, "mcp_3d_relief") registers the FastAPI routes as MCP methods, making the convert method available to downstream servers.
  • server.py lines 60-61: mcp.run(transport="stdio") initiates the stdio transport, which is the critical interface for process-based chaining.
  • relief.py: The relief() coroutine performs the actual image processing, depth-map generation, and STL export. This is the logical method invoked when chaining with other 3D-processing MCP servers.
  • requirements.txt: Dependencies include fastmcp, fastapi, opencv-python, pillow, and aiohttp, ensuring compatibility with standard Python environments without requiring specialized hardware.

Summary

  • The 3D-Relief tool uses FastMCP and stdio transport to expose FastAPI endpoints as Model Context Protocol methods.
  • You can chain this MCP tool with other Model Context Protocol servers by launching them as subprocesses and piping JSON-RPC messages between their standard input and output streams.
  • Sequential pipelines allow one tool's output (e.g., an STL file path) to become the next tool's input (e.g., for mesh simplification).
  • HTTP gateways can bridge stdio-based MCP tools to web services, enabling hybrid transport architectures.
  • Key files for integration include server.py (MCP setup), relief.py (processing logic), and requirements.txt (dependencies).

Frequently Asked Questions

How does the stdio transport enable chaining between MCP servers?

The stdio transport uses standard input and output streams to exchange JSON-RPC messages. When you launch an MCP server as a subprocess, you can write requests to its stdin and read responses from its stdout. This allows you to programmatically chain this MCP tool with other Model Context Protocol servers by treating the output of one process as the input to another, creating a pipeline of discrete transformation steps.

Can I chain the 3D-Relief tool with MCP servers that use HTTP instead of stdio?

Yes, but you need a transport bridge. The 3D-Relief tool exclusively uses stdio via mcp.run(transport="stdio") in server.py. To chain it with HTTP-based MCP servers, create a gateway service (like the FastAPI example shown above) that receives HTTP requests, forwards them to the stdio tool via subprocess communication, and returns the JSON-RPC responses over HTTP. This hybrid approach lets you integrate the tool into web-based MCP ecosystems.

What are the performance considerations when chaining multiple MCP servers?

Each MCP server in a chain runs as an independent process, so chaining introduces serialization overhead for JSON-RPC messages and potential I/O bottlenecks at pipe boundaries. For CPU-intensive tasks like the 3D-Relief tool's depth-map generation (implemented in relief.py), ensure sufficient system memory and consider running chained tools on the same machine to avoid network latency. The FastMCP library handles message framing efficiently, but complex chains with more than three or four tools may benefit from asynchronous orchestration using asyncio to manage subprocess I/O concurrently.

Which method should I invoke when chaining the 3D-Relief tool with downstream processors?

When chaining, invoke the convert method, which corresponds to the /convert endpoint defined in server.py (lines 16-55). This method accepts parameters including image_path, model_width, model_thickness, base_thickness, detail_level, and boolean flags like skip_depth and invert_depth. The method returns a JSON object containing the stl_path, which downstream MCP tools (such as mesh simplifiers or 3D printers) can consume as input for their own processing pipelines.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →