cua-mcp-server 0.1.0__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.
Potentially problematic release.
This version of cua-mcp-server might be problematic. Click here for more details.
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: cua-mcp-server
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP Server for Computer-Use Agent (CUA)
|
|
5
|
+
Author-Email: TryCua <gh@trycua.com>
|
|
6
|
+
Requires-Python: <3.13,>=3.10
|
|
7
|
+
Requires-Dist: mcp<2.0.0,>=1.6.0
|
|
8
|
+
Requires-Dist: cua-agent<0.2.0,>=0.1.0
|
|
9
|
+
Requires-Dist: cua-computer<0.2.0,>=0.1.0
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
<div align="center">
|
|
13
|
+
<h1>
|
|
14
|
+
<div class="image-wrapper" style="display: inline-block;">
|
|
15
|
+
<picture>
|
|
16
|
+
<source media="(prefers-color-scheme: dark)" alt="logo" height="150" srcset="../../img/logo_white.png" style="display: block; margin: auto;">
|
|
17
|
+
<source media="(prefers-color-scheme: light)" alt="logo" height="150" srcset="../../img/logo_black.png" style="display: block; margin: auto;">
|
|
18
|
+
<img alt="Shows my svg">
|
|
19
|
+
</picture>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
[](#)
|
|
23
|
+
[](#)
|
|
24
|
+
[](https://discord.com/invite/mVnXXpdE85)
|
|
25
|
+
[](https://pypi.org/project/cua-computer/)
|
|
26
|
+
</h1>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
**cua-mcp-server** is a MCP server for the Computer-Use Agent (CUA), allowing you to run CUA through Claude Desktop or other MCP clients.
|
|
30
|
+
### Get started with Agent
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
Install the package from PyPI:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install cua-mcp-server
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This will install:
|
|
41
|
+
- The MCP server
|
|
42
|
+
- CUA agent and computer dependencies
|
|
43
|
+
- An executable `cua-mcp-server` script in your PATH
|
|
44
|
+
|
|
45
|
+
## Easy Setup Script
|
|
46
|
+
|
|
47
|
+
If you want to simplify installation, you can use this one-liner to download and run a setup script:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/mcp-server/scripts/run_mcp_server.sh | bash
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Or use the script directly in your MCP configuration like this:
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"mcpServers": {
|
|
58
|
+
"cua-agent": {
|
|
59
|
+
"command": "/bin/bash",
|
|
60
|
+
"args": ["-c", "curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/mcp-server/scripts/run_mcp_server.sh | bash"],
|
|
61
|
+
"env": {
|
|
62
|
+
"CUA_AGENT_LOOP": "OMNI",
|
|
63
|
+
"CUA_MODEL_PROVIDER": "ANTHROPIC",
|
|
64
|
+
"CUA_MODEL_NAME": "claude-3-7-sonnet-20250219",
|
|
65
|
+
"ANTHROPIC_API_KEY": "your-api-key"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
This script will automatically check if cua-mcp-server is installed, install it if needed, and run it.
|
|
73
|
+
|
|
74
|
+
## Claude Desktop Integration
|
|
75
|
+
|
|
76
|
+
To use with Claude Desktop, add an entry to your Claude Desktop configuration (`claude_desktop_config.json`, typically found in `~/.config/claude-desktop/`):
|
|
77
|
+
|
|
78
|
+
For more information on MCP with Claude Desktop, see the [official MCP User Guide](https://modelcontextprotocol.io/quickstart/user).
|
|
79
|
+
|
|
80
|
+
## Cursor Integration
|
|
81
|
+
|
|
82
|
+
To use with Cursor, add an MCP configuration file in one of these locations:
|
|
83
|
+
|
|
84
|
+
- **Project-specific**: Create `.cursor/mcp.json` in your project directory
|
|
85
|
+
- **Global**: Create `~/.cursor/mcp.json` in your home directory
|
|
86
|
+
|
|
87
|
+
After configuration, you can simply tell Cursor's Agent to perform computer tasks by explicitly mentioning the CUA agent, such as "Use the computer control tools to open Safari."
|
|
88
|
+
|
|
89
|
+
For more information on MCP with Cursor, see the [official Cursor MCP documentation](https://docs.cursor.com/context/model-context-protocol).
|
|
90
|
+
|
|
91
|
+
### First-time Usage Notes
|
|
92
|
+
|
|
93
|
+
**API Keys**: Ensure you have valid API keys:
|
|
94
|
+
- Add your Anthropic API key, or other model provider API key in the Claude Desktop config (as shown above)
|
|
95
|
+
- Or set it as an environment variable in your shell profile
|
|
96
|
+
|
|
97
|
+
## Configuration
|
|
98
|
+
|
|
99
|
+
The server is configured using environment variables (can be set in the Claude Desktop config):
|
|
100
|
+
|
|
101
|
+
| Variable | Description | Default |
|
|
102
|
+
|----------|-------------|---------|
|
|
103
|
+
| `CUA_AGENT_LOOP` | Agent loop to use (OPENAI, ANTHROPIC, OMNI) | OMNI |
|
|
104
|
+
| `CUA_MODEL_PROVIDER` | Model provider (ANTHROPIC, OPENAI, OLLAMA, OAICOMPAT) | ANTHROPIC |
|
|
105
|
+
| `CUA_MODEL_NAME` | Model name to use | None (provider default) |
|
|
106
|
+
| `CUA_PROVIDER_BASE_URL` | Base URL for provider API | None |
|
|
107
|
+
| `CUA_MAX_IMAGES` | Maximum number of images to keep in context | 3 |
|
|
108
|
+
|
|
109
|
+
## Available Tools
|
|
110
|
+
|
|
111
|
+
The MCP server exposes the following tools to Claude:
|
|
112
|
+
|
|
113
|
+
1. `run_cua_task` - Run a single Computer-Use Agent task with the given instruction
|
|
114
|
+
2. `run_multi_cua_tasks` - Run multiple tasks in sequence
|
|
115
|
+
|
|
116
|
+
## Usage
|
|
117
|
+
|
|
118
|
+
Once configured, you can simply ask Claude to perform computer tasks:
|
|
119
|
+
|
|
120
|
+
- "Open Chrome and go to github.com"
|
|
121
|
+
- "Create a folder called 'Projects' on my desktop"
|
|
122
|
+
- "Find all PDFs in my Downloads folder"
|
|
123
|
+
- "Take a screenshot and highlight the error message"
|
|
124
|
+
|
|
125
|
+
Claude will automatically use your CUA agent to perform these tasks.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1>
|
|
3
|
+
<div class="image-wrapper" style="display: inline-block;">
|
|
4
|
+
<picture>
|
|
5
|
+
<source media="(prefers-color-scheme: dark)" alt="logo" height="150" srcset="../../img/logo_white.png" style="display: block; margin: auto;">
|
|
6
|
+
<source media="(prefers-color-scheme: light)" alt="logo" height="150" srcset="../../img/logo_black.png" style="display: block; margin: auto;">
|
|
7
|
+
<img alt="Shows my svg">
|
|
8
|
+
</picture>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
[](#)
|
|
12
|
+
[](#)
|
|
13
|
+
[](https://discord.com/invite/mVnXXpdE85)
|
|
14
|
+
[](https://pypi.org/project/cua-computer/)
|
|
15
|
+
</h1>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
**cua-mcp-server** is a MCP server for the Computer-Use Agent (CUA), allowing you to run CUA through Claude Desktop or other MCP clients.
|
|
19
|
+
### Get started with Agent
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
Install the package from PyPI:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install cua-mcp-server
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This will install:
|
|
30
|
+
- The MCP server
|
|
31
|
+
- CUA agent and computer dependencies
|
|
32
|
+
- An executable `cua-mcp-server` script in your PATH
|
|
33
|
+
|
|
34
|
+
## Easy Setup Script
|
|
35
|
+
|
|
36
|
+
If you want to simplify installation, you can use this one-liner to download and run a setup script:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/mcp-server/scripts/run_mcp_server.sh | bash
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Or use the script directly in your MCP configuration like this:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"mcpServers": {
|
|
47
|
+
"cua-agent": {
|
|
48
|
+
"command": "/bin/bash",
|
|
49
|
+
"args": ["-c", "curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/mcp-server/scripts/run_mcp_server.sh | bash"],
|
|
50
|
+
"env": {
|
|
51
|
+
"CUA_AGENT_LOOP": "OMNI",
|
|
52
|
+
"CUA_MODEL_PROVIDER": "ANTHROPIC",
|
|
53
|
+
"CUA_MODEL_NAME": "claude-3-7-sonnet-20250219",
|
|
54
|
+
"ANTHROPIC_API_KEY": "your-api-key"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This script will automatically check if cua-mcp-server is installed, install it if needed, and run it.
|
|
62
|
+
|
|
63
|
+
## Claude Desktop Integration
|
|
64
|
+
|
|
65
|
+
To use with Claude Desktop, add an entry to your Claude Desktop configuration (`claude_desktop_config.json`, typically found in `~/.config/claude-desktop/`):
|
|
66
|
+
|
|
67
|
+
For more information on MCP with Claude Desktop, see the [official MCP User Guide](https://modelcontextprotocol.io/quickstart/user).
|
|
68
|
+
|
|
69
|
+
## Cursor Integration
|
|
70
|
+
|
|
71
|
+
To use with Cursor, add an MCP configuration file in one of these locations:
|
|
72
|
+
|
|
73
|
+
- **Project-specific**: Create `.cursor/mcp.json` in your project directory
|
|
74
|
+
- **Global**: Create `~/.cursor/mcp.json` in your home directory
|
|
75
|
+
|
|
76
|
+
After configuration, you can simply tell Cursor's Agent to perform computer tasks by explicitly mentioning the CUA agent, such as "Use the computer control tools to open Safari."
|
|
77
|
+
|
|
78
|
+
For more information on MCP with Cursor, see the [official Cursor MCP documentation](https://docs.cursor.com/context/model-context-protocol).
|
|
79
|
+
|
|
80
|
+
### First-time Usage Notes
|
|
81
|
+
|
|
82
|
+
**API Keys**: Ensure you have valid API keys:
|
|
83
|
+
- Add your Anthropic API key, or other model provider API key in the Claude Desktop config (as shown above)
|
|
84
|
+
- Or set it as an environment variable in your shell profile
|
|
85
|
+
|
|
86
|
+
## Configuration
|
|
87
|
+
|
|
88
|
+
The server is configured using environment variables (can be set in the Claude Desktop config):
|
|
89
|
+
|
|
90
|
+
| Variable | Description | Default |
|
|
91
|
+
|----------|-------------|---------|
|
|
92
|
+
| `CUA_AGENT_LOOP` | Agent loop to use (OPENAI, ANTHROPIC, OMNI) | OMNI |
|
|
93
|
+
| `CUA_MODEL_PROVIDER` | Model provider (ANTHROPIC, OPENAI, OLLAMA, OAICOMPAT) | ANTHROPIC |
|
|
94
|
+
| `CUA_MODEL_NAME` | Model name to use | None (provider default) |
|
|
95
|
+
| `CUA_PROVIDER_BASE_URL` | Base URL for provider API | None |
|
|
96
|
+
| `CUA_MAX_IMAGES` | Maximum number of images to keep in context | 3 |
|
|
97
|
+
|
|
98
|
+
## Available Tools
|
|
99
|
+
|
|
100
|
+
The MCP server exposes the following tools to Claude:
|
|
101
|
+
|
|
102
|
+
1. `run_cua_task` - Run a single Computer-Use Agent task with the given instruction
|
|
103
|
+
2. `run_multi_cua_tasks` - Run multiple tasks in sequence
|
|
104
|
+
|
|
105
|
+
## Usage
|
|
106
|
+
|
|
107
|
+
Once configured, you can simply ask Claude to perform computer tasks:
|
|
108
|
+
|
|
109
|
+
- "Open Chrome and go to github.com"
|
|
110
|
+
- "Create a folder called 'Projects' on my desktop"
|
|
111
|
+
- "Find all PDFs in my Downloads folder"
|
|
112
|
+
- "Take a screenshot and highlight the error message"
|
|
113
|
+
|
|
114
|
+
Claude will automatically use your CUA agent to perform these tasks.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""MCP Server for Computer-Use Agent (CUA)."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
# Add detailed debugging at import time
|
|
7
|
+
with open("/tmp/mcp_server_debug.log", "w") as f:
|
|
8
|
+
f.write(f"Python executable: {sys.executable}\n")
|
|
9
|
+
f.write(f"Python version: {sys.version}\n")
|
|
10
|
+
f.write(f"Working directory: {os.getcwd()}\n")
|
|
11
|
+
f.write(f"Python path:\n{chr(10).join(sys.path)}\n")
|
|
12
|
+
f.write(f"Environment variables:\n")
|
|
13
|
+
for key, value in os.environ.items():
|
|
14
|
+
f.write(f"{key}={value}\n")
|
|
15
|
+
|
|
16
|
+
from .server import server, main
|
|
17
|
+
|
|
18
|
+
__version__ = "0.1.0"
|
|
19
|
+
__all__ = ["server", "main"]
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
import traceback
|
|
6
|
+
from typing import Any, Dict, List, Optional, Union
|
|
7
|
+
|
|
8
|
+
# Configure logging to output to stderr for debug visibility
|
|
9
|
+
logging.basicConfig(
|
|
10
|
+
level=logging.DEBUG, # Changed to DEBUG
|
|
11
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
12
|
+
stream=sys.stderr,
|
|
13
|
+
)
|
|
14
|
+
logger = logging.getLogger("mcp-server")
|
|
15
|
+
|
|
16
|
+
# More visible startup message
|
|
17
|
+
logger.debug("MCP Server module loading...")
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
from mcp.server.fastmcp import Context, FastMCP
|
|
21
|
+
|
|
22
|
+
logger.debug("Successfully imported FastMCP")
|
|
23
|
+
except ImportError as e:
|
|
24
|
+
logger.error(f"Failed to import FastMCP: {e}")
|
|
25
|
+
traceback.print_exc(file=sys.stderr)
|
|
26
|
+
sys.exit(1)
|
|
27
|
+
|
|
28
|
+
try:
|
|
29
|
+
from computer import Computer
|
|
30
|
+
from agent import ComputerAgent, LLMProvider, LLM, AgentLoop
|
|
31
|
+
|
|
32
|
+
logger.debug("Successfully imported Computer and Agent modules")
|
|
33
|
+
except ImportError as e:
|
|
34
|
+
logger.error(f"Failed to import Computer/Agent modules: {e}")
|
|
35
|
+
traceback.print_exc(file=sys.stderr)
|
|
36
|
+
sys.exit(1)
|
|
37
|
+
|
|
38
|
+
# Global computer instance for reuse
|
|
39
|
+
global_computer = None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def get_env_bool(key: str, default: bool = False) -> bool:
|
|
43
|
+
"""Get boolean value from environment variable."""
|
|
44
|
+
return os.getenv(key, str(default)).lower() in ("true", "1", "yes")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def serve() -> FastMCP:
|
|
48
|
+
"""Create and configure the MCP server."""
|
|
49
|
+
server = FastMCP("cua-agent")
|
|
50
|
+
|
|
51
|
+
@server.tool()
|
|
52
|
+
async def run_cua_task(ctx: Context, task: str) -> str:
|
|
53
|
+
"""
|
|
54
|
+
Run a Computer-Use Agent (CUA) task and return the results.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
ctx: The MCP context
|
|
58
|
+
task: The instruction or task for the agent to perform
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
A string containing the agent's response
|
|
62
|
+
"""
|
|
63
|
+
global global_computer
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
logger.info(f"Starting CUA task: {task}")
|
|
67
|
+
|
|
68
|
+
# Initialize computer if needed
|
|
69
|
+
if global_computer is None:
|
|
70
|
+
global_computer = Computer(verbosity=logging.INFO)
|
|
71
|
+
await global_computer.run()
|
|
72
|
+
|
|
73
|
+
# Determine which loop to use
|
|
74
|
+
loop_str = os.getenv("CUA_AGENT_LOOP", "OMNI")
|
|
75
|
+
if loop_str == "OPENAI":
|
|
76
|
+
loop = AgentLoop.OPENAI
|
|
77
|
+
elif loop_str == "ANTHROPIC":
|
|
78
|
+
loop = AgentLoop.ANTHROPIC
|
|
79
|
+
else:
|
|
80
|
+
loop = AgentLoop.OMNI
|
|
81
|
+
|
|
82
|
+
# Determine provider
|
|
83
|
+
provider_str = os.getenv("CUA_MODEL_PROVIDER", "ANTHROPIC")
|
|
84
|
+
provider = getattr(LLMProvider, provider_str)
|
|
85
|
+
|
|
86
|
+
# Get model name (if specified)
|
|
87
|
+
model_name = os.getenv("CUA_MODEL_NAME", None)
|
|
88
|
+
|
|
89
|
+
# Get base URL for provider (if needed)
|
|
90
|
+
provider_base_url = os.getenv("CUA_PROVIDER_BASE_URL", None)
|
|
91
|
+
|
|
92
|
+
# Create agent with the specified configuration
|
|
93
|
+
agent = ComputerAgent(
|
|
94
|
+
computer=global_computer,
|
|
95
|
+
loop=loop,
|
|
96
|
+
model=LLM(
|
|
97
|
+
provider=provider,
|
|
98
|
+
name=model_name,
|
|
99
|
+
provider_base_url=provider_base_url,
|
|
100
|
+
),
|
|
101
|
+
save_trajectory=False,
|
|
102
|
+
only_n_most_recent_images=int(os.getenv("CUA_MAX_IMAGES", "3")),
|
|
103
|
+
verbosity=logging.INFO,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Collect all results
|
|
107
|
+
full_result = ""
|
|
108
|
+
async for result in agent.run(task):
|
|
109
|
+
logger.info(f"Agent step complete: {result.get('id', 'unknown')}")
|
|
110
|
+
|
|
111
|
+
# Add response ID to output
|
|
112
|
+
full_result += f"\n[Response ID: {result.get('id', 'unknown')}]\n"
|
|
113
|
+
|
|
114
|
+
# Extract and concatenate text responses
|
|
115
|
+
if "text" in result:
|
|
116
|
+
# Handle both string and dict responses
|
|
117
|
+
text_response = result.get("text", "")
|
|
118
|
+
if isinstance(text_response, str):
|
|
119
|
+
full_result += f"Response: {text_response}\n"
|
|
120
|
+
else:
|
|
121
|
+
# If it's a dict or other structure, convert to string representation
|
|
122
|
+
full_result += f"Response: {str(text_response)}\n"
|
|
123
|
+
|
|
124
|
+
# Log detailed information
|
|
125
|
+
if "tools" in result:
|
|
126
|
+
tools_info = result.get("tools")
|
|
127
|
+
logger.debug(f"Tools used: {tools_info}")
|
|
128
|
+
full_result += f"\nTools used: {tools_info}\n"
|
|
129
|
+
|
|
130
|
+
# Process output if available
|
|
131
|
+
outputs = result.get("output", [])
|
|
132
|
+
for output in outputs:
|
|
133
|
+
output_type = output.get("type")
|
|
134
|
+
if output_type == "reasoning":
|
|
135
|
+
logger.debug(f"Reasoning: {output}")
|
|
136
|
+
full_result += f"\nReasoning: {output.get('content', '')}\n"
|
|
137
|
+
elif output_type == "computer_call":
|
|
138
|
+
logger.debug(f"Computer call: {output}")
|
|
139
|
+
action = output.get("action", "")
|
|
140
|
+
result_value = output.get("result", "")
|
|
141
|
+
full_result += f"\nComputer Action: {action}\nResult: {result_value}\n"
|
|
142
|
+
|
|
143
|
+
# Add separator between steps
|
|
144
|
+
full_result += "\n" + "-" * 40 + "\n"
|
|
145
|
+
|
|
146
|
+
logger.info(f"CUA task completed successfully")
|
|
147
|
+
return full_result or "Task completed with no text output."
|
|
148
|
+
|
|
149
|
+
except Exception as e:
|
|
150
|
+
error_msg = f"Error running CUA task: {str(e)}\n{traceback.format_exc()}"
|
|
151
|
+
logger.error(error_msg)
|
|
152
|
+
return f"Error during task execution: {str(e)}"
|
|
153
|
+
|
|
154
|
+
@server.tool()
|
|
155
|
+
async def run_multi_cua_tasks(ctx: Context, tasks: List[str]) -> str:
|
|
156
|
+
"""
|
|
157
|
+
Run multiple CUA tasks in sequence and return the combined results.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
ctx: The MCP context
|
|
161
|
+
tasks: List of tasks to run in sequence
|
|
162
|
+
|
|
163
|
+
Returns:
|
|
164
|
+
Combined results from all tasks
|
|
165
|
+
"""
|
|
166
|
+
results = []
|
|
167
|
+
|
|
168
|
+
for i, task in enumerate(tasks):
|
|
169
|
+
logger.info(f"Running task {i+1}/{len(tasks)}: {task}")
|
|
170
|
+
result = await run_cua_task(ctx, task)
|
|
171
|
+
results.append(f"Task {i+1}: {task}\nResult: {result}\n")
|
|
172
|
+
|
|
173
|
+
return "\n".join(results)
|
|
174
|
+
|
|
175
|
+
return server
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
server = serve()
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def main():
|
|
182
|
+
"""Run the MCP server."""
|
|
183
|
+
try:
|
|
184
|
+
logger.debug("Starting MCP server...")
|
|
185
|
+
server.run()
|
|
186
|
+
except Exception as e:
|
|
187
|
+
logger.error(f"Error starting server: {e}")
|
|
188
|
+
traceback.print_exc(file=sys.stderr)
|
|
189
|
+
sys.exit(1)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
if __name__ == "__main__":
|
|
193
|
+
main()
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = [
|
|
3
|
+
"pdm-backend",
|
|
4
|
+
]
|
|
5
|
+
build-backend = "pdm.backend"
|
|
6
|
+
|
|
7
|
+
[project]
|
|
8
|
+
name = "cua-mcp-server"
|
|
9
|
+
description = "MCP Server for Computer-Use Agent (CUA)"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
requires-python = ">=3.10,<3.13"
|
|
12
|
+
version = "0.1.0"
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "TryCua", email = "gh@trycua.com" },
|
|
15
|
+
]
|
|
16
|
+
dependencies = [
|
|
17
|
+
"mcp>=1.6.0,<2.0.0",
|
|
18
|
+
"cua-agent>=0.1.0,<0.2.0",
|
|
19
|
+
"cua-computer>=0.1.0,<0.2.0",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.scripts]
|
|
23
|
+
cua-mcp-server = "mcp_server.server:main"
|
|
24
|
+
|
|
25
|
+
[tool.pdm]
|
|
26
|
+
distribution = true
|
|
27
|
+
|
|
28
|
+
[tool.pdm.dev-dependencies]
|
|
29
|
+
dev = [
|
|
30
|
+
"black>=23.9.1",
|
|
31
|
+
"ruff>=0.0.292",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[tool.black]
|
|
35
|
+
line-length = 100
|
|
36
|
+
target-version = [
|
|
37
|
+
"py310",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[tool.ruff]
|
|
41
|
+
line-length = 100
|
|
42
|
+
target-version = "0.1.0"
|
|
43
|
+
select = [
|
|
44
|
+
"E",
|
|
45
|
+
"F",
|
|
46
|
+
"B",
|
|
47
|
+
"I",
|
|
48
|
+
]
|
|
49
|
+
fix = true
|