rocketsmith 0.0.1__tar.gz

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.
Files changed (35) hide show
  1. rocketsmith-0.0.1/LICENSE +21 -0
  2. rocketsmith-0.0.1/PKG-INFO +54 -0
  3. rocketsmith-0.0.1/README.md +37 -0
  4. rocketsmith-0.0.1/pyproject.toml +45 -0
  5. rocketsmith-0.0.1/setup.cfg +4 -0
  6. rocketsmith-0.0.1/src/rocketsmith/__init__.py +19 -0
  7. rocketsmith-0.0.1/src/rocketsmith/cli/__init__.py +16 -0
  8. rocketsmith-0.0.1/src/rocketsmith/cli/__main__.py +26 -0
  9. rocketsmith-0.0.1/src/rocketsmith/cli/options.py +15 -0
  10. rocketsmith-0.0.1/src/rocketsmith/cli/version.py +20 -0
  11. rocketsmith-0.0.1/src/rocketsmith/data/__init__.py +5 -0
  12. rocketsmith-0.0.1/src/rocketsmith/mcp/__init__.py +0 -0
  13. rocketsmith-0.0.1/src/rocketsmith/mcp/__main__.py +16 -0
  14. rocketsmith-0.0.1/src/rocketsmith/mcp/cli/__init__.py +10 -0
  15. rocketsmith-0.0.1/src/rocketsmith/mcp/cli/__main__.py +8 -0
  16. rocketsmith-0.0.1/src/rocketsmith/mcp/cli/development.py +46 -0
  17. rocketsmith-0.0.1/src/rocketsmith/mcp/cli/install.py +43 -0
  18. rocketsmith-0.0.1/src/rocketsmith/mcp/cli/uninstall.py +21 -0
  19. rocketsmith-0.0.1/src/rocketsmith/mcp/install.py +123 -0
  20. rocketsmith-0.0.1/src/rocketsmith/mcp/types.py +25 -0
  21. rocketsmith-0.0.1/src/rocketsmith/mcp/uninstall.py +91 -0
  22. rocketsmith-0.0.1/src/rocketsmith/mcp/utils.py +13 -0
  23. rocketsmith-0.0.1/src/rocketsmith/py.typed +0 -0
  24. rocketsmith-0.0.1/src/rocketsmith/workspace/__init__.py +0 -0
  25. rocketsmith-0.0.1/src/rocketsmith/workspace/cli/__init__.py +6 -0
  26. rocketsmith-0.0.1/src/rocketsmith/workspace/cli/__main__.py +8 -0
  27. rocketsmith-0.0.1/src/rocketsmith/workspace/cli/create.py +35 -0
  28. rocketsmith-0.0.1/src/rocketsmith/workspace/create.py +20 -0
  29. rocketsmith-0.0.1/src/rocketsmith/workspace/mcp.py +58 -0
  30. rocketsmith-0.0.1/src/rocketsmith.egg-info/PKG-INFO +54 -0
  31. rocketsmith-0.0.1/src/rocketsmith.egg-info/SOURCES.txt +33 -0
  32. rocketsmith-0.0.1/src/rocketsmith.egg-info/dependency_links.txt +1 -0
  33. rocketsmith-0.0.1/src/rocketsmith.egg-info/entry_points.txt +2 -0
  34. rocketsmith-0.0.1/src/rocketsmith.egg-info/requires.txt +5 -0
  35. rocketsmith-0.0.1/src/rocketsmith.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Peter Pak
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.
@@ -0,0 +1,54 @@
1
+ Metadata-Version: 2.4
2
+ Name: rocketsmith
3
+ Version: 0.0.1
4
+ Summary: Let agents design, simulate, and build your rocket.
5
+ Author-email: Peter Pak <ppak10@gmail.com>
6
+ Project-URL: Homepage, https://github.com/ppak10/RocketSmith
7
+ Project-URL: Issues, https://github.com/ppak10/RocketSmith/issues
8
+ Requires-Python: >=3.10
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Requires-Dist: mcp>=1.12.3
12
+ Requires-Dist: pydantic>=2.11.7
13
+ Requires-Dist: rich>=14.0.0
14
+ Requires-Dist: typer>=0.16.0
15
+ Requires-Dist: workspace-agent>=0.1.9
16
+ Dynamic: license-file
17
+
18
+ [![pytest](https://github.com/ppak10/RocketSmith/actions/workflows/pytest.yml/badge.svg)](https://github.com/ppak10/RocketSmith/actions/workflows/pytest.yml)
19
+
20
+ # RocketSmith <img src="https://cdn.jsdelivr.net/npm/lucide-static/icons/rocket.svg" width="32" height="32" />
21
+
22
+ Let agents design, simulate, and build your rocket.
23
+
24
+ ## Getting Started
25
+ ### Installation
26
+
27
+ ```bash
28
+ uv add rocketsmith
29
+ ```
30
+
31
+ ### Agent
32
+ #### Claude Code
33
+
34
+ 1. Install MCP tools and Agent
35
+
36
+ ```bash
37
+ rocketsmith mcp install
38
+ ```
39
+
40
+ #### Claude Desktop
41
+
42
+ 1. Install MCP tools
43
+
44
+ ```bash
45
+ rocketsmith mcp install claude-desktop --project-path /path/to/RocketSmith
46
+ ```
47
+
48
+ Note: After installation, restart Claude Desktop for the changes to take effect.
49
+
50
+ ### CLI (`rocketsmith --help`)
51
+ #### Create Workspace (via `workspace-agent`)
52
+ ```bash
53
+ rocketsmith workspace create <workspace-name>
54
+ ```
@@ -0,0 +1,37 @@
1
+ [![pytest](https://github.com/ppak10/RocketSmith/actions/workflows/pytest.yml/badge.svg)](https://github.com/ppak10/RocketSmith/actions/workflows/pytest.yml)
2
+
3
+ # RocketSmith <img src="https://cdn.jsdelivr.net/npm/lucide-static/icons/rocket.svg" width="32" height="32" />
4
+
5
+ Let agents design, simulate, and build your rocket.
6
+
7
+ ## Getting Started
8
+ ### Installation
9
+
10
+ ```bash
11
+ uv add rocketsmith
12
+ ```
13
+
14
+ ### Agent
15
+ #### Claude Code
16
+
17
+ 1. Install MCP tools and Agent
18
+
19
+ ```bash
20
+ rocketsmith mcp install
21
+ ```
22
+
23
+ #### Claude Desktop
24
+
25
+ 1. Install MCP tools
26
+
27
+ ```bash
28
+ rocketsmith mcp install claude-desktop --project-path /path/to/RocketSmith
29
+ ```
30
+
31
+ Note: After installation, restart Claude Desktop for the changes to take effect.
32
+
33
+ ### CLI (`rocketsmith --help`)
34
+ #### Create Workspace (via `workspace-agent`)
35
+ ```bash
36
+ rocketsmith workspace create <workspace-name>
37
+ ```
@@ -0,0 +1,45 @@
1
+ [project]
2
+ name = "rocketsmith"
3
+ version = "0.0.1"
4
+ authors = [
5
+ { name = "Peter Pak", email = "ppak10@gmail.com" },
6
+ ]
7
+ description = "Let agents design, simulate, and build your rocket."
8
+ readme = "README.md"
9
+ requires-python = ">=3.10"
10
+ dependencies = [
11
+ "mcp>=1.12.3",
12
+ "pydantic>=2.11.7",
13
+ "rich>=14.0.0",
14
+ "typer>=0.16.0",
15
+ "workspace-agent>=0.1.9",
16
+ ]
17
+
18
+ [project.urls]
19
+ Homepage = "https://github.com/ppak10/RocketSmith"
20
+ Issues = "https://github.com/ppak10/RocketSmith/issues"
21
+
22
+ [project.scripts]
23
+ rocketsmith = "rocketsmith.cli:app"
24
+
25
+ [tool.setuptools.packages.find]
26
+ where = ["src"]
27
+
28
+ [tool.setuptools.package-data]
29
+ "rocketsmith.data" = ["**/*.md"]
30
+
31
+ [tool.black]
32
+ line-length = 88
33
+ target-version = ["py310"]
34
+
35
+ [dependency-groups]
36
+ dev = [
37
+ "black>=25.1.0",
38
+ "coverage>=7.10.5",
39
+ "pre-commit>=4.3.0",
40
+ "pytest>=8.4.1",
41
+ "pytest-cov>=6.2.1",
42
+ ]
43
+
44
+ [tool.pytest.ini_options]
45
+ filterwarnings = []
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,19 @@
1
+ __author__ = "Peter Pak"
2
+ __email__ = "ppak10@gmail.com"
3
+
4
+ # Set multiprocessing start method to 'spawn' for compatibility with MCP server
5
+ # This ensures consistent behavior across platforms (Linux uses 'fork' by default,
6
+ # macOS uses 'spawn') and prevents issues with forking async/MCP server state
7
+ import multiprocessing
8
+ import sys
9
+ import warnings
10
+
11
+ if sys.platform != "win32": # spawn is already default on Windows
12
+ try:
13
+ multiprocessing.set_start_method("spawn", force=True)
14
+ except RuntimeError:
15
+ # Method already set, ignore
16
+ pass
17
+
18
+ # Suppress tqdm experimental warning for rich integration
19
+ warnings.filterwarnings("ignore", message=".*rich is experimental.*")
@@ -0,0 +1,16 @@
1
+ from .__main__ import app
2
+
3
+ # from .version import register_version
4
+
5
+ from rocketsmith.mcp.cli import app as mcp_app
6
+ from rocketsmith.workspace.cli import app as workspace_app
7
+
8
+ __all__ = ["app"]
9
+
10
+ app.add_typer(mcp_app, name="mcp", rich_help_panel="Configuration Commands")
11
+ app.add_typer(workspace_app, name="workspace", rich_help_panel="Configuration Commands")
12
+
13
+ # _ = register_version(app)
14
+
15
+ if __name__ == "__main__":
16
+ app()
@@ -0,0 +1,26 @@
1
+ import sys
2
+ import typer
3
+
4
+ from rich.console import Console
5
+ from rich import print as rprint
6
+
7
+ app = typer.Typer(
8
+ name="rocketsmith",
9
+ help="RocketSmith",
10
+ add_completion=False,
11
+ no_args_is_help=True,
12
+ )
13
+
14
+
15
+ def _rich_exception_handler(exc_type, exc_value, exc_traceback):
16
+ """Handle exceptions with rich formatting."""
17
+ if exc_type is KeyboardInterrupt:
18
+ rprint("\n ⚠️ [yellow]Operation cancelled by user[/yellow]")
19
+ sys.exit(1)
20
+ else:
21
+ sys.__excepthook__(exc_type, exc_value, exc_traceback)
22
+
23
+
24
+ sys.__excepthook__ = _rich_exception_handler
25
+
26
+ console = Console()
@@ -0,0 +1,15 @@
1
+ import typer
2
+
3
+ from typing_extensions import Annotated
4
+
5
+ VerboseOption = Annotated[
6
+ bool | None, typer.Option("--verbose", "-v", help="Enable verbose logging")
7
+ ]
8
+
9
+ NumProc = Annotated[
10
+ int,
11
+ typer.Option(
12
+ "--num-proc",
13
+ help="Enable multiprocessing by specifying number of processes to use.",
14
+ ),
15
+ ]
@@ -0,0 +1,20 @@
1
+ import importlib.metadata
2
+ import typer
3
+
4
+ from rich import print as rprint
5
+
6
+
7
+ def register_version(app: typer.Typer):
8
+ @app.command()
9
+ def version() -> None:
10
+ """Show the installed version of `rocketsmith` package."""
11
+ try:
12
+ version = importlib.metadata.version("rocketsmith")
13
+ rprint(f"✅ rocketsmith version {version}")
14
+ except importlib.metadata.PackageNotFoundError:
15
+ rprint(
16
+ "⚠️ [yellow]rocketsmith version unknown (package not installed)[/yellow]"
17
+ )
18
+ raise typer.Exit()
19
+
20
+ return version
@@ -0,0 +1,5 @@
1
+ from pathlib import Path
2
+
3
+ DATA_DIR = Path(__file__).parent
4
+
5
+ __all__ = ["DATA_DIR"]
File without changes
@@ -0,0 +1,16 @@
1
+ from mcp.server.fastmcp import FastMCP
2
+
3
+ from rocketsmith.workspace.mcp import register_workspace_create
4
+
5
+ app = FastMCP(name="rocketsmith")
6
+
7
+ _ = register_workspace_create(app)
8
+
9
+
10
+ def main():
11
+ """Entry point for the direct execution server."""
12
+ app.run()
13
+
14
+
15
+ if __name__ == "__main__":
16
+ main()
@@ -0,0 +1,10 @@
1
+ from .__main__ import app
2
+ from .development import register_mcp_development
3
+ from .install import register_mcp_install
4
+ from .uninstall import register_mcp_uninstall
5
+
6
+ _ = register_mcp_development(app)
7
+ _ = register_mcp_install(app)
8
+ _ = register_mcp_uninstall(app)
9
+
10
+ __all__ = ["app"]
@@ -0,0 +1,8 @@
1
+ import typer
2
+
3
+ app = typer.Typer(
4
+ name="mcp",
5
+ help="Model Context Protocol (MCP) Managment",
6
+ add_completion=False,
7
+ no_args_is_help=True,
8
+ )
@@ -0,0 +1,46 @@
1
+ import os
2
+ import subprocess
3
+ import sys
4
+ import typer
5
+
6
+ from importlib.resources import files
7
+ from rich import print as rprint
8
+
9
+
10
+ def register_mcp_development(app: typer.Typer):
11
+ @app.command(name="development")
12
+ def mcp_development() -> None:
13
+ from mcp.cli import cli
14
+
15
+ rprint(f"Starting MCP Development Server")
16
+
17
+ # Get the correct npx command
18
+ npx_cmd = cli._get_npx_command()
19
+
20
+ if not npx_cmd:
21
+ cli.logger.error(
22
+ "npx not found. Please ensure Node.js and npm are properly installed and added to your system PATH."
23
+ )
24
+ raise typer.Exit(1)
25
+
26
+ # Run the MCP Inspector command with shell=True on Windows
27
+ shell = sys.platform == "win32"
28
+
29
+ file_spec = files("rocketsmith.mcp").joinpath("__main__.py")
30
+
31
+ print(file_spec)
32
+
33
+ uv_cmd = ["uv", "run", "--with", "mcp", "mcp", "run", str(file_spec)]
34
+ print(f"uv_cmd: {uv_cmd}")
35
+
36
+ process = subprocess.run(
37
+ [npx_cmd, "@modelcontextprotocol/inspector"] + uv_cmd,
38
+ check=True,
39
+ shell=shell,
40
+ env=dict(os.environ.items()),
41
+ )
42
+ _ = typer.Exit(process.returncode)
43
+ rprint(f"✅ MCP Development Running")
44
+
45
+ _ = app.command(name="dev")(mcp_development)
46
+ return mcp_development
@@ -0,0 +1,43 @@
1
+ import typer
2
+
3
+ from typing_extensions import Annotated
4
+ from pathlib import Path
5
+ from rich import print as rprint
6
+
7
+ from rocketsmith.mcp.install import install
8
+
9
+
10
+ def register_mcp_install(app: typer.Typer):
11
+ @app.command(name="install")
12
+ def mcp_install(
13
+ client: Annotated[
14
+ str,
15
+ typer.Argument(
16
+ help="Target client to install for. Options: claude-code, claude-desktop, gemini-cli, codex"
17
+ ),
18
+ ] = "claude-code",
19
+ include_agent: Annotated[bool, typer.Option("--include-agent")] = False,
20
+ project_path: Annotated[str | None, typer.Option("--project-path")] = None,
21
+ dev: Annotated[bool, typer.Option("--dev")] = False,
22
+ ) -> None:
23
+ import rocketsmith
24
+
25
+ # Determine project root path
26
+ if dev:
27
+ rocketsmith_path = Path(rocketsmith.__file__).parents[2]
28
+ elif project_path:
29
+ rocketsmith_path = Path(project_path)
30
+ else:
31
+ # Path(rocketsmith.__file__) example:
32
+ # /GitHub/rocketsmith-agent/.venv/lib/python3.13/site-packages/rocketsmith
33
+ # Going up 5 levels to get to the project root
34
+ rocketsmith_path = Path(rocketsmith.__file__).parents[5]
35
+
36
+ rprint(
37
+ f"[bold green]Using `rocketsmith` packaged under project path:[/bold green] {rocketsmith_path}"
38
+ )
39
+
40
+ install(rocketsmith_path, client=client, include_agent=include_agent)
41
+
42
+ _ = app.command(name="install")(mcp_install)
43
+ return mcp_install
@@ -0,0 +1,21 @@
1
+ import typer
2
+
3
+ from typing_extensions import Annotated
4
+
5
+
6
+ def register_mcp_uninstall(app: typer.Typer):
7
+ @app.command(name="uninstall")
8
+ def mcp_uninstall(
9
+ client: Annotated[
10
+ str,
11
+ typer.Argument(
12
+ help="Target client to uninstall. Options: claude-code, claude-desktop, gemini-cli, codex"
13
+ ),
14
+ ] = "claude-code",
15
+ ) -> None:
16
+ from rocketsmith.mcp.uninstall import uninstall
17
+
18
+ uninstall(client=client)
19
+
20
+ _ = app.command(name="uninstall")(mcp_uninstall)
21
+ return mcp_uninstall
@@ -0,0 +1,123 @@
1
+ import json
2
+ import subprocess
3
+ import sys
4
+
5
+ from pathlib import Path
6
+ from rich import print as rprint
7
+
8
+
9
+ def install(path: Path, client: str, include_agent: bool = True) -> None:
10
+ match client:
11
+ case "claude-code":
12
+ cmd = [
13
+ "claude",
14
+ "mcp",
15
+ "add-json",
16
+ "rocketsmith",
17
+ f'{{"command": "uv", "args": ["--directory", "{path}", "run", "-m", "rocketsmith.mcp"]}}',
18
+ ]
19
+
20
+ case "claude-desktop":
21
+ # Determine config file path based on platform
22
+ if sys.platform == "darwin":
23
+ config_path = (
24
+ Path.home()
25
+ / "Library"
26
+ / "Application Support"
27
+ / "Claude"
28
+ / "claude_desktop_config.json"
29
+ )
30
+ elif sys.platform == "win32":
31
+ config_path = (
32
+ Path.home()
33
+ / "AppData"
34
+ / "Roaming"
35
+ / "Claude"
36
+ / "claude_desktop_config.json"
37
+ )
38
+ else: # Linux
39
+ config_path = (
40
+ Path.home() / ".config" / "Claude" / "claude_desktop_config.json"
41
+ )
42
+
43
+ # Ensure config directory exists
44
+ config_path.parent.mkdir(parents=True, exist_ok=True)
45
+
46
+ # Read existing config or create new one
47
+ if config_path.exists():
48
+ with open(config_path, "r") as f:
49
+ config = json.load(f)
50
+ rprint(f"[blue]Found existing config at:[/blue] {config_path}")
51
+ else:
52
+ config = {}
53
+ rprint(f"[yellow]Creating new config at:[/yellow] {config_path}")
54
+
55
+ # Ensure mcpServers section exists
56
+ if "mcpServers" not in config:
57
+ config["mcpServers"] = {}
58
+
59
+ # Add rocketsmith server
60
+ rprint("[blue]Adding 'rocketsmith' MCP server to config...[/blue]")
61
+ config["mcpServers"]["rocketsmith"] = {
62
+ "command": "uv",
63
+ "args": ["--directory", str(path), "run", "-m", "rocketsmith.mcp"],
64
+ }
65
+
66
+ # Write config back
67
+ with open(config_path, "w") as f:
68
+ json.dump(config, f, indent=2)
69
+
70
+ rprint(
71
+ f"[bold green]Successfully updated config at:[/bold green] {config_path}"
72
+ )
73
+ rprint(
74
+ "[yellow]Note: Please restart Claude Desktop for changes to take effect.[/yellow]"
75
+ )
76
+
77
+ # Skip agent installation as Claude Desktop doesn't support custom agents
78
+ if include_agent:
79
+ rprint(
80
+ "[yellow]Note: Claude Desktop does not support custom agents like Claude Code does.[/yellow]"
81
+ )
82
+
83
+ return # Early return since we don't need to run subprocess command
84
+
85
+ case "gemini-cli":
86
+ cmd = [
87
+ "gemini",
88
+ "mcp",
89
+ "add",
90
+ "rocketsmith",
91
+ "uv",
92
+ "--directory",
93
+ f"{path}",
94
+ "run",
95
+ "-m",
96
+ "rocketsmith.mcp",
97
+ ]
98
+
99
+ case "codex":
100
+ cmd = [
101
+ "codex",
102
+ "mcp",
103
+ "add",
104
+ "rocketsmith",
105
+ "uv",
106
+ "--directory",
107
+ f"{path}",
108
+ "run",
109
+ "-m",
110
+ "rocketsmith.mcp",
111
+ ]
112
+
113
+ case _:
114
+ rprint("[yellow]No client provided.[/yellow]")
115
+
116
+ try:
117
+ rprint(f"[blue]Running command:[/blue] {' '.join(cmd)}")
118
+ subprocess.run(cmd, check=True)
119
+ except subprocess.CalledProcessError as e:
120
+ rprint(f"[red]Command failed with return code {e.returncode}[/red]")
121
+ rprint(f"[red]Error output: {e.stderr}[/red]" if e.stderr else "")
122
+ except Exception as e:
123
+ rprint(f"[red]Unexpected error running command:[/red] {e}")
@@ -0,0 +1,25 @@
1
+ from typing import Union, Dict, Any, TypeVar, Generic
2
+ from pydantic import BaseModel
3
+
4
+ # Generic type for the success data
5
+ T = TypeVar("T")
6
+
7
+
8
+ class ToolError(BaseModel):
9
+ """Standard error response for MCP tools."""
10
+
11
+ success: bool = False
12
+ error: str
13
+ error_code: str
14
+ details: Dict[str, Any] = {}
15
+
16
+
17
+ class ToolSuccess(BaseModel, Generic[T]):
18
+ """Standard success response for MCP tools."""
19
+
20
+ success: bool = True
21
+ data: T
22
+
23
+
24
+ # Type alias for tool responses
25
+ ToolResponse = Union[ToolSuccess[T], ToolError]
@@ -0,0 +1,91 @@
1
+ import json
2
+ import subprocess
3
+ import sys
4
+
5
+ from pathlib import Path
6
+ from rich import print as rprint
7
+
8
+
9
+ def uninstall(client: str) -> None:
10
+ cmd = None
11
+ match client:
12
+ case "claude-code":
13
+ cmd = ["claude", "mcp", "remove", "rocketsmith"]
14
+
15
+ case "claude-desktop":
16
+ # Determine config file path based on platform
17
+ if sys.platform == "darwin":
18
+ config_path = (
19
+ Path.home()
20
+ / "Library"
21
+ / "Application Support"
22
+ / "Claude"
23
+ / "claude_desktop_config.json"
24
+ )
25
+ elif sys.platform == "win32":
26
+ config_path = (
27
+ Path.home()
28
+ / "AppData"
29
+ / "Roaming"
30
+ / "Claude"
31
+ / "claude_desktop_config.json"
32
+ )
33
+ else: # Linux
34
+ config_path = (
35
+ Path.home() / ".config" / "Claude" / "claude_desktop_config.json"
36
+ )
37
+
38
+ # Check if config file exists
39
+ if not config_path.exists():
40
+ rprint(f"[yellow]Config file not found at:[/yellow] {config_path}")
41
+ rprint("[yellow]Nothing to uninstall.[/yellow]")
42
+ return
43
+
44
+ # Read existing config
45
+ try:
46
+ with open(config_path, "r") as f:
47
+ config = json.load(f)
48
+ except json.JSONDecodeError:
49
+ rprint(f"[red]Error reading config file at:[/red] {config_path}")
50
+ return
51
+
52
+ # Remove rocketsmith server
53
+ if "mcpServers" in config and "rocketsmith" in config["mcpServers"]:
54
+ del config["mcpServers"]["rocketsmith"]
55
+ rprint("[blue]Removed 'rocketsmith' MCP server from config[/blue]")
56
+ else:
57
+ rprint(
58
+ "[yellow]'rocketsmith' MCP server not found in config[/yellow]"
59
+ )
60
+
61
+ # Write config back
62
+ with open(config_path, "w") as f:
63
+ json.dump(config, f, indent=2)
64
+
65
+ rprint(
66
+ f"[bold green]Successfully updated config at:[/bold green] {config_path}"
67
+ )
68
+ rprint(
69
+ "[yellow]Note: Please restart Claude Desktop for changes to take effect.[/yellow]"
70
+ )
71
+ return
72
+
73
+ case "gemini-cli":
74
+ cmd = ["gemini", "mcp", "remove", "rocketsmith"]
75
+
76
+ case "codex":
77
+ cmd = ["codex", "mcp", "remove", "rocketsmith"]
78
+
79
+ case _:
80
+ rprint("[yellow]No client provided.[/yellow]\n")
81
+
82
+ if cmd is not None:
83
+ try:
84
+ rprint(f"[blue]Running command:[/blue] {' '.join(cmd)}")
85
+ subprocess.run(cmd, check=True)
86
+
87
+ except subprocess.CalledProcessError as e:
88
+ rprint(f"[red]Command failed with return code {e.returncode}[/red]")
89
+ rprint(f"[red]Error output: {e.stderr}[/red]" if e.stderr else "")
90
+ except Exception as e:
91
+ rprint(f"[red]Unexpected error running command:[/red] {e}")
@@ -0,0 +1,13 @@
1
+ from rocketsmith.mcp.types import T, ToolError, ToolSuccess
2
+
3
+
4
+ # Convenience function to create error responses
5
+ def tool_error(message: str, code: str, **details) -> ToolError:
6
+ """Create a standardized tool error response."""
7
+ return ToolError(error=message, error_code=code, details=details)
8
+
9
+
10
+ # Convenience function to create success responses
11
+ def tool_success(data: T) -> ToolSuccess[T]:
12
+ """Create a standardized tool success response."""
13
+ return ToolSuccess(data=data)
File without changes
@@ -0,0 +1,6 @@
1
+ from .__main__ import app
2
+ from .create import register_workspace_create
3
+
4
+ _ = register_workspace_create(app)
5
+
6
+ __all__ = ["app"]
@@ -0,0 +1,8 @@
1
+ import typer
2
+
3
+ app = typer.Typer(
4
+ name="workspace",
5
+ help="Workspace management for `rocketsmith` package.",
6
+ add_completion=False,
7
+ no_args_is_help=True,
8
+ )
@@ -0,0 +1,35 @@
1
+ import typer
2
+
3
+ from pathlib import Path
4
+ from rich import print as rprint
5
+ from typing_extensions import Annotated
6
+
7
+
8
+ def register_workspace_create(app: typer.Typer):
9
+ @app.command(name="create")
10
+ def workspace_create(
11
+ workspace_name: str,
12
+ workspaces_path: Path | None = None,
13
+ force: Annotated[
14
+ bool, typer.Option("--force", help="Overwrite existing subfolder")
15
+ ] = False,
16
+ ) -> None:
17
+ """Create a folder to store data related to a workspace."""
18
+ from rocketsmith.workspace.create import create_rocketsmith_workspace
19
+
20
+ try:
21
+ workspace = create_rocketsmith_workspace(
22
+ workspace_name=workspace_name,
23
+ workspaces_path=workspaces_path,
24
+ force=force,
25
+ )
26
+ rprint(f"✅ Workspace created at: {workspace.path}")
27
+ except FileExistsError:
28
+ rprint(f"⚠️ [yellow]Workspace: `{workspace_name}` already exists.[/yellow]")
29
+ rprint("Use [cyan]--force[/cyan] to overwrite, or edit the existing file.")
30
+ _ = typer.Exit()
31
+ except:
32
+ rprint("⚠️ [yellow]Unable to create workspace directory[/yellow]")
33
+ _ = typer.Exit()
34
+
35
+ return workspace_create
@@ -0,0 +1,20 @@
1
+ from pathlib import Path
2
+
3
+ from wa import create_workspace, Workspace
4
+
5
+
6
+ def create_rocketsmith_workspace(
7
+ workspace_name: str,
8
+ workspaces_path: Path | None = None,
9
+ force: bool = False,
10
+ **kwargs,
11
+ ) -> Workspace:
12
+ """
13
+ Create RocketSmith Workspace class object and folder.
14
+ """
15
+
16
+ workspace = create_workspace(
17
+ workspace_name=workspace_name, workspaces_path=workspaces_path, force=force
18
+ )
19
+
20
+ return workspace
@@ -0,0 +1,58 @@
1
+ from mcp.server.fastmcp import FastMCP
2
+
3
+ from pathlib import Path
4
+ from typing import Union
5
+
6
+
7
+ def register_workspace_create(app: FastMCP):
8
+ from rocketsmith.mcp.types import ToolSuccess, ToolError
9
+ from rocketsmith.mcp.utils import tool_success, tool_error
10
+ from wa import Workspace
11
+
12
+ @app.tool(
13
+ title="Create RocketSmith Workspace",
14
+ description="Creates workspace folder for use with rocketsmith tools.",
15
+ structured_output=True,
16
+ )
17
+ async def workspace_create(
18
+ workspace_name: str,
19
+ workspaces_path: Path | None = None,
20
+ force: bool = False,
21
+ ) -> Union[ToolSuccess[Workspace], ToolError]:
22
+ """
23
+ Initialize rocketsmith workspace folder.
24
+
25
+ Args:
26
+ workspace_name: Name of folder to initialize.
27
+ workspaces_path: Path of folder containing workspaces.
28
+ force: Overwrite existing workspace.
29
+ """
30
+ from rocketsmith.workspace.create import create_rocketsmith_workspace
31
+
32
+ try:
33
+ workspace = create_rocketsmith_workspace(
34
+ workspace_name=workspace_name,
35
+ workspaces_path=workspaces_path,
36
+ force=force,
37
+ )
38
+
39
+ return tool_success(workspace)
40
+
41
+ except PermissionError as e:
42
+ return tool_error(
43
+ "Permission denied when creating workspace folder",
44
+ "PERMISSION_DENIED",
45
+ workspace_name=workspace_name,
46
+ exception_type=type(e).__name__,
47
+ )
48
+
49
+ except Exception as e:
50
+ return tool_error(
51
+ "Failed to create workspace folder",
52
+ "WORKSPACE_CREATE_FAILED",
53
+ workspace_name=workspace_name,
54
+ exception_type=type(e).__name__,
55
+ exception_message=str(e),
56
+ )
57
+
58
+ _ = workspace_create
@@ -0,0 +1,54 @@
1
+ Metadata-Version: 2.4
2
+ Name: rocketsmith
3
+ Version: 0.0.1
4
+ Summary: Let agents design, simulate, and build your rocket.
5
+ Author-email: Peter Pak <ppak10@gmail.com>
6
+ Project-URL: Homepage, https://github.com/ppak10/RocketSmith
7
+ Project-URL: Issues, https://github.com/ppak10/RocketSmith/issues
8
+ Requires-Python: >=3.10
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Requires-Dist: mcp>=1.12.3
12
+ Requires-Dist: pydantic>=2.11.7
13
+ Requires-Dist: rich>=14.0.0
14
+ Requires-Dist: typer>=0.16.0
15
+ Requires-Dist: workspace-agent>=0.1.9
16
+ Dynamic: license-file
17
+
18
+ [![pytest](https://github.com/ppak10/RocketSmith/actions/workflows/pytest.yml/badge.svg)](https://github.com/ppak10/RocketSmith/actions/workflows/pytest.yml)
19
+
20
+ # RocketSmith <img src="https://cdn.jsdelivr.net/npm/lucide-static/icons/rocket.svg" width="32" height="32" />
21
+
22
+ Let agents design, simulate, and build your rocket.
23
+
24
+ ## Getting Started
25
+ ### Installation
26
+
27
+ ```bash
28
+ uv add rocketsmith
29
+ ```
30
+
31
+ ### Agent
32
+ #### Claude Code
33
+
34
+ 1. Install MCP tools and Agent
35
+
36
+ ```bash
37
+ rocketsmith mcp install
38
+ ```
39
+
40
+ #### Claude Desktop
41
+
42
+ 1. Install MCP tools
43
+
44
+ ```bash
45
+ rocketsmith mcp install claude-desktop --project-path /path/to/RocketSmith
46
+ ```
47
+
48
+ Note: After installation, restart Claude Desktop for the changes to take effect.
49
+
50
+ ### CLI (`rocketsmith --help`)
51
+ #### Create Workspace (via `workspace-agent`)
52
+ ```bash
53
+ rocketsmith workspace create <workspace-name>
54
+ ```
@@ -0,0 +1,33 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/rocketsmith/__init__.py
5
+ src/rocketsmith/py.typed
6
+ src/rocketsmith.egg-info/PKG-INFO
7
+ src/rocketsmith.egg-info/SOURCES.txt
8
+ src/rocketsmith.egg-info/dependency_links.txt
9
+ src/rocketsmith.egg-info/entry_points.txt
10
+ src/rocketsmith.egg-info/requires.txt
11
+ src/rocketsmith.egg-info/top_level.txt
12
+ src/rocketsmith/cli/__init__.py
13
+ src/rocketsmith/cli/__main__.py
14
+ src/rocketsmith/cli/options.py
15
+ src/rocketsmith/cli/version.py
16
+ src/rocketsmith/data/__init__.py
17
+ src/rocketsmith/mcp/__init__.py
18
+ src/rocketsmith/mcp/__main__.py
19
+ src/rocketsmith/mcp/install.py
20
+ src/rocketsmith/mcp/types.py
21
+ src/rocketsmith/mcp/uninstall.py
22
+ src/rocketsmith/mcp/utils.py
23
+ src/rocketsmith/mcp/cli/__init__.py
24
+ src/rocketsmith/mcp/cli/__main__.py
25
+ src/rocketsmith/mcp/cli/development.py
26
+ src/rocketsmith/mcp/cli/install.py
27
+ src/rocketsmith/mcp/cli/uninstall.py
28
+ src/rocketsmith/workspace/__init__.py
29
+ src/rocketsmith/workspace/create.py
30
+ src/rocketsmith/workspace/mcp.py
31
+ src/rocketsmith/workspace/cli/__init__.py
32
+ src/rocketsmith/workspace/cli/__main__.py
33
+ src/rocketsmith/workspace/cli/create.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ rocketsmith = rocketsmith.cli:app
@@ -0,0 +1,5 @@
1
+ mcp>=1.12.3
2
+ pydantic>=2.11.7
3
+ rich>=14.0.0
4
+ typer>=0.16.0
5
+ workspace-agent>=0.1.9
@@ -0,0 +1 @@
1
+ rocketsmith