@meshy-ai/meshy-mcp-server 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +14 -0
- package/LICENSE +21 -0
- package/README.md +108 -0
- package/dist/constants.d.ts +123 -0
- package/dist/constants.js +169 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +130 -0
- package/dist/instructions.d.ts +6 -0
- package/dist/instructions.js +90 -0
- package/dist/schemas/balance.d.ts +11 -0
- package/dist/schemas/balance.js +8 -0
- package/dist/schemas/common.d.ts +38 -0
- package/dist/schemas/common.js +52 -0
- package/dist/schemas/generation.d.ts +219 -0
- package/dist/schemas/generation.js +217 -0
- package/dist/schemas/image.d.ts +55 -0
- package/dist/schemas/image.js +46 -0
- package/dist/schemas/output.d.ts +75 -0
- package/dist/schemas/output.js +41 -0
- package/dist/schemas/postprocessing.d.ts +135 -0
- package/dist/schemas/postprocessing.js +123 -0
- package/dist/schemas/printing.d.ts +63 -0
- package/dist/schemas/printing.js +54 -0
- package/dist/schemas/tasks.d.ts +123 -0
- package/dist/schemas/tasks.js +85 -0
- package/dist/services/error-handler.d.ts +32 -0
- package/dist/services/error-handler.js +141 -0
- package/dist/services/file-utils.d.ts +15 -0
- package/dist/services/file-utils.js +55 -0
- package/dist/services/meshy-client.d.ts +54 -0
- package/dist/services/meshy-client.js +172 -0
- package/dist/services/output-manager.d.ts +52 -0
- package/dist/services/output-manager.js +284 -0
- package/dist/tools/balance.d.ts +9 -0
- package/dist/tools/balance.js +61 -0
- package/dist/tools/generation.d.ts +9 -0
- package/dist/tools/generation.js +419 -0
- package/dist/tools/image.d.ts +9 -0
- package/dist/tools/image.js +154 -0
- package/dist/tools/postprocessing.d.ts +9 -0
- package/dist/tools/postprocessing.js +405 -0
- package/dist/tools/printing.d.ts +9 -0
- package/dist/tools/printing.js +338 -0
- package/dist/tools/tasks.d.ts +9 -0
- package/dist/tools/tasks.js +1074 -0
- package/dist/tools/workspace.d.ts +9 -0
- package/dist/tools/workspace.js +161 -0
- package/dist/types.d.ts +261 -0
- package/dist/types.js +4 -0
- package/dist/utils/endpoints.d.ts +16 -0
- package/dist/utils/endpoints.js +38 -0
- package/dist/utils/request-builder.d.ts +15 -0
- package/dist/utils/request-builder.js +24 -0
- package/dist/utils/response-formatter.d.ts +27 -0
- package/dist/utils/response-formatter.js +37 -0
- package/dist/utils/slicer-detector.d.ts +29 -0
- package/dist/utils/slicer-detector.js +237 -0
- package/package.json +64 -0
package/.env.example
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Required: Your Meshy API key
|
|
2
|
+
MESHY_API_KEY=your_api_key_here
|
|
3
|
+
|
|
4
|
+
# Optional: Meshy API host (default: https://api.meshy.ai)
|
|
5
|
+
MESHY_API_HOST=https://api.meshy.ai
|
|
6
|
+
|
|
7
|
+
# Optional: Transport mode (stdio or http, default: stdio)
|
|
8
|
+
TRANSPORT=stdio
|
|
9
|
+
|
|
10
|
+
# Optional: Port for HTTP transport (default: 3000)
|
|
11
|
+
PORT=3000
|
|
12
|
+
|
|
13
|
+
# Optional: Maximum response size in characters (default: 25000)
|
|
14
|
+
CHARACTER_LIMIT=25000
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Meshy AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Meshy MCP Server
|
|
2
|
+
|
|
3
|
+
[Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for the [Meshy AI](https://www.meshy.ai) 3D generation platform. Enables AI agents to create, manage, and download 3D models, textures, images, rigged characters, and animations through natural conversation.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
19 tools covering the full Meshy API:
|
|
8
|
+
|
|
9
|
+
| Category | Tools |
|
|
10
|
+
|----------|-------|
|
|
11
|
+
| **3D Generation** | `meshy_text_to_3d`, `meshy_text_to_3d_refine`, `meshy_image_to_3d`, `meshy_multi_image_to_3d` |
|
|
12
|
+
| **Post-Processing** | `meshy_remesh`, `meshy_retexture`, `meshy_rig`, `meshy_animate` |
|
|
13
|
+
| **Image Generation** | `meshy_text_to_image`, `meshy_image_to_image` |
|
|
14
|
+
| **Task Management** | `meshy_get_task_status`, `meshy_list_tasks`, `meshy_cancel_task`, `meshy_download_model` |
|
|
15
|
+
| **Workspace** | `meshy_list_models` |
|
|
16
|
+
| **3D Printing** | `meshy_send_to_slicer`, `meshy_analyze_printability`, `meshy_process_multicolor` |
|
|
17
|
+
| **Account** | `meshy_check_balance` |
|
|
18
|
+
|
|
19
|
+
### Key Capabilities
|
|
20
|
+
|
|
21
|
+
- **Text to 3D**: Generate 3D models from text descriptions (preview + refine pipeline)
|
|
22
|
+
- **Image to 3D**: Convert single or multiple images into 3D models
|
|
23
|
+
- **Auto-Rigging & Animation**: Add skeletons and animations to humanoid characters
|
|
24
|
+
- **Multi-Color 3D Printing**: Process textured models into multi-color 3MF files for 3D printing
|
|
25
|
+
- **Slicer Integration**: Auto-detect installed slicer software and open models directly
|
|
26
|
+
- **Print-Ready OBJ**: Built-in coordinate transformation (Y-up → Z-up) for 3D printing
|
|
27
|
+
- **Smart File Organization**: Auto-saves to `meshy_output/` with project folders, metadata, and history tracking
|
|
28
|
+
- **Built-in Workflow Intelligence**: Server instructions guide the agent through correct tool chains for each use case
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
### Prerequisites
|
|
33
|
+
|
|
34
|
+
- Node.js >= 18
|
|
35
|
+
- A Meshy API key ([get one here](https://www.meshy.ai/settings/api) — requires Pro plan or above)
|
|
36
|
+
|
|
37
|
+
### Claude Code
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
claude mcp add meshy -- npx -y @meshy-ai/meshy-mcp-server -e MESHY_API_KEY=msy_YOUR_API_KEY
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
That's it. The server includes built-in workflow instructions — no additional configuration needed.
|
|
44
|
+
|
|
45
|
+
### Cursor
|
|
46
|
+
|
|
47
|
+
Add to your Cursor MCP settings (`.cursor/mcp.json`):
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"mcpServers": {
|
|
52
|
+
"meshy": {
|
|
53
|
+
"command": "npx",
|
|
54
|
+
"args": ["-y", "@meshy-ai/meshy-mcp-server"],
|
|
55
|
+
"env": {
|
|
56
|
+
"MESHY_API_KEY": "msy_YOUR_API_KEY"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Configuration
|
|
64
|
+
|
|
65
|
+
| Environment Variable | Description | Default |
|
|
66
|
+
|---------------------|-------------|---------|
|
|
67
|
+
| `MESHY_API_KEY` | **Required.** Your Meshy API key (starts with `msy_`) | — |
|
|
68
|
+
| `MESHY_API_HOST` | API base URL | `https://api.meshy.ai` |
|
|
69
|
+
| `TRANSPORT` | Transport mode: `stdio` or `http` | `stdio` |
|
|
70
|
+
| `PORT` | Port for HTTP transport | `3000` |
|
|
71
|
+
| `CHARACTER_LIMIT` | Max response size in characters | `25000` |
|
|
72
|
+
|
|
73
|
+
## Development
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Clone and install
|
|
77
|
+
git clone https://github.com/meshy-dev/meshy-mcp-server.git
|
|
78
|
+
cd meshy-mcp-server
|
|
79
|
+
npm install
|
|
80
|
+
|
|
81
|
+
# Development with hot reload
|
|
82
|
+
npm run dev
|
|
83
|
+
|
|
84
|
+
# Build
|
|
85
|
+
npm run build
|
|
86
|
+
|
|
87
|
+
# Type check
|
|
88
|
+
npm run lint
|
|
89
|
+
|
|
90
|
+
# Run
|
|
91
|
+
npm start
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## HTTP Transport
|
|
95
|
+
|
|
96
|
+
For remote access, run in HTTP mode:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
TRANSPORT=http PORT=3000 npm start
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Endpoints:
|
|
103
|
+
- `POST /mcp` — MCP protocol endpoint
|
|
104
|
+
- `GET /health` — Health check
|
|
105
|
+
|
|
106
|
+
## License
|
|
107
|
+
|
|
108
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants for Meshy MCP Server
|
|
3
|
+
*/
|
|
4
|
+
export declare const API_BASE_URL: string;
|
|
5
|
+
export declare const CHARACTER_LIMIT: number;
|
|
6
|
+
export declare enum ResponseFormat {
|
|
7
|
+
MARKDOWN = "markdown",
|
|
8
|
+
JSON = "json"
|
|
9
|
+
}
|
|
10
|
+
export declare enum TaskStatus {
|
|
11
|
+
PENDING = "PENDING",
|
|
12
|
+
IN_PROGRESS = "IN_PROGRESS",
|
|
13
|
+
SUCCEEDED = "SUCCEEDED",
|
|
14
|
+
FAILED = "FAILED",
|
|
15
|
+
CANCELED = "CANCELED"
|
|
16
|
+
}
|
|
17
|
+
export declare enum TaskPhase {
|
|
18
|
+
DRAFT = "draft",
|
|
19
|
+
GENERATE = "generate",
|
|
20
|
+
TEXTURE = "texture",
|
|
21
|
+
STYLIZE = "stylize",
|
|
22
|
+
ANIMATE = "animate"
|
|
23
|
+
}
|
|
24
|
+
export declare enum Topology {
|
|
25
|
+
QUAD = "quad",
|
|
26
|
+
TRIANGLE = "triangle"
|
|
27
|
+
}
|
|
28
|
+
export declare enum ModelFormat {
|
|
29
|
+
GLB = "glb",
|
|
30
|
+
FBX = "fbx",
|
|
31
|
+
USDZ = "usdz",
|
|
32
|
+
THREE_MF = "3mf"
|
|
33
|
+
}
|
|
34
|
+
export declare enum AIModel {
|
|
35
|
+
MESHY_5 = "meshy-5",
|
|
36
|
+
MESHY_6 = "meshy-6",
|
|
37
|
+
LATEST = "latest"
|
|
38
|
+
}
|
|
39
|
+
export declare enum ModelType {
|
|
40
|
+
STANDARD = "standard",
|
|
41
|
+
LOWPOLY = "lowpoly"
|
|
42
|
+
}
|
|
43
|
+
export declare enum SymmetryMode {
|
|
44
|
+
OFF = "off",
|
|
45
|
+
AUTO = "auto",
|
|
46
|
+
ON = "on"
|
|
47
|
+
}
|
|
48
|
+
export declare enum PoseMode {
|
|
49
|
+
A_POSE = "a-pose",
|
|
50
|
+
T_POSE = "t-pose"
|
|
51
|
+
}
|
|
52
|
+
export declare enum TaskType {
|
|
53
|
+
TEXT_TO_3D = "text-to-3d",
|
|
54
|
+
IMAGE_TO_3D = "image-to-3d",
|
|
55
|
+
MULTI_IMAGE_TO_3D = "multi-image-to-3d",
|
|
56
|
+
REMESH = "remesh",
|
|
57
|
+
RETEXTURE = "retexture",
|
|
58
|
+
RIGGING = "rigging",
|
|
59
|
+
ANIMATION = "animation",
|
|
60
|
+
TEXT_TO_IMAGE = "text-to-image",
|
|
61
|
+
IMAGE_TO_IMAGE = "image-to-image",
|
|
62
|
+
MULTI_COLOR_PRINT = "multi-color-print"
|
|
63
|
+
}
|
|
64
|
+
export declare enum RemeshFormat {
|
|
65
|
+
GLB = "glb",
|
|
66
|
+
FBX = "fbx",
|
|
67
|
+
OBJ = "obj",
|
|
68
|
+
USDZ = "usdz",
|
|
69
|
+
BLEND = "blend",
|
|
70
|
+
STL = "stl"
|
|
71
|
+
}
|
|
72
|
+
export declare enum OriginAt {
|
|
73
|
+
BOTTOM = "bottom",
|
|
74
|
+
CENTER = "center"
|
|
75
|
+
}
|
|
76
|
+
export declare enum TextToImageModel {
|
|
77
|
+
NANO_BANANA = "nano-banana",
|
|
78
|
+
NANO_BANANA_PRO = "nano-banana-pro"
|
|
79
|
+
}
|
|
80
|
+
export declare enum AspectRatio {
|
|
81
|
+
SQUARE = "1:1",
|
|
82
|
+
WIDESCREEN = "16:9",
|
|
83
|
+
PORTRAIT = "9:16",
|
|
84
|
+
STANDARD = "4:3",
|
|
85
|
+
PORTRAIT_STANDARD = "3:4"
|
|
86
|
+
}
|
|
87
|
+
export declare enum SlicerType {
|
|
88
|
+
AUTO = "auto",
|
|
89
|
+
BAMBU = "bambu",
|
|
90
|
+
ORCASLICER = "orcaslicer",
|
|
91
|
+
CREALITY_PRINT = "creality_print",
|
|
92
|
+
ELEGOO_SLICER = "elegoo_slicer",
|
|
93
|
+
ANYCUBIC_SLICER = "anycubic_slicer",
|
|
94
|
+
PRUSASLICER = "prusaslicer",
|
|
95
|
+
CURA = "cura"
|
|
96
|
+
}
|
|
97
|
+
export declare const MULTICOLOR_CAPABLE_SLICERS: SlicerType[];
|
|
98
|
+
export declare const MULTI_COLOR_CREDITS = 10;
|
|
99
|
+
export declare enum AnimationPostProcessOp {
|
|
100
|
+
CHANGE_FPS = "change_fps",
|
|
101
|
+
FBX2USDZ = "fbx2usdz",
|
|
102
|
+
EXTRACT_ARMATURE = "extract_armature"
|
|
103
|
+
}
|
|
104
|
+
export declare enum ErrorCode {
|
|
105
|
+
INSUFFICIENT_CREDITS = "InsufficientCredits",
|
|
106
|
+
TOO_MANY_PENDING_TASKS = "TooManyPendingTasks",
|
|
107
|
+
INVALID_MODEL_NOT_SUPPORTED = "InvalidModel:NotSupported",
|
|
108
|
+
INVALID_MODEL_INVALID_FORMAT = "InvalidModel:InvalidFormat",
|
|
109
|
+
LIMIT_EXCEEDED = "LimitExceeded",
|
|
110
|
+
FORBIDDEN = "Forbidden",
|
|
111
|
+
NOT_FOUND = "NotFound",
|
|
112
|
+
INTERNAL_ERROR = "InternalError"
|
|
113
|
+
}
|
|
114
|
+
export declare const API_TIMEOUT = 30000;
|
|
115
|
+
export declare const RETRY_DELAYS: number[];
|
|
116
|
+
export declare const MAX_RETRIES = 3;
|
|
117
|
+
export declare const POLL_INITIAL_DELAY = 5000;
|
|
118
|
+
export declare const POLL_MAX_DELAY = 30000;
|
|
119
|
+
export declare const POLL_BACKOFF_FACTOR = 1.5;
|
|
120
|
+
export declare const POLL_FINALIZATION_DELAY = 15000;
|
|
121
|
+
export declare const POLL_DEFAULT_TIMEOUT = 300000;
|
|
122
|
+
export declare const POLL_MAX_TIMEOUT = 300000;
|
|
123
|
+
export declare const RIGGING_MAX_FACES = 300000;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants for Meshy MCP Server
|
|
3
|
+
*/
|
|
4
|
+
// API Configuration
|
|
5
|
+
export const API_BASE_URL = process.env.MESHY_API_HOST || "https://api.meshy.ai";
|
|
6
|
+
export const CHARACTER_LIMIT = parseInt(process.env.CHARACTER_LIMIT || "25000", 10);
|
|
7
|
+
// Response Formats
|
|
8
|
+
export var ResponseFormat;
|
|
9
|
+
(function (ResponseFormat) {
|
|
10
|
+
ResponseFormat["MARKDOWN"] = "markdown";
|
|
11
|
+
ResponseFormat["JSON"] = "json";
|
|
12
|
+
})(ResponseFormat || (ResponseFormat = {}));
|
|
13
|
+
// Task Status
|
|
14
|
+
export var TaskStatus;
|
|
15
|
+
(function (TaskStatus) {
|
|
16
|
+
TaskStatus["PENDING"] = "PENDING";
|
|
17
|
+
TaskStatus["IN_PROGRESS"] = "IN_PROGRESS";
|
|
18
|
+
TaskStatus["SUCCEEDED"] = "SUCCEEDED";
|
|
19
|
+
TaskStatus["FAILED"] = "FAILED";
|
|
20
|
+
TaskStatus["CANCELED"] = "CANCELED";
|
|
21
|
+
})(TaskStatus || (TaskStatus = {}));
|
|
22
|
+
// Task Phases
|
|
23
|
+
export var TaskPhase;
|
|
24
|
+
(function (TaskPhase) {
|
|
25
|
+
TaskPhase["DRAFT"] = "draft";
|
|
26
|
+
TaskPhase["GENERATE"] = "generate";
|
|
27
|
+
TaskPhase["TEXTURE"] = "texture";
|
|
28
|
+
TaskPhase["STYLIZE"] = "stylize";
|
|
29
|
+
TaskPhase["ANIMATE"] = "animate";
|
|
30
|
+
})(TaskPhase || (TaskPhase = {}));
|
|
31
|
+
// Topology Types
|
|
32
|
+
export var Topology;
|
|
33
|
+
(function (Topology) {
|
|
34
|
+
Topology["QUAD"] = "quad";
|
|
35
|
+
Topology["TRIANGLE"] = "triangle";
|
|
36
|
+
})(Topology || (Topology = {}));
|
|
37
|
+
// Model Formats
|
|
38
|
+
export var ModelFormat;
|
|
39
|
+
(function (ModelFormat) {
|
|
40
|
+
ModelFormat["GLB"] = "glb";
|
|
41
|
+
ModelFormat["FBX"] = "fbx";
|
|
42
|
+
ModelFormat["USDZ"] = "usdz";
|
|
43
|
+
ModelFormat["THREE_MF"] = "3mf";
|
|
44
|
+
})(ModelFormat || (ModelFormat = {}));
|
|
45
|
+
// AI Models
|
|
46
|
+
export var AIModel;
|
|
47
|
+
(function (AIModel) {
|
|
48
|
+
AIModel["MESHY_5"] = "meshy-5";
|
|
49
|
+
AIModel["MESHY_6"] = "meshy-6";
|
|
50
|
+
AIModel["LATEST"] = "latest";
|
|
51
|
+
})(AIModel || (AIModel = {}));
|
|
52
|
+
// Model Types
|
|
53
|
+
export var ModelType;
|
|
54
|
+
(function (ModelType) {
|
|
55
|
+
ModelType["STANDARD"] = "standard";
|
|
56
|
+
ModelType["LOWPOLY"] = "lowpoly";
|
|
57
|
+
})(ModelType || (ModelType = {}));
|
|
58
|
+
// Symmetry Modes
|
|
59
|
+
export var SymmetryMode;
|
|
60
|
+
(function (SymmetryMode) {
|
|
61
|
+
SymmetryMode["OFF"] = "off";
|
|
62
|
+
SymmetryMode["AUTO"] = "auto";
|
|
63
|
+
SymmetryMode["ON"] = "on";
|
|
64
|
+
})(SymmetryMode || (SymmetryMode = {}));
|
|
65
|
+
// Pose Modes
|
|
66
|
+
export var PoseMode;
|
|
67
|
+
(function (PoseMode) {
|
|
68
|
+
PoseMode["A_POSE"] = "a-pose";
|
|
69
|
+
PoseMode["T_POSE"] = "t-pose";
|
|
70
|
+
})(PoseMode || (PoseMode = {}));
|
|
71
|
+
// Task Types
|
|
72
|
+
export var TaskType;
|
|
73
|
+
(function (TaskType) {
|
|
74
|
+
TaskType["TEXT_TO_3D"] = "text-to-3d";
|
|
75
|
+
TaskType["IMAGE_TO_3D"] = "image-to-3d";
|
|
76
|
+
TaskType["MULTI_IMAGE_TO_3D"] = "multi-image-to-3d";
|
|
77
|
+
TaskType["REMESH"] = "remesh";
|
|
78
|
+
TaskType["RETEXTURE"] = "retexture";
|
|
79
|
+
TaskType["RIGGING"] = "rigging";
|
|
80
|
+
TaskType["ANIMATION"] = "animation";
|
|
81
|
+
TaskType["TEXT_TO_IMAGE"] = "text-to-image";
|
|
82
|
+
TaskType["IMAGE_TO_IMAGE"] = "image-to-image";
|
|
83
|
+
TaskType["MULTI_COLOR_PRINT"] = "multi-color-print";
|
|
84
|
+
})(TaskType || (TaskType = {}));
|
|
85
|
+
// Remesh Output Formats
|
|
86
|
+
export var RemeshFormat;
|
|
87
|
+
(function (RemeshFormat) {
|
|
88
|
+
RemeshFormat["GLB"] = "glb";
|
|
89
|
+
RemeshFormat["FBX"] = "fbx";
|
|
90
|
+
RemeshFormat["OBJ"] = "obj";
|
|
91
|
+
RemeshFormat["USDZ"] = "usdz";
|
|
92
|
+
RemeshFormat["BLEND"] = "blend";
|
|
93
|
+
RemeshFormat["STL"] = "stl";
|
|
94
|
+
})(RemeshFormat || (RemeshFormat = {}));
|
|
95
|
+
// Origin At (for remesh)
|
|
96
|
+
export var OriginAt;
|
|
97
|
+
(function (OriginAt) {
|
|
98
|
+
OriginAt["BOTTOM"] = "bottom";
|
|
99
|
+
OriginAt["CENTER"] = "center";
|
|
100
|
+
})(OriginAt || (OriginAt = {}));
|
|
101
|
+
// Text-to-Image Models
|
|
102
|
+
export var TextToImageModel;
|
|
103
|
+
(function (TextToImageModel) {
|
|
104
|
+
TextToImageModel["NANO_BANANA"] = "nano-banana";
|
|
105
|
+
TextToImageModel["NANO_BANANA_PRO"] = "nano-banana-pro";
|
|
106
|
+
})(TextToImageModel || (TextToImageModel = {}));
|
|
107
|
+
// Aspect Ratios
|
|
108
|
+
export var AspectRatio;
|
|
109
|
+
(function (AspectRatio) {
|
|
110
|
+
AspectRatio["SQUARE"] = "1:1";
|
|
111
|
+
AspectRatio["WIDESCREEN"] = "16:9";
|
|
112
|
+
AspectRatio["PORTRAIT"] = "9:16";
|
|
113
|
+
AspectRatio["STANDARD"] = "4:3";
|
|
114
|
+
AspectRatio["PORTRAIT_STANDARD"] = "3:4";
|
|
115
|
+
})(AspectRatio || (AspectRatio = {}));
|
|
116
|
+
// Slicer Types
|
|
117
|
+
export var SlicerType;
|
|
118
|
+
(function (SlicerType) {
|
|
119
|
+
SlicerType["AUTO"] = "auto";
|
|
120
|
+
SlicerType["BAMBU"] = "bambu";
|
|
121
|
+
SlicerType["ORCASLICER"] = "orcaslicer";
|
|
122
|
+
SlicerType["CREALITY_PRINT"] = "creality_print";
|
|
123
|
+
SlicerType["ELEGOO_SLICER"] = "elegoo_slicer";
|
|
124
|
+
SlicerType["ANYCUBIC_SLICER"] = "anycubic_slicer";
|
|
125
|
+
SlicerType["PRUSASLICER"] = "prusaslicer";
|
|
126
|
+
SlicerType["CURA"] = "cura";
|
|
127
|
+
})(SlicerType || (SlicerType = {}));
|
|
128
|
+
// Slicers that support multi-color printing (AMS/MMU)
|
|
129
|
+
export const MULTICOLOR_CAPABLE_SLICERS = [
|
|
130
|
+
SlicerType.ORCASLICER,
|
|
131
|
+
SlicerType.BAMBU,
|
|
132
|
+
SlicerType.CREALITY_PRINT,
|
|
133
|
+
SlicerType.ELEGOO_SLICER,
|
|
134
|
+
SlicerType.ANYCUBIC_SLICER
|
|
135
|
+
];
|
|
136
|
+
// Multi-color processing credit cost
|
|
137
|
+
export const MULTI_COLOR_CREDITS = 10;
|
|
138
|
+
// Animation Post Process Operations
|
|
139
|
+
export var AnimationPostProcessOp;
|
|
140
|
+
(function (AnimationPostProcessOp) {
|
|
141
|
+
AnimationPostProcessOp["CHANGE_FPS"] = "change_fps";
|
|
142
|
+
AnimationPostProcessOp["FBX2USDZ"] = "fbx2usdz";
|
|
143
|
+
AnimationPostProcessOp["EXTRACT_ARMATURE"] = "extract_armature";
|
|
144
|
+
})(AnimationPostProcessOp || (AnimationPostProcessOp = {}));
|
|
145
|
+
// Error Codes
|
|
146
|
+
export var ErrorCode;
|
|
147
|
+
(function (ErrorCode) {
|
|
148
|
+
ErrorCode["INSUFFICIENT_CREDITS"] = "InsufficientCredits";
|
|
149
|
+
ErrorCode["TOO_MANY_PENDING_TASKS"] = "TooManyPendingTasks";
|
|
150
|
+
ErrorCode["INVALID_MODEL_NOT_SUPPORTED"] = "InvalidModel:NotSupported";
|
|
151
|
+
ErrorCode["INVALID_MODEL_INVALID_FORMAT"] = "InvalidModel:InvalidFormat";
|
|
152
|
+
ErrorCode["LIMIT_EXCEEDED"] = "LimitExceeded";
|
|
153
|
+
ErrorCode["FORBIDDEN"] = "Forbidden";
|
|
154
|
+
ErrorCode["NOT_FOUND"] = "NotFound";
|
|
155
|
+
ErrorCode["INTERNAL_ERROR"] = "InternalError";
|
|
156
|
+
})(ErrorCode || (ErrorCode = {}));
|
|
157
|
+
// Timeouts
|
|
158
|
+
export const API_TIMEOUT = 30000; // 30 seconds
|
|
159
|
+
export const RETRY_DELAYS = [2000, 4000, 8000]; // Exponential backoff
|
|
160
|
+
export const MAX_RETRIES = 3;
|
|
161
|
+
// Polling Configuration (for meshy_get_task_status wait mode)
|
|
162
|
+
export const POLL_INITIAL_DELAY = 5000; // 5 seconds
|
|
163
|
+
export const POLL_MAX_DELAY = 30000; // 30 seconds
|
|
164
|
+
export const POLL_BACKOFF_FACTOR = 1.5;
|
|
165
|
+
export const POLL_FINALIZATION_DELAY = 15000; // 15s when progress >= 95%
|
|
166
|
+
export const POLL_DEFAULT_TIMEOUT = 300000; // 5 minutes
|
|
167
|
+
export const POLL_MAX_TIMEOUT = 300000; // 5 minutes
|
|
168
|
+
// Rigging Constraints
|
|
169
|
+
export const RIGGING_MAX_FACES = 300000;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Meshy MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Model Context Protocol server for Meshy AI's 3D generation platform.
|
|
6
|
+
* Enables AI agents to create and manage 3D models programmatically.
|
|
7
|
+
*/
|
|
8
|
+
// Load environment variables from .env file
|
|
9
|
+
import dotenv from "dotenv";
|
|
10
|
+
// Redirect console.log to stderr during dotenv load to prevent stdio corruption
|
|
11
|
+
// (dotenv may call console.log which would corrupt the stdio JSON-RPC transport)
|
|
12
|
+
const originalLog = console.log;
|
|
13
|
+
console.log = (...args) => console.error(...args);
|
|
14
|
+
dotenv.config();
|
|
15
|
+
console.log = originalLog;
|
|
16
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
17
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
18
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
19
|
+
import express from "express";
|
|
20
|
+
import { createMeshyClient } from "./services/meshy-client.js";
|
|
21
|
+
import { registerGenerationTools } from "./tools/generation.js";
|
|
22
|
+
import { registerTaskTools } from "./tools/tasks.js";
|
|
23
|
+
import { registerWorkspaceTools } from "./tools/workspace.js";
|
|
24
|
+
import { registerPostProcessingTools } from "./tools/postprocessing.js";
|
|
25
|
+
import { registerImageTools } from "./tools/image.js";
|
|
26
|
+
import { registerPrintingTools } from "./tools/printing.js";
|
|
27
|
+
import { registerBalanceTool } from "./tools/balance.js";
|
|
28
|
+
import { MESHY_INSTRUCTIONS } from "./instructions.js";
|
|
29
|
+
// Create MCP server instance
|
|
30
|
+
const server = new McpServer({ name: "@meshy-ai/meshy-mcp-server", version: "0.2.0" }, { instructions: MESHY_INSTRUCTIONS });
|
|
31
|
+
/**
|
|
32
|
+
* Initialize server and register tools
|
|
33
|
+
*/
|
|
34
|
+
async function initializeServer() {
|
|
35
|
+
try {
|
|
36
|
+
// Create and validate Meshy API client
|
|
37
|
+
const meshyClient = await createMeshyClient();
|
|
38
|
+
console.error("✓ Meshy client initialized");
|
|
39
|
+
// Register all tools
|
|
40
|
+
console.error("Registering MCP tools...");
|
|
41
|
+
registerGenerationTools(server, meshyClient);
|
|
42
|
+
console.error(" ✓ Generation tools registered (text-to-3d, text-to-3d-refine, image-to-3d, multi-image-to-3d)");
|
|
43
|
+
registerTaskTools(server, meshyClient);
|
|
44
|
+
console.error(" ✓ Task management tools registered (get status, list, cancel, download)");
|
|
45
|
+
registerWorkspaceTools(server, meshyClient);
|
|
46
|
+
console.error(" ✓ Workspace tools registered (list models)");
|
|
47
|
+
registerPostProcessingTools(server, meshyClient);
|
|
48
|
+
console.error(" ✓ Post-processing tools registered (remesh, retexture, rig, animate)");
|
|
49
|
+
registerImageTools(server, meshyClient);
|
|
50
|
+
console.error(" ✓ Image tools registered (text-to-image, image-to-image)");
|
|
51
|
+
registerPrintingTools(server, meshyClient);
|
|
52
|
+
console.error(" ✓ Printing tools registered (send-to-slicer, analyze-printability, process-multicolor)");
|
|
53
|
+
registerBalanceTool(server, meshyClient);
|
|
54
|
+
console.error(" ✓ Balance tool registered (check-balance)");
|
|
55
|
+
console.error("✓ Server initialized successfully with 19 tools");
|
|
56
|
+
return meshyClient;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error("Failed to initialize server:", error);
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Run server with stdio transport (for local integrations)
|
|
65
|
+
*/
|
|
66
|
+
async function runStdio() {
|
|
67
|
+
console.error("Starting Meshy MCP Server (stdio mode)...");
|
|
68
|
+
await initializeServer();
|
|
69
|
+
const transport = new StdioServerTransport();
|
|
70
|
+
await server.connect(transport);
|
|
71
|
+
console.error("✓ Meshy MCP Server running via stdio");
|
|
72
|
+
console.error("Ready to accept requests from MCP client");
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Run server with HTTP transport (for remote access)
|
|
76
|
+
*/
|
|
77
|
+
async function runHTTP() {
|
|
78
|
+
console.error("Starting Meshy MCP Server (HTTP mode)...");
|
|
79
|
+
await initializeServer();
|
|
80
|
+
const app = express();
|
|
81
|
+
app.use(express.json());
|
|
82
|
+
// Health check endpoint
|
|
83
|
+
app.get("/health", (req, res) => {
|
|
84
|
+
res.json({ status: "ok", server: "meshy-mcp-server", version: "1.0.0" });
|
|
85
|
+
});
|
|
86
|
+
// MCP endpoint
|
|
87
|
+
app.post("/mcp", async (req, res) => {
|
|
88
|
+
const transport = new StreamableHTTPServerTransport({
|
|
89
|
+
sessionIdGenerator: undefined,
|
|
90
|
+
enableJsonResponse: true
|
|
91
|
+
});
|
|
92
|
+
res.on("close", () => transport.close());
|
|
93
|
+
await server.connect(transport);
|
|
94
|
+
await transport.handleRequest(req, res, req.body);
|
|
95
|
+
});
|
|
96
|
+
const port = parseInt(process.env.PORT || "3000", 10);
|
|
97
|
+
app.listen(port, () => {
|
|
98
|
+
console.error(`✓ Meshy MCP Server running on http://localhost:${port}/mcp`);
|
|
99
|
+
console.error(`Health check: http://localhost:${port}/health`);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Main entry point
|
|
104
|
+
*/
|
|
105
|
+
async function main() {
|
|
106
|
+
const transport = process.env.TRANSPORT || "stdio";
|
|
107
|
+
try {
|
|
108
|
+
if (transport === "http") {
|
|
109
|
+
await runHTTP();
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
await runStdio();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
console.error("Fatal error:", error);
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Handle graceful shutdown
|
|
121
|
+
process.on("SIGINT", () => {
|
|
122
|
+
console.error("\nShutting down gracefully...");
|
|
123
|
+
process.exit(0);
|
|
124
|
+
});
|
|
125
|
+
process.on("SIGTERM", () => {
|
|
126
|
+
console.error("\nShutting down gracefully...");
|
|
127
|
+
process.exit(0);
|
|
128
|
+
});
|
|
129
|
+
// Start the server
|
|
130
|
+
main();
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-level instructions sent to clients on connection.
|
|
3
|
+
* Provides top-level workflow routing so the agent picks the right tool chain.
|
|
4
|
+
* Specific parameter details and constraints live in each tool's description.
|
|
5
|
+
*/
|
|
6
|
+
export declare const MESHY_INSTRUCTIONS = "\n# Meshy AI \u2014 Workflow Guide\n\n## Rule 1: Cost Confirmation\nBefore calling ANY tool that costs credits, present the cost and wait for user confirmation.\n\n| Tool | Credits |\n|------|---------|\n| meshy_text_to_3d | 5\u201320 |\n| meshy_text_to_3d_refine | 10 |\n| meshy_image_to_3d / meshy_multi_image_to_3d | 5\u201330 |\n| meshy_retexture | 10 |\n| meshy_remesh | 5 |\n| meshy_rig | 5 (includes walking + running) |\n| meshy_animate | 3 |\n| meshy_process_multicolor | 10 |\n| meshy_text_to_image / meshy_image_to_image | 3\u20139 |\n\n## Rule 2: Determine Output Format BEFORE Generating\nThe API parameter target_formats controls which formats are produced. Decide the output format before calling any generation tool, because target_formats must be set at creation time. Ask user about their intended use first.\n\n## Rule 3: Identify the Use Case, Then Confirm with User\nDetermine which scenario below best matches, present a suggested plan to the user, and confirm before executing. Do not mix steps across scenarios.\n\n---\n\nEach scenario below is a recommended workflow. Discuss with the user to confirm the plan before executing.\n\n## Scenario A: 3D Printing (white model)\nTrigger: user mentions print, slicer, figurine, miniature, statue, physical model \u2014 single-color.\nSuggested flow:\n1. Detect installed slicers (meshy_send_to_slicer, slicer_type:\"auto\") \u2014 present list, save for later\n2. Generate untextured model (text-to-3d or image-to-3d) with target_formats:[\"obj\"]\n3. Wait for completion\n4. Download OBJ with print_ready=true (auto coordinate fix for slicer)\n5. Present slicer list from step 1, ask user which to use, execute launch_command via Bash\n\n## Scenario B: 3D Printing (multicolor)\nTrigger: user wants multicolor/color print.\nSuggested flow:\n1. Detect multicolor-capable slicers (meshy_send_to_slicer, is_multicolor:true) \u2014 present list, save for later\n2. Generate a textured model \u2014 via text-to-3d (preview + refine) or image-to-3d with textures\n3. Multi-color processing (meshy_process_multicolor) with input_task_id from the textured task \u2014 10 credits, outputs 3MF\n4. Wait for completion (task_type:\"multi-color-print\")\n5. Download 3MF\n6. Present slicer list from step 1, ask user which to use, execute launch_command via Bash\n\n## Scenario C: Game Engine (Unity/Unreal/Godot)\nTrigger: user mentions game, Unity, Unreal, Godot, game-ready.\nSuggested flow:\n1. Generate model with target_formats:[\"fbx\"]\n2. Add textures (refine or retexture)\n3. Remesh for game-ready topology (meshy_remesh, topology:\"quad\", appropriate polycount)\n4. Download FBX\n\n## Scenario D: Character Animation\nTrigger: user mentions rig, animate, walking, running, character animation.\nSuggested flow:\n1. Generate model with pose_mode:\"t-pose\"\n2. Add textures (refine or retexture)\n3. Rig the model (meshy_rig, \u2264300K faces; if over, remesh to reduce polycount first)\n4. Download \u2014 rigging includes walking+running free. Only use meshy_animate for custom animations.\n\n## Scenario E: AR / Apple\nTrigger: user mentions AR, USDZ, Vision Pro, Quick Look.\nSuggested flow:\n1. Generate model with target_formats:[\"usdz\"]\n2. Add textures (refine or retexture)\n3. Remesh for USDZ format conversion (meshy_remesh, target_formats:[\"usdz\"])\n4. Download USDZ\n\n## Scenario F: Retexture\nTrigger: user wants to change textures/style of existing model.\nSuggested flow:\n1. Ask user for text_style_prompt OR image_style_url (one required, image takes precedence)\n2. Apply retexture (meshy_retexture)\n\n## Scenario G: General 3D Model (default)\nTrigger: none of the above.\nSuggested flow:\n1. Ask user about intended use to determine format\n2. Generate model\n3. Ask: add textures (refine)?\n4. Download in chosen format\n";
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-level instructions sent to clients on connection.
|
|
3
|
+
* Provides top-level workflow routing so the agent picks the right tool chain.
|
|
4
|
+
* Specific parameter details and constraints live in each tool's description.
|
|
5
|
+
*/
|
|
6
|
+
export const MESHY_INSTRUCTIONS = `
|
|
7
|
+
# Meshy AI — Workflow Guide
|
|
8
|
+
|
|
9
|
+
## Rule 1: Cost Confirmation
|
|
10
|
+
Before calling ANY tool that costs credits, present the cost and wait for user confirmation.
|
|
11
|
+
|
|
12
|
+
| Tool | Credits |
|
|
13
|
+
|------|---------|
|
|
14
|
+
| meshy_text_to_3d | 5–20 |
|
|
15
|
+
| meshy_text_to_3d_refine | 10 |
|
|
16
|
+
| meshy_image_to_3d / meshy_multi_image_to_3d | 5–30 |
|
|
17
|
+
| meshy_retexture | 10 |
|
|
18
|
+
| meshy_remesh | 5 |
|
|
19
|
+
| meshy_rig | 5 (includes walking + running) |
|
|
20
|
+
| meshy_animate | 3 |
|
|
21
|
+
| meshy_process_multicolor | 10 |
|
|
22
|
+
| meshy_text_to_image / meshy_image_to_image | 3–9 |
|
|
23
|
+
|
|
24
|
+
## Rule 2: Determine Output Format BEFORE Generating
|
|
25
|
+
The API parameter target_formats controls which formats are produced. Decide the output format before calling any generation tool, because target_formats must be set at creation time. Ask user about their intended use first.
|
|
26
|
+
|
|
27
|
+
## Rule 3: Identify the Use Case, Then Confirm with User
|
|
28
|
+
Determine which scenario below best matches, present a suggested plan to the user, and confirm before executing. Do not mix steps across scenarios.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
Each scenario below is a recommended workflow. Discuss with the user to confirm the plan before executing.
|
|
33
|
+
|
|
34
|
+
## Scenario A: 3D Printing (white model)
|
|
35
|
+
Trigger: user mentions print, slicer, figurine, miniature, statue, physical model — single-color.
|
|
36
|
+
Suggested flow:
|
|
37
|
+
1. Detect installed slicers (meshy_send_to_slicer, slicer_type:"auto") — present list, save for later
|
|
38
|
+
2. Generate untextured model (text-to-3d or image-to-3d) with target_formats:["obj"]
|
|
39
|
+
3. Wait for completion
|
|
40
|
+
4. Download OBJ with print_ready=true (auto coordinate fix for slicer)
|
|
41
|
+
5. Present slicer list from step 1, ask user which to use, execute launch_command via Bash
|
|
42
|
+
|
|
43
|
+
## Scenario B: 3D Printing (multicolor)
|
|
44
|
+
Trigger: user wants multicolor/color print.
|
|
45
|
+
Suggested flow:
|
|
46
|
+
1. Detect multicolor-capable slicers (meshy_send_to_slicer, is_multicolor:true) — present list, save for later
|
|
47
|
+
2. Generate a textured model — via text-to-3d (preview + refine) or image-to-3d with textures
|
|
48
|
+
3. Multi-color processing (meshy_process_multicolor) with input_task_id from the textured task — 10 credits, outputs 3MF
|
|
49
|
+
4. Wait for completion (task_type:"multi-color-print")
|
|
50
|
+
5. Download 3MF
|
|
51
|
+
6. Present slicer list from step 1, ask user which to use, execute launch_command via Bash
|
|
52
|
+
|
|
53
|
+
## Scenario C: Game Engine (Unity/Unreal/Godot)
|
|
54
|
+
Trigger: user mentions game, Unity, Unreal, Godot, game-ready.
|
|
55
|
+
Suggested flow:
|
|
56
|
+
1. Generate model with target_formats:["fbx"]
|
|
57
|
+
2. Add textures (refine or retexture)
|
|
58
|
+
3. Remesh for game-ready topology (meshy_remesh, topology:"quad", appropriate polycount)
|
|
59
|
+
4. Download FBX
|
|
60
|
+
|
|
61
|
+
## Scenario D: Character Animation
|
|
62
|
+
Trigger: user mentions rig, animate, walking, running, character animation.
|
|
63
|
+
Suggested flow:
|
|
64
|
+
1. Generate model with pose_mode:"t-pose"
|
|
65
|
+
2. Add textures (refine or retexture)
|
|
66
|
+
3. Rig the model (meshy_rig, ≤300K faces; if over, remesh to reduce polycount first)
|
|
67
|
+
4. Download — rigging includes walking+running free. Only use meshy_animate for custom animations.
|
|
68
|
+
|
|
69
|
+
## Scenario E: AR / Apple
|
|
70
|
+
Trigger: user mentions AR, USDZ, Vision Pro, Quick Look.
|
|
71
|
+
Suggested flow:
|
|
72
|
+
1. Generate model with target_formats:["usdz"]
|
|
73
|
+
2. Add textures (refine or retexture)
|
|
74
|
+
3. Remesh for USDZ format conversion (meshy_remesh, target_formats:["usdz"])
|
|
75
|
+
4. Download USDZ
|
|
76
|
+
|
|
77
|
+
## Scenario F: Retexture
|
|
78
|
+
Trigger: user wants to change textures/style of existing model.
|
|
79
|
+
Suggested flow:
|
|
80
|
+
1. Ask user for text_style_prompt OR image_style_url (one required, image takes precedence)
|
|
81
|
+
2. Apply retexture (meshy_retexture)
|
|
82
|
+
|
|
83
|
+
## Scenario G: General 3D Model (default)
|
|
84
|
+
Trigger: none of the above.
|
|
85
|
+
Suggested flow:
|
|
86
|
+
1. Ask user about intended use to determine format
|
|
87
|
+
2. Generate model
|
|
88
|
+
3. Ask: add textures (refine)?
|
|
89
|
+
4. Download in chosen format
|
|
90
|
+
`;
|