qbraid-cli 0.10.9a0__py3-none-any.whl → 0.11.0__py3-none-any.whl

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.

Potentially problematic release.


This version of qbraid-cli might be problematic. Click here for more details.

qbraid_cli/_version.py ADDED
@@ -0,0 +1,18 @@
1
+ # Copyright (c) 2025, qBraid Development Team
2
+ # All rights reserved.
3
+
4
+ """
5
+ Module defining package version.
6
+
7
+ """
8
+
9
+ import importlib.metadata
10
+
11
+ try:
12
+ __version__ = importlib.metadata.version("qbraid-cli")
13
+ except Exception: # pylint: disable=broad-exception-caught # pragma: no cover
14
+ __version__ = "dev"
15
+
16
+ __version_tuple__ = tuple(int(part) if part.isdigit() else part for part in __version__.split("."))
17
+
18
+ __all__ = ["__version__", "__version_tuple__"]
@@ -131,5 +131,92 @@ def configure_magic():
131
131
  console.print(f"\n\t{in_1}\n\n\t{in_2}\n")
132
132
 
133
133
 
134
+ @configure_app.command(name="claude")
135
+ def configure_claude(
136
+ action: str = typer.Argument(
137
+ ...,
138
+ help="Action to perform: 'add', 'remove', or 'show'",
139
+ ),
140
+ overwrite: bool = typer.Option(
141
+ False,
142
+ "--overwrite",
143
+ help="Overwrite existing MCP server configuration",
144
+ ),
145
+ ):
146
+ """
147
+ Manage qBraid MCP server in Claude Desktop configuration.
148
+
149
+ Add, remove, or show the qBraid MCP server in your Claude Desktop config
150
+ (claude_desktop_config.json).
151
+ """
152
+ # pylint: disable-next=import-outside-toplevel
153
+ from qbraid_cli.configure.claude_config import (
154
+ add_qbraid_mcp_server,
155
+ get_claude_config_path,
156
+ get_qbraid_mcp_server_config,
157
+ remove_qbraid_mcp_server,
158
+ )
159
+
160
+ console = Console()
161
+
162
+ # Validate action
163
+ valid_actions = ["add", "remove", "show"]
164
+ if action not in valid_actions:
165
+ console.print(
166
+ f"[red]Error:[/red] Invalid action '{action}'. "
167
+ f"Must be one of: {', '.join(valid_actions)}"
168
+ )
169
+ raise typer.Exit(1)
170
+
171
+ # Check if Claude config exists (except for show which can work without it)
172
+ if action != "show":
173
+ config_path = get_claude_config_path()
174
+ if config_path is None:
175
+ console.print(
176
+ "[yellow]Warning:[/yellow] Claude Desktop config file not found.\n"
177
+ "Expected locations:\n"
178
+ " - macOS: ~/Library/Application Support/Claude/claude_desktop_config.json\n"
179
+ " - Windows: %APPDATA%\\Claude\\claude_desktop_config.json\n"
180
+ " - Linux: ~/.config/Claude/claude_desktop_config.json\n\n"
181
+ "Creating new config file..."
182
+ )
183
+
184
+ # Perform action
185
+ if action == "add":
186
+ success, message = add_qbraid_mcp_server(overwrite=overwrite)
187
+ if success:
188
+ console.print(f"[green]Success:[/green] {message}")
189
+ console.print(
190
+ "\n[yellow]Note:[/yellow] You may need to restart Claude Desktop "
191
+ "for changes to take effect."
192
+ )
193
+ else:
194
+ console.print(f"[red]Error:[/red] {message}")
195
+ raise typer.Exit(1)
196
+
197
+ elif action == "remove":
198
+ success, message = remove_qbraid_mcp_server()
199
+ if success:
200
+ console.print(f"[green]Success:[/green] {message}")
201
+ console.print(
202
+ "\n[yellow]Note:[/yellow] You may need to restart Claude Desktop "
203
+ "for changes to take effect."
204
+ )
205
+ else:
206
+ console.print(f"[red]Error:[/red] {message}")
207
+ raise typer.Exit(1)
208
+
209
+ elif action == "show":
210
+ server_config = get_qbraid_mcp_server_config()
211
+ if server_config is None:
212
+ console.print("No qBraid MCP server found in Claude Desktop configuration.")
213
+ return
214
+
215
+ console.print("\n[cyan]qBraid MCP Server Configuration:[/cyan]\n")
216
+ console.print(f" Command: {server_config.get('command', 'N/A')}")
217
+ console.print(f" Args: {server_config.get('args', [])}")
218
+ console.print()
219
+
220
+
134
221
  if __name__ == "__main__":
135
222
  configure_app()
@@ -0,0 +1,215 @@
1
+ # Copyright (c) 2025, qBraid Development Team
2
+ # All rights reserved.
3
+
4
+ """
5
+ Utility functions for managing Claude Desktop configuration.
6
+
7
+ This module provides cross-platform support for locating and updating
8
+ the claude_desktop_config.json file used by Claude Desktop.
9
+ """
10
+
11
+ import json
12
+ import os
13
+ import platform
14
+ import shutil
15
+ from pathlib import Path
16
+ from typing import Optional
17
+
18
+
19
+ def get_claude_config_path() -> Optional[Path]:
20
+ """
21
+ Get the path to the Claude Desktop configuration file.
22
+
23
+ Returns the platform-specific path to claude_desktop_config.json:
24
+ - macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
25
+ - Windows: %APPDATA%\\Claude\\claude_desktop_config.json
26
+ - Linux: ~/.config/Claude/claude_desktop_config.json
27
+
28
+ Returns:
29
+ Path to the config file if it exists, None otherwise
30
+ """
31
+ system = platform.system()
32
+
33
+ if system == "Darwin": # macOS
34
+ config_path = Path.home() / "Library" / "Application Support" / "Claude"
35
+ elif system == "Windows":
36
+ appdata = os.environ.get("APPDATA")
37
+ if not appdata:
38
+ return None
39
+ config_path = Path(appdata) / "Claude"
40
+ elif system == "Linux":
41
+ config_path = Path.home() / ".config" / "Claude"
42
+ else:
43
+ return None
44
+
45
+ config_file = config_path / "claude_desktop_config.json"
46
+ return config_file if config_file.exists() else None
47
+
48
+
49
+ def load_claude_config() -> dict:
50
+ """
51
+ Load the Claude Desktop configuration file.
52
+
53
+ Returns:
54
+ Configuration dictionary. If file doesn't exist, returns empty dict.
55
+
56
+ Raises:
57
+ json.JSONDecodeError: If config file exists but contains invalid JSON
58
+ OSError: If there are permission issues reading the file
59
+ """
60
+ config_path = get_claude_config_path()
61
+
62
+ if config_path is None or not config_path.exists():
63
+ return {}
64
+
65
+ with open(config_path, "r", encoding="utf-8") as f:
66
+ return json.load(f)
67
+
68
+
69
+ def save_claude_config(config: dict) -> Path:
70
+ """
71
+ Save the Claude Desktop configuration file.
72
+
73
+ Creates the configuration directory if it doesn't exist.
74
+
75
+ Args:
76
+ config: Configuration dictionary to save
77
+
78
+ Returns:
79
+ Path to the saved configuration file
80
+
81
+ Raises:
82
+ OSError: If there are permission issues or the platform is unsupported
83
+ """
84
+ system = platform.system()
85
+
86
+ if system == "Darwin": # macOS
87
+ config_dir = Path.home() / "Library" / "Application Support" / "Claude"
88
+ elif system == "Windows":
89
+ appdata = os.environ.get("APPDATA")
90
+ if not appdata:
91
+ raise OSError("APPDATA environment variable not set")
92
+ config_dir = Path(appdata) / "Claude"
93
+ elif system == "Linux":
94
+ config_dir = Path.home() / ".config" / "Claude"
95
+ else:
96
+ raise OSError(f"Unsupported platform: {system}")
97
+
98
+ # Create directory if it doesn't exist
99
+ config_dir.mkdir(parents=True, exist_ok=True)
100
+
101
+ config_file = config_dir / "claude_desktop_config.json"
102
+
103
+ # Write config with pretty formatting
104
+ with open(config_file, "w", encoding="utf-8") as f:
105
+ json.dump(config, f, indent=2, ensure_ascii=False)
106
+ f.write("\n") # Add trailing newline
107
+
108
+ return config_file
109
+
110
+
111
+ def add_qbraid_mcp_server(overwrite: bool = False) -> tuple[bool, str]:
112
+ """
113
+ Add qBraid MCP server configuration to Claude Desktop config.
114
+
115
+ Args:
116
+ overwrite: If True, overwrite existing qbraid entry
117
+
118
+ Returns:
119
+ Tuple of (success: bool, message: str)
120
+ """
121
+ # Get the full path to qbraid executable
122
+ qbraid_path = shutil.which("qbraid")
123
+ if not qbraid_path:
124
+ return (
125
+ False,
126
+ "Could not find qbraid executable in PATH. "
127
+ "Please ensure qbraid-cli is installed and accessible.",
128
+ )
129
+
130
+ try:
131
+ config = load_claude_config()
132
+ except json.JSONDecodeError as e:
133
+ return False, f"Invalid JSON in Claude config file: {e}"
134
+ except OSError as e:
135
+ return False, f"Error reading Claude config file: {e}"
136
+
137
+ # Initialize mcpServers section if it doesn't exist
138
+ if "mcpServers" not in config:
139
+ config["mcpServers"] = {}
140
+
141
+ # Determine server name
142
+ server_name = "qbraid"
143
+
144
+ # Check if server already exists
145
+ if server_name in config["mcpServers"] and not overwrite:
146
+ return (
147
+ False,
148
+ f"MCP server '{server_name}' already exists in config. "
149
+ "Use --overwrite to replace it.",
150
+ )
151
+
152
+ # Build server configuration with full path to qbraid
153
+ server_config = {"command": qbraid_path, "args": ["mcp", "serve"]}
154
+
155
+ # Add server to config
156
+ config["mcpServers"][server_name] = server_config
157
+
158
+ # Save config
159
+ try:
160
+ config_path = save_claude_config(config)
161
+ action = "Updated" if server_name in config["mcpServers"] else "Added"
162
+ return True, f"{action} MCP server '{server_name}' in [cyan]{config_path}[/cyan]"
163
+ except OSError as e:
164
+ return False, f"Error saving Claude config file: {e}"
165
+
166
+
167
+ def remove_qbraid_mcp_server() -> tuple[bool, str]:
168
+ """
169
+ Remove qBraid MCP server configuration from Claude Desktop config.
170
+
171
+ Returns:
172
+ Tuple of (success: bool, message: str)
173
+ """
174
+ try:
175
+ config = load_claude_config()
176
+ except json.JSONDecodeError as e:
177
+ return False, f"Invalid JSON in Claude config file: {e}"
178
+ except OSError as e:
179
+ return False, f"Error reading Claude config file: {e}"
180
+
181
+ if "mcpServers" not in config:
182
+ return False, "No mcpServers section found in Claude config"
183
+
184
+ server_name = "qbraid"
185
+
186
+ if server_name not in config["mcpServers"]:
187
+ return False, f"MCP server '{server_name}' not found in config"
188
+
189
+ # Remove server
190
+ del config["mcpServers"][server_name]
191
+
192
+ # Save config
193
+ try:
194
+ config_path = save_claude_config(config)
195
+ return True, f"Removed MCP server '{server_name}' from [cyan]{config_path}[/cyan]"
196
+ except OSError as e:
197
+ return False, f"Error saving Claude config file: {e}"
198
+
199
+
200
+ def get_qbraid_mcp_server_config() -> Optional[dict]:
201
+ """
202
+ Get qBraid MCP server configuration from Claude Desktop config.
203
+
204
+ Returns:
205
+ Server configuration dict if found, None otherwise
206
+ """
207
+ try:
208
+ config = load_claude_config()
209
+ except (json.JSONDecodeError, OSError):
210
+ return None
211
+
212
+ if "mcpServers" not in config:
213
+ return None
214
+
215
+ return config["mcpServers"].get("qbraid")
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qbraid-cli
3
- Version: 0.10.9a0
3
+ Version: 0.11.0
4
4
  Summary: Command Line Interface for interacting with all parts of the qBraid platform.
5
5
  Author-email: qBraid Development Team <contact@qbraid.com>
6
- License: Proprietary
6
+ License-Expression: LicenseRef-Proprietary
7
7
  Project-URL: Homepage, https://docs.qbraid.com/cli/user-guide/overview
8
8
  Project-URL: Documentation, https://docs.qbraid.com/cli/api-reference/qbraid
9
9
  Project-URL: Bug Tracker, https://github.com/qBraid/community/issues
@@ -12,7 +12,6 @@ Keywords: qbraid,cli,quantum,cloud
12
12
  Classifier: Development Status :: 5 - Production/Stable
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: Natural Language :: English
15
- Classifier: License :: Other/Proprietary License
16
15
  Classifier: Intended Audience :: System Administrators
17
16
  Classifier: Operating System :: Microsoft :: Windows
18
17
  Classifier: Operating System :: POSIX :: Linux
@@ -1,4 +1,5 @@
1
1
  qbraid_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ qbraid_cli/_version.py,sha256=3XwaThsiOWydODTKqEaylQmodo5qZxp3-tSzxEJq1sw,456
2
3
  qbraid_cli/exceptions.py,sha256=KjlhYJhSHMVazaNiBjD_Ur06w4sekP8zRsFzBdyIpno,672
3
4
  qbraid_cli/handlers.py,sha256=qRxrB37-n9WBYIAf63KLEAPSQ7Hfhb1qRaHgsA2TVH8,8069
4
5
  qbraid_cli/main.py,sha256=s0PA-jlebLxrFiI_mPDhioQ8JHTvMOjprFa7vbsmLII,3996
@@ -13,7 +14,8 @@ qbraid_cli/chat/__init__.py,sha256=NO41vndEdfr0vDynNcmHFh-nhzWjnWqGm4M9parikck,2
13
14
  qbraid_cli/chat/app.py,sha256=-YqCLGDh4ezF149xB3dfuUAQotKAklZwYp0BL3HhA90,2256
14
15
  qbraid_cli/configure/__init__.py,sha256=YaJ74Ztz2vl3eYp8_jVBucWkXscxz7EZEIzr70OfuOM,187
15
16
  qbraid_cli/configure/actions.py,sha256=Zv-y7iGgj1fwYceMSXrurpK2PyFCIitKXPqCb4H9AZo,3818
16
- qbraid_cli/configure/app.py,sha256=7UN8Bje0n_s2nDE-cHid8VwOp7gl0jjw9gldyCcZNhI,4164
17
+ qbraid_cli/configure/app.py,sha256=CxzQmWDpCwpNe4HO7sOxJzbFwJ4dayzD8sjzefQvNNE,7260
18
+ qbraid_cli/configure/claude_config.py,sha256=OJqdEA0wr19F4BnZMAxRBf7rA9FehX12VzC6TQ-rr6c,6457
17
19
  qbraid_cli/devices/__init__.py,sha256=hiScO-px6jCL5cJj5Hbty55EUfNejTO4bmqUZuS3aqc,181
18
20
  qbraid_cli/devices/app.py,sha256=B-cRdV092C6ACeu3C-5l2P_izpPDxvCzzAKfxO1WkaM,3224
19
21
  qbraid_cli/devices/validation.py,sha256=YhShyUufgrKnx2XjXOXF-PqFJYklJT9CgeqIwKcNam4,809
@@ -36,9 +38,9 @@ qbraid_cli/mcp/serve.py,sha256=4LFXjuv6CQPIuskPxcFXS0qE2igv1vYmLup-u1xhIZ0,11384
36
38
  qbraid_cli/pip/__init__.py,sha256=tJtU0rxn-ODogNh5Y4pp_BgDQXMN-3JY1QGj0OZHwjQ,169
37
39
  qbraid_cli/pip/app.py,sha256=jkk-djductrDOJIRYfHK_7WDJ12f0zOT3MMkiZp97oM,1365
38
40
  qbraid_cli/pip/hooks.py,sha256=jkIeev3cOd-cmaoJSdSqbmhTYCs6z1we84FMqa3ZoZw,2124
39
- qbraid_cli-0.10.9a0.dist-info/licenses/LICENSE,sha256=3KvWfsaXBCqbZ4qwk5jN9CQXE53tQeaZTySN5a-CCgQ,2753
40
- qbraid_cli-0.10.9a0.dist-info/METADATA,sha256=3qv0HRybpysRiHUy37YiksN97Q4Jg-MeAzwZH9LU8l8,7839
41
- qbraid_cli-0.10.9a0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
42
- qbraid_cli-0.10.9a0.dist-info/entry_points.txt,sha256=c5ZJ7NjbxhDqMpou9q5F03_b_KG34HzFDijIDmEIwgQ,47
43
- qbraid_cli-0.10.9a0.dist-info/top_level.txt,sha256=LTYJgeYSCHo9Il8vZu0yIPuGdGyNaIw6iRy6BeoZo8o,11
44
- qbraid_cli-0.10.9a0.dist-info/RECORD,,
41
+ qbraid_cli-0.11.0.dist-info/licenses/LICENSE,sha256=3KvWfsaXBCqbZ4qwk5jN9CQXE53tQeaZTySN5a-CCgQ,2753
42
+ qbraid_cli-0.11.0.dist-info/METADATA,sha256=abpcskHSE3v-4-23dVHTN77lhSTv_aGsYx9OEB4Mrbs,7810
43
+ qbraid_cli-0.11.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
44
+ qbraid_cli-0.11.0.dist-info/entry_points.txt,sha256=c5ZJ7NjbxhDqMpou9q5F03_b_KG34HzFDijIDmEIwgQ,47
45
+ qbraid_cli-0.11.0.dist-info/top_level.txt,sha256=LTYJgeYSCHo9Il8vZu0yIPuGdGyNaIw6iRy6BeoZo8o,11
46
+ qbraid_cli-0.11.0.dist-info/RECORD,,