universal-mcp 0.1.0__py3-none-any.whl → 0.1.1__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.
universal_mcp/cli.py CHANGED
@@ -1,9 +1,15 @@
1
1
  import typer
2
2
  from pathlib import Path
3
- import sys
3
+
4
+ from universal_mcp.utils.installation import (
5
+ get_supported_apps,
6
+ install_claude,
7
+ install_cursor,
8
+ )
4
9
 
5
10
  app = typer.Typer()
6
11
 
12
+
7
13
  @app.command()
8
14
  def generate(schema_path: Path = typer.Option(..., "--schema", "-s")):
9
15
  """Generate API client from OpenAPI schema"""
@@ -20,19 +26,22 @@ def generate(schema_path: Path = typer.Option(..., "--schema", "-s")):
20
26
  code = generate_api_client(schema)
21
27
  print(code)
22
28
 
29
+
23
30
  @app.command()
24
- def run():
31
+ def run(transport: str = typer.Option("stdio", "--transport", "-t")):
25
32
  """Run the MCP server"""
26
33
  from universal_mcp.servers.server import AgentRServer
27
- mcp = AgentRServer(name="AgentR Server", description="AgentR Server")
28
- mcp.run()
34
+
35
+ mcp = AgentRServer(name="AgentR Server", description="AgentR Server", port=8005)
36
+ mcp.run(transport=transport)
37
+
29
38
 
30
39
  @app.command()
31
40
  def install(app_name: str = typer.Argument(..., help="Name of app to install")):
32
41
  """Install an app"""
33
42
  # List of supported apps
34
- supported_apps = ["claude", "cursor"]
35
-
43
+ supported_apps = get_supported_apps()
44
+
36
45
  if app_name not in supported_apps:
37
46
  typer.echo("Available apps:")
38
47
  for app in supported_apps:
@@ -40,72 +49,35 @@ def install(app_name: str = typer.Argument(..., help="Name of app to install")):
40
49
  typer.echo(f"\nApp '{app_name}' not supported")
41
50
  raise typer.Exit(1)
42
51
 
43
- import json
44
-
45
52
  # Print instructions before asking for API key
46
- typer.echo("╭─ Instruction ─────────────────────────────────────────────────────────────────╮")
47
- typer.echo(" API key is required. Visit https://agentr.dev to create an API key. │")
48
- typer.echo("╰───────────────────────────────────────────────────────────────────────────────╯")
49
-
53
+ typer.echo(
54
+ "╭─ Instruction ─────────────────────────────────────────────────────────────────╮"
55
+ )
56
+ typer.echo(
57
+ "│ API key is required. Visit https://agentr.dev to create an API key. │"
58
+ )
59
+ typer.echo(
60
+ "╰───────────────────────────────────────────────────────────────────────────────╯"
61
+ )
62
+
50
63
  # Prompt for API key
51
64
  api_key = typer.prompt("Enter your AgentR API key", hide_input=True)
65
+ try:
66
+ if app_name == "claude":
67
+ typer.echo(f"Installing mcp server for: {app_name}")
68
+ install_claude(api_key)
69
+ typer.echo("App installed successfully")
70
+ elif app_name == "cursor":
71
+ typer.echo(f"Installing mcp server for: {app_name}")
72
+ install_cursor(api_key)
73
+ typer.echo("App installed successfully")
74
+ except Exception as e:
75
+ typer.echo(f"Error installing app: {e}", err=True)
76
+ import traceback
77
+
78
+ traceback.print_exc()
79
+ raise typer.Exit(1)
52
80
 
53
- if app_name == "claude":
54
- typer.echo(f"Installing mcp server for: {app_name}")
55
-
56
- # Determine platform-specific config path
57
- if sys.platform == "darwin": # macOS
58
- config_path = Path.home() / "Library/Application Support/Claude/claude_desktop_config.json"
59
- elif sys.platform == "win32": # Windows
60
- config_path = Path.home() / "AppData/Roaming/Claude/claude_desktop_config.json"
61
- else:
62
- typer.echo("Unsupported platform. Only macOS and Windows are currently supported.", err=True)
63
- raise typer.Exit(1)
64
-
65
-
66
- with open(config_path, 'r') as f:
67
- config = json.load(f)
68
- if 'mcpServers' not in config:
69
- config['mcpServers'] = {}
70
- config['mcpServers']['universal_mcp'] = {
71
- "command": "uvx",
72
- "args": ["universal_mcp@latest", "run"],
73
- "env": {
74
- "AGENTR_API_KEY": api_key
75
- }
76
- }
77
- with open(config_path, 'w') as f:
78
- json.dump(config, f, indent=4)
79
- typer.echo("App installed successfully")
80
- elif app_name == "cursor":
81
- typer.echo(f"Installing mcp server for: {app_name}")
82
-
83
- # Set up Cursor config path
84
- config_path = Path.home() / ".cursor/mcp.json"
85
-
86
- # Create config directory if it doesn't exist
87
- config_path.parent.mkdir(parents=True, exist_ok=True)
88
-
89
- # Create or load existing config
90
- if config_path.exists():
91
- with open(config_path, 'r') as f:
92
- config = json.load(f)
93
- else:
94
- config = {}
95
-
96
- if 'mcpServers' not in config:
97
- config['mcpServers'] = {}
98
- config['mcpServers']['universal_mcp'] = {
99
- "command": "uvx",
100
- "args": ["universal_mcp@latest", "run"],
101
- "env": {
102
- "AGENTR_API_KEY": api_key
103
- }
104
- }
105
-
106
- with open(config_path, 'w') as f:
107
- json.dump(config, f, indent=4)
108
- typer.echo("App installed successfully")
109
81
 
110
82
  if __name__ == "__main__":
111
83
  app()
@@ -16,7 +16,6 @@ class Server(FastMCP, ABC):
16
16
  """
17
17
  Server is responsible for managing the applications and the store
18
18
  It also acts as a router for the applications, and exposed to the client
19
-
20
19
  """
21
20
  def __init__(self, name: str, description: str, **kwargs):
22
21
  super().__init__(name, description, **kwargs)
@@ -0,0 +1,89 @@
1
+ import json
2
+ import sys
3
+ from pathlib import Path
4
+
5
+
6
+ def create_file_if_not_exists(path: Path) -> None:
7
+ """Create a file if it doesn't exist"""
8
+ if not path.exists():
9
+ with open(path, "w") as f:
10
+ json.dump({}, f)
11
+
12
+
13
+ def get_supported_apps() -> list[str]:
14
+ """Get list of supported apps"""
15
+ return ["claude", "cursor", "windsurf"]
16
+
17
+
18
+ def install_claude(api_key: str) -> None:
19
+ """Install Claude"""
20
+ # Determine platform-specific config path
21
+ if sys.platform == "darwin": # macOS
22
+ config_path = (
23
+ Path.home()
24
+ / "Library/Application Support/Claude/claude_desktop_config.json"
25
+ )
26
+ elif sys.platform == "win32": # Windows
27
+ config_path = Path.home() / "AppData/Roaming/Claude/claude_desktop_config.json"
28
+ else:
29
+ raise ValueError(
30
+ "Unsupported platform. Only macOS and Windows are currently supported.",
31
+ )
32
+
33
+ # Create config directory if it doesn't exist
34
+ create_file_if_not_exists(config_path)
35
+ try:
36
+ config = json.loads(config_path.read_text())
37
+ except json.JSONDecodeError:
38
+ config = {}
39
+ if "mcpServers" not in config:
40
+ config["mcpServers"] = {}
41
+ config["mcpServers"]["universal_mcp"] = {
42
+ "command": "uvx",
43
+ "args": ["universal_mcp@latest", "run"],
44
+ "env": {"AGENTR_API_KEY": api_key},
45
+ }
46
+ with open(config_path, "w") as f:
47
+ json.dump(config, f, indent=4)
48
+
49
+
50
+ def install_cursor(api_key: str) -> None:
51
+ """Install Cursor"""
52
+ # Set up Cursor config path
53
+ config_path = Path.home() / ".cursor/mcp.json"
54
+
55
+ # Create config directory if it doesn't exist
56
+ create_file_if_not_exists(config_path)
57
+
58
+ try:
59
+ config = json.loads(config_path.read_text())
60
+ except json.JSONDecodeError:
61
+ config = {}
62
+
63
+ if "mcpServers" not in config:
64
+ config["mcpServers"] = {}
65
+ config["mcpServers"]["universal_mcp"] = {
66
+ "command": "uvx",
67
+ "args": ["universal_mcp@latest", "run"],
68
+ "env": {"AGENTR_API_KEY": api_key},
69
+ }
70
+
71
+ with open(config_path, "w") as f:
72
+ json.dump(config, f, indent=4)
73
+
74
+
75
+ def install_windsurf() -> None:
76
+ """Install Windsurf"""
77
+ pass
78
+
79
+
80
+ def install_app(app_name: str) -> None:
81
+ """Install an app"""
82
+ if app_name == "claude":
83
+ install_claude()
84
+ elif app_name == "cursor":
85
+ install_cursor()
86
+ elif app_name == "windsurf":
87
+ install_windsurf()
88
+ else:
89
+ raise ValueError(f"App '{app_name}' not supported")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: universal-mcp
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Universal MCP acts as a middle ware for your API applications. It can store your credentials, authorize, enable disable apps on the fly and much more.
5
5
  Author-email: Manoj Bajaj <manojbajaj95@gmail.com>
6
6
  Requires-Python: >=3.11
@@ -10,6 +10,13 @@ Requires-Dist: pydantic-settings>=2.8.1
10
10
  Requires-Dist: pydantic>=2.11.1
11
11
  Requires-Dist: pyyaml>=6.0.2
12
12
  Requires-Dist: typer>=0.15.2
13
+ Provides-Extra: playground
14
+ Requires-Dist: fastapi[standard]>=0.115.12; extra == 'playground'
15
+ Requires-Dist: langchain-anthropic>=0.3.10; extra == 'playground'
16
+ Requires-Dist: langchain-mcp-adapters>=0.0.3; extra == 'playground'
17
+ Requires-Dist: langgraph-checkpoint-sqlite>=2.0.6; extra == 'playground'
18
+ Requires-Dist: langgraph>=0.3.24; extra == 'playground'
19
+ Requires-Dist: streamlit>=1.44.1; extra == 'playground'
13
20
  Provides-Extra: test
14
21
  Requires-Dist: pytest-asyncio>=0.26.0; extra == 'test'
15
22
  Requires-Dist: pytest>=8.3.5; extra == 'test'
@@ -87,6 +94,24 @@ if __name__ == "__main__":
87
94
  server.run()
88
95
  ```
89
96
 
97
+ ## Using Playground
98
+
99
+ Start MCP Server
100
+ ```bash
101
+ universal_mcp run -t sse
102
+ ```
103
+
104
+ Start FastAPI app
105
+ ```bash
106
+ fastapi run src/playground
107
+ ```
108
+
109
+ Start Frontend
110
+ ```bash
111
+ streamlit run src/playground/streamlit.py
112
+ ```
113
+
114
+
90
115
  ## 🧩 Available Applications
91
116
  AgentR comes with several pre-built applications:
92
117
 
@@ -1,10 +1,9 @@
1
1
  universal_mcp/__init__.py,sha256=2gdHpHaDDcsRjZjJ01FLN-1iidN_wbDAolNpxhGoFB4,59
2
- universal_mcp/cli.py,sha256=vbhiDfxnsJcMKhSpJyEA-YemrnlHgEMZ7BZll9pH8Xk,4152
2
+ universal_mcp/cli.py,sha256=BmO-_huXXKvBsg0S3REPDNdu1YNmmSz5-fXlFceJyg4,2848
3
3
  universal_mcp/config.py,sha256=YTygfFJPUuL-epRuILvt5tc5ACzByWIFFNhpFwHlDCE,387
4
4
  universal_mcp/exceptions.py,sha256=cPpdoioDrtNXD6QvH_GKs7bcQ5XRfX8wTrklC4mLS2g,273
5
5
  universal_mcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  universal_mcp/applications/__init__.py,sha256=8X1y7kzqBRYsx7vP5jKSagyi4wa5hkbj6d8f8XanKU4,1132
7
- universal_mcp/applications/agentr.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
7
  universal_mcp/applications/application.py,sha256=gHVR7jS0SusNiIm98yoy6RpR-uJsgnvYNa_6DanaPsY,3409
9
8
  universal_mcp/applications/github/app.py,sha256=yXVukXPvAtTAuwNRjo6VU_bt52Sp91P3-K7GUpa3jt4,14020
10
9
  universal_mcp/applications/google_calendar/app.py,sha256=tovWxCW6YM2DiXM7aEZyA7_u2w2IHlcGcvmj3NsQzyA,19897
@@ -18,12 +17,13 @@ universal_mcp/integrations/__init__.py,sha256=frBUL7zHnCeukXLuGL8g2P8Rx7D_1TryJQ
18
17
  universal_mcp/integrations/agentr.py,sha256=wmac5vwMvftv8PWR54_42fYGlQloFejx76e-vxa597Q,3385
19
18
  universal_mcp/integrations/integration.py,sha256=R4yATIL6JcuPmFZQknQgWv9mb5eGIcpoismOx2VkKPs,4647
20
19
  universal_mcp/servers/__init__.py,sha256=IA9hGn0pebJx4hzTdcsRlH4rPD6BAeuw-7VG_WlRzFw,105
21
- universal_mcp/servers/server.py,sha256=RzqX0slJOzgU9rxJJECEHQyVGNUAlAeDaOrLrtdwXRc,5276
20
+ universal_mcp/servers/server.py,sha256=vGnqdCd6AA1uh0G87GyfbCXuKqjR12gC2TDnGhFzFYU,5275
22
21
  universal_mcp/stores/__init__.py,sha256=2_qV1Np4GIrFPdH5CIKLeXEXn2b_ImoOTXmaEuHLc6g,135
23
22
  universal_mcp/stores/store.py,sha256=fB3uAaobnWf2ILcDBmg3ToDaqAIPYlLtmHBdpmkcGcI,1585
24
23
  universal_mcp/utils/bridge.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ universal_mcp/utils/installation.py,sha256=DXcl6voNn1Ihx717KIo2LBzFi_67ffDUxvPu8j0bMyY,2498
25
25
  universal_mcp/utils/openapi.py,sha256=YvDAUohGkcUf2j1-C9jXCF9DaM4ovnr2NlwejFRxGdI,9590
26
- universal_mcp-0.1.0.dist-info/METADATA,sha256=pRUC64lsW_p2E9lBiRnQe_SnjIcbWkr1N1enzRGFMNY,4506
27
- universal_mcp-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
28
- universal_mcp-0.1.0.dist-info/entry_points.txt,sha256=QlBrVKmA2jIM0q-C-3TQMNJTTWOsOFQvgedBq2rZTS8,56
29
- universal_mcp-0.1.0.dist-info/RECORD,,
26
+ universal_mcp-0.1.1.dist-info/METADATA,sha256=KFEK1nblKHpSOiRxmJEpbPHAIFzcaYF1vXCCVTlhJAc,5123
27
+ universal_mcp-0.1.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
28
+ universal_mcp-0.1.1.dist-info/entry_points.txt,sha256=QlBrVKmA2jIM0q-C-3TQMNJTTWOsOFQvgedBq2rZTS8,56
29
+ universal_mcp-0.1.1.dist-info/RECORD,,
File without changes