astrax-mcp 0.2.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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Astrax
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,239 @@
1
+ Metadata-Version: 2.5
2
+ Name: astrax-mcp
3
+ Version: 0.2.0
4
+ Summary: Agentic System Telemetry, Realtime Automation & X-control: servidor MCP que da ojos y manos a tu IA
5
+ Project-URL: Homepage, https://github.com/AstraxOf/astrax-mcp
6
+ Project-URL: Telegram, https://t.me/AstraxMCP
7
+ Project-URL: YouTube, https://youtube.com/@AstraxOf
8
+ License-File: LICENSE
9
+ Keywords: ai-agents,automation,computer-use,mcp,model-context-protocol,pyautogui
10
+ Classifier: Operating System :: MacOS
11
+ Classifier: Operating System :: Microsoft :: Windows
12
+ Classifier: Operating System :: POSIX :: Linux
13
+ Classifier: Programming Language :: Python :: 3
14
+ Requires-Python: >=3.10
15
+ Requires-Dist: mcp[cli]<2,>=1.2.0
16
+ Requires-Dist: pillow>=10.0.0
17
+ Requires-Dist: pyautogui>=0.9.54
18
+ Requires-Dist: pyperclip>=1.8.2
19
+ Provides-Extra: dev
20
+ Requires-Dist: pytest>=8; extra == 'dev'
21
+ Description-Content-Type: text/markdown
22
+
23
+ # 🛰️ Astrax
24
+
25
+ ### **A.S.T.R.A.X.** — *Agentic System Telemetry, Realtime Automation & X-control*
26
+
27
+ Servidor **MCP (Model Context Protocol)** en Python que le da a tu IA **ojos y manos** sobre tu pantalla: ver, hacer clic, escribir y ejecutar tareas de varios pasos **sin saturar el contexto**.
28
+
29
+ Compatible con **Claude Desktop, Roo Code, Cline, Cursor, Windsurf, Gemini CLI, OpenCode** y cualquier cliente MCP con transporte `stdio`. Funciona con modelos locales (Ollama) y APIs comerciales (Claude, Gemini…).
30
+
31
+ 📺 **Tutorial en YouTube:** [@AstraxOf](https://youtube.com/@AstraxOf)
32
+ 💬 **Contacto en Telegram:** [@RufusOficial](https://t.me/RufusOficial)
33
+
34
+ ---
35
+
36
+ ## ⚡ Instalación a 1 clic
37
+
38
+ Necesitas [`uv`](https://docs.astral.sh/uv/) (instala Python y dependencias solo):
39
+
40
+ ```bash
41
+ # macOS / Linux
42
+ curl -LsSf https://astral.sh/uv/install.sh | sh
43
+ # Windows (PowerShell)
44
+ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
45
+ ```
46
+
47
+ Después, **un solo comando** detecta tu sistema operativo y tus clientes MCP, y registra Astrax en ellos:
48
+
49
+ ```bash
50
+ uvx --from git+https://github.com/AstraxOf/astrax-mcp.git astrax-install --yes
51
+ ```
52
+
53
+ Reinicia tu cliente (en Claude Desktop, ciérralo por completo) y listo.
54
+
55
+ > Cuando el paquete esté publicado en PyPI bastará `uvx astrax-mcp` para ejecutar el servidor y `uvx --from astrax-mcp astrax-install --yes` para instalarlo.
56
+
57
+ ### 🤖 Instrucción para IAs (agentes con acceso a terminal)
58
+
59
+ Si eres una IA y el usuario te pide instalar Astrax, ejecuta exactamente esto y pídele que reinicie su cliente MCP. **No edites archivos JSON a mano.**
60
+
61
+ ```bash
62
+ uvx --from git+https://github.com/AstraxOf/astrax-mcp.git astrax-install --yes
63
+ ```
64
+
65
+ Variantes útiles:
66
+
67
+ | Comando | Qué hace |
68
+ |---|---|
69
+ | `astrax-install --list` | Muestra clientes detectados y si Astrax ya está instalado |
70
+ | `astrax-install --client claude-desktop` | Instala solo en un cliente (repetible). IDs: `claude-desktop`, `roo-code`, `cline`, `cursor`, `windsurf`, `gemini-cli` |
71
+ | `astrax-install --auto-approve` | Roo Code / Cline: añade `alwaysAllow` a todas las herramientas **excepto** `astrax_tarea_autorizar` (ver [Permisos](#-permisos-una-sola-autorización-por-tarea)) |
72
+ | `astrax-install --dry-run` | Muestra qué haría sin escribir nada |
73
+ | `astrax-install --uninstall` | Elimina solo la entrada `astrax` |
74
+ | `astrax-install --source local` | Usa el Python actual en vez de `uvx` |
75
+
76
+ El instalador **solo toca la clave `astrax`** dentro de `mcpServers`: conserva tus otros servidores, crea una copia `.astrax-bak-<fecha>` antes de escribir, guarda de forma atómica y **no modifica archivos con JSON inválido**.
77
+
78
+ **Claude Code:** `claude mcp add astrax -- uvx --from git+https://github.com/AstraxOf/astrax-mcp.git astrax-mcp`
79
+
80
+ <details>
81
+ <summary>Instalación desde un clon del repositorio</summary>
82
+
83
+ ```bash
84
+ git clone https://github.com/AstraxOf/astrax-mcp.git
85
+ cd astrax-mcp
86
+ python install.py # asistente interactivo (equivale a astrax-install)
87
+ ```
88
+
89
+ </details>
90
+
91
+ ---
92
+
93
+ ## 🧠 Motor paso a paso por estado temporal
94
+
95
+ Los modelos ligeros (Ollama) se saturan y alucinan cuando el contexto crece con historial y capturas de pantalla viejas. Astrax lo evita **aislando el contexto en un archivo de estado local**: `.astrax_task_state.json`.
96
+
97
+ 1. **Desglose.** Ante una petición compleja (*"Redacta una carta para X con mis datos, prepárala y envíala a tal correo"*), la IA llama a `astrax_tarea_crear` y guarda el plan como pasos ordenados.
98
+ 2. **Lectura directa.** Para cada paso, la IA llama a `astrax_tarea_estado`: recibe solo el **paso actual, el siguiente y los datos guardados** (un JSON de unas pocas líneas) en lugar de releer toda la conversación, el prompt inicial o capturas pasadas.
99
+ 3. **Caché de salidas.** Al cerrar un paso con `astrax_tarea_completar_paso`, la IA guarda lo relevante, por ejemplo `{"pdf_generado": "/rutas/carta.pdf"}`. El paso siguiente (adjuntar al correo) consulta solo ese dato y usa la ruta exacta, sin adivinarla.
100
+ 4. **Cierre.** Al terminar el último paso la tarea queda `completada`, los permisos se **revocan** y se borran las capturas temporales. `astrax_tarea_limpiar` elimina el archivo.
101
+
102
+ Detalles que protegen al modelo:
103
+
104
+ - **Guarda rutas, no contenidos:** cada dato admite hasta 4000 caracteres; si es más, la herramienta pide guardarlo en un archivo y almacenar la ruta.
105
+ - **Anti-bucles:** un paso que falla 3 veces pasa a `bloqueada` y la IA debe parar y explicar al usuario qué ocurrió.
106
+ - **Sin imágenes pesadas en el historial:** las acciones devuelven texto corto; solo `astrax_ver_pantalla` devuelve imagen, cuando hace falta verificar.
107
+ - **Ubicación:** carpeta privada del usuario (`~/.cache/astrax`, `~/Library/Caches/astrax` o `%LOCALAPPDATA%\astrax`), con permisos restringidos. Cámbiala con `ASTRAX_HOME`.
108
+
109
+ ---
110
+
111
+ ## 🔐 Permisos: una sola autorización por tarea
112
+
113
+ Antes de ejecutar nada, la IA declara **todo lo que necesitará la tarea completa** en `astrax_tarea_crear`:
114
+
115
+ | Permiso | Habilita |
116
+ |---|---|
117
+ | `pantalla` | `astrax_ver_pantalla`, `astrax_capturar_pantalla` |
118
+ | `raton_teclado` | clic, doble clic, teclas, atajos, scroll, escribir |
119
+ | `portapapeles` | `astrax_portapapeles` y escritura de texto no ASCII (ñ, tildes, emojis) |
120
+ | `terminal` | `astrax_ejecutar_comando` |
121
+
122
+ Después muestra el plan y los permisos, **pide tu confirmación una sola vez** y llama a `astrax_tarea_autorizar`. Desde ese momento puede trabajar de forma desatendida durante la sesión (60 min por defecto, `ASTRAX_SESSION_MINUTES`). Las herramientas de acción **rechazan** cualquier uso fuera de una tarea autorizada o de un permiso no solicitado.
123
+
124
+ **Cómo evitar las confirmaciones por paso en tu cliente:** el servidor no puede saltarse las confirmaciones que muestra el cliente. Por eso `astrax-install --auto-approve` (Roo Code / Cline) marca como "permitir siempre" todas las herramientas *excepto* `astrax_tarea_autorizar`: tu cliente te pregunta **una vez**, justo en la autorización, y no durante la ejecución. En otros clientes (p. ej. Claude Desktop) elige "Permitir siempre" en esa herramienta o en el resto cuando te lo pida.
125
+
126
+ Para volver al comportamiento anterior sin tareas ni sesiones: `ASTRAX_REQUIRE_SESSION=0`.
127
+
128
+ ---
129
+
130
+ ## ✨ ¿Qué puede hacer?
131
+
132
+ | Herramienta | Descripción |
133
+ |---|---|
134
+ | `astrax_tarea_crear` | Guarda el plan por pasos y los permisos que necesita la tarea completa |
135
+ | `astrax_tarea_autorizar` | Concede los permisos tras la confirmación del usuario |
136
+ | `astrax_tarea_estado` | Lee el paso actual, el siguiente y los datos guardados |
137
+ | `astrax_tarea_guardar` | Guarda un dato clave (rutas, ids…) |
138
+ | `astrax_tarea_completar_paso` | Cierra el paso, guarda salidas y devuelve el siguiente |
139
+ | `astrax_tarea_limpiar` | Borra el estado y las capturas temporales |
140
+ | `astrax_ver_pantalla` | **La IA ve la pantalla**: captura como imagen (marca roja en el cursor) |
141
+ | `astrax_capturar_pantalla` | Guarda un PNG y devuelve la ruta |
142
+ | `astrax_info_pantalla` | Ancho y alto de la pantalla |
143
+ | `astrax_clic` / `astrax_doble_clic` | Clic en `(x, y)` con validación de límites |
144
+ | `astrax_escribir` | Teclea texto (soporta `ñ`, tildes y emojis vía portapapeles) |
145
+ | `astrax_tecla` / `astrax_atajo` | Teclas sueltas y atajos (`["ctrl", "t"]`…) |
146
+ | `astrax_scroll` | Rueda del ratón arriba/abajo |
147
+ | `astrax_esperar` | Espera a que cargue una app o página |
148
+ | `astrax_portapapeles` | Lee o escribe el portapapeles |
149
+ | `astrax_ejecutar_comando` | Ejecuta un comando de shell con timeout y salida recortada |
150
+
151
+ Ejemplo de prompt:
152
+
153
+ > *"Usa Astrax: redacta una carta para Ana con mis datos, guárdala como PDF y envíala a ana@ejemplo.com con el asunto 'Propuesta'."*
154
+
155
+ ---
156
+
157
+ ## ⚙️ Configuración manual
158
+
159
+ Si prefieres no usar el instalador, añade esto a tu `mcp_settings.json` (o al archivo equivalente de tu cliente):
160
+
161
+ ```json
162
+ {
163
+ "mcpServers": {
164
+ "astrax": {
165
+ "command": "uvx",
166
+ "args": ["--from", "git+https://github.com/AstraxOf/astrax-mcp.git", "astrax-mcp"]
167
+ }
168
+ }
169
+ }
170
+ ```
171
+
172
+ > En clientes de escritorio que no heredan tu `PATH`, usa la ruta absoluta de `uvx` (`which uvx` / `where uvx`). El instalador ya lo hace por ti.
173
+
174
+ ---
175
+
176
+ ## 🛡️ Seguridad
177
+
178
+ Astrax controla tu ratón, teclado y (si lo autorizas) tu terminal reales. Úsalo con cabeza:
179
+
180
+ - **Fail-safe activo:** mueve el ratón a una esquina de la pantalla para abortar cualquier automatización.
181
+ - **Permisos mínimos:** la IA solo recibe los permisos que declara y que tú confirmas; se revocan al terminar o al bloquearse la tarea.
182
+ - Los clics fuera de los límites de la pantalla se rechazan.
183
+ - `astrax_ejecutar_comando` bloquea patrones destructivos obvios (`rm -rf /`, `mkfs`, `format C:`, `shutdown`…). **Es una red de seguridad contra accidentes, no un sandbox.** Concede `terminal` solo si confías en la tarea y la supervisas.
184
+ - Evita ejecutarlo mientras tengas abiertos datos sensibles (contraseñas, banca, etc.).
185
+
186
+ ---
187
+
188
+ ## 🖥️ Notas por sistema operativo
189
+
190
+ - **Windows:** funciona sin configuración extra.
191
+ - **macOS:** concede permisos de *Grabación de pantalla* y *Accesibilidad* a tu terminal o editor.
192
+ - **Linux:** funciona en X11 (Wayland suele bloquear captura y control). Puede hacer falta `sudo apt install python3-tk python3-dev scrot xclip`.
193
+
194
+ ---
195
+
196
+ ## 🧩 Arquitectura
197
+
198
+ ```
199
+ astrax-mcp/
200
+ ├── pyproject.toml # entry points: astrax-mcp, astrax-install
201
+ ├── install.py # atajo para quien clona el repo
202
+ ├── mcp_settings.json # ejemplo (Roo Code / Cline)
203
+ ├── tests/
204
+ └── src/astrax_mcp/
205
+ ├── server.py # construye el servidor y registra los módulos
206
+ ├── config.py # constantes, rutas y variables ASTRAX_*
207
+ ├── state.py # motor del archivo de estado de tareas (sin dependencias de MCP)
208
+ ├── tasks.py # herramientas MCP del gestor de tareas
209
+ ├── permissions.py # verificación de permisos de sesión
210
+ ├── vision.py # captura y visión de pantalla
211
+ ├── control.py # ratón, teclado, scroll, esperas
212
+ ├── system.py # terminal y portapapeles
213
+ ├── gui.py # acceso perezoso a pyautogui + validaciones
214
+ ├── utils.py # log a stderr, errores uniformes, truncado
215
+ ├── compat.py # SDK MCP v1 (FastMCP) / v2 (MCPServer)
216
+ └── installer.py # wizard de instalación multiplataforma
217
+ ```
218
+
219
+ - Basado en el SDK oficial de MCP para Python. `compat.py` usa `MCPServer` (v2) y recurre a `FastMCP` (v1.x); `pyproject.toml` fija `mcp<2` como en la configuración original: quita el tope cuando pruebes el SDK v2.
220
+ - Transporte `stdio`; todos los logs van a `stderr` para no corromper el flujo JSON-RPC.
221
+ - Las capturas se normalizan al tamaño lógico de pantalla: las coordenadas de la imagen coinciden con las del clic, incluso en HiDPI/Retina. La calidad JPEG se ajusta con `ASTRAX_JPEG_QUALITY` (30-95, por defecto 65).
222
+ - Tests: `pip install -e ".[dev]" && pytest`
223
+
224
+ ---
225
+
226
+ ## 🤝 Contribuciones / Community
227
+
228
+ Astrax es **Open Source** y crece con la comunidad. Si quieres sumarte, eres bienvenido: puedes abrir *issues*, enviar *pull requests*, proponer ideas, probar Astrax en otros sistemas o clientes MCP y reportar errores.
229
+
230
+ - 📧 **Correo de contacto:** [avpn497@gmail.com](mailto:avpn497@gmail.com)
231
+ - 📢 **Canal oficial de Telegram:** [https://t.me/AstraxMCP](https://t.me/AstraxMCP) — únete al canal para aportar, hacer preguntas o reportar problemas.
232
+ - 📺 **YouTube:** [@AstraxOf](https://youtube.com/@AstraxOf) — tutoriales y novedades
233
+ - 💬 **Creador en Telegram:** [@RufusOficial](https://t.me/RufusOficial)
234
+
235
+ Si te sirvió el proyecto, deja una ⭐ en el repositorio y suscríbete al canal.
236
+
237
+ ---
238
+
239
+ <p align="center">Hecho con 💙 por <b>Rufus</b> · <a href="https://youtube.com/@AstraxOf">@AstraxOf</a></p>
@@ -0,0 +1,217 @@
1
+ # 🛰️ Astrax
2
+
3
+ ### **A.S.T.R.A.X.** — *Agentic System Telemetry, Realtime Automation & X-control*
4
+
5
+ Servidor **MCP (Model Context Protocol)** en Python que le da a tu IA **ojos y manos** sobre tu pantalla: ver, hacer clic, escribir y ejecutar tareas de varios pasos **sin saturar el contexto**.
6
+
7
+ Compatible con **Claude Desktop, Roo Code, Cline, Cursor, Windsurf, Gemini CLI, OpenCode** y cualquier cliente MCP con transporte `stdio`. Funciona con modelos locales (Ollama) y APIs comerciales (Claude, Gemini…).
8
+
9
+ 📺 **Tutorial en YouTube:** [@AstraxOf](https://youtube.com/@AstraxOf)
10
+ 💬 **Contacto en Telegram:** [@RufusOficial](https://t.me/RufusOficial)
11
+
12
+ ---
13
+
14
+ ## ⚡ Instalación a 1 clic
15
+
16
+ Necesitas [`uv`](https://docs.astral.sh/uv/) (instala Python y dependencias solo):
17
+
18
+ ```bash
19
+ # macOS / Linux
20
+ curl -LsSf https://astral.sh/uv/install.sh | sh
21
+ # Windows (PowerShell)
22
+ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
23
+ ```
24
+
25
+ Después, **un solo comando** detecta tu sistema operativo y tus clientes MCP, y registra Astrax en ellos:
26
+
27
+ ```bash
28
+ uvx --from git+https://github.com/AstraxOf/astrax-mcp.git astrax-install --yes
29
+ ```
30
+
31
+ Reinicia tu cliente (en Claude Desktop, ciérralo por completo) y listo.
32
+
33
+ > Cuando el paquete esté publicado en PyPI bastará `uvx astrax-mcp` para ejecutar el servidor y `uvx --from astrax-mcp astrax-install --yes` para instalarlo.
34
+
35
+ ### 🤖 Instrucción para IAs (agentes con acceso a terminal)
36
+
37
+ Si eres una IA y el usuario te pide instalar Astrax, ejecuta exactamente esto y pídele que reinicie su cliente MCP. **No edites archivos JSON a mano.**
38
+
39
+ ```bash
40
+ uvx --from git+https://github.com/AstraxOf/astrax-mcp.git astrax-install --yes
41
+ ```
42
+
43
+ Variantes útiles:
44
+
45
+ | Comando | Qué hace |
46
+ |---|---|
47
+ | `astrax-install --list` | Muestra clientes detectados y si Astrax ya está instalado |
48
+ | `astrax-install --client claude-desktop` | Instala solo en un cliente (repetible). IDs: `claude-desktop`, `roo-code`, `cline`, `cursor`, `windsurf`, `gemini-cli` |
49
+ | `astrax-install --auto-approve` | Roo Code / Cline: añade `alwaysAllow` a todas las herramientas **excepto** `astrax_tarea_autorizar` (ver [Permisos](#-permisos-una-sola-autorización-por-tarea)) |
50
+ | `astrax-install --dry-run` | Muestra qué haría sin escribir nada |
51
+ | `astrax-install --uninstall` | Elimina solo la entrada `astrax` |
52
+ | `astrax-install --source local` | Usa el Python actual en vez de `uvx` |
53
+
54
+ El instalador **solo toca la clave `astrax`** dentro de `mcpServers`: conserva tus otros servidores, crea una copia `.astrax-bak-<fecha>` antes de escribir, guarda de forma atómica y **no modifica archivos con JSON inválido**.
55
+
56
+ **Claude Code:** `claude mcp add astrax -- uvx --from git+https://github.com/AstraxOf/astrax-mcp.git astrax-mcp`
57
+
58
+ <details>
59
+ <summary>Instalación desde un clon del repositorio</summary>
60
+
61
+ ```bash
62
+ git clone https://github.com/AstraxOf/astrax-mcp.git
63
+ cd astrax-mcp
64
+ python install.py # asistente interactivo (equivale a astrax-install)
65
+ ```
66
+
67
+ </details>
68
+
69
+ ---
70
+
71
+ ## 🧠 Motor paso a paso por estado temporal
72
+
73
+ Los modelos ligeros (Ollama) se saturan y alucinan cuando el contexto crece con historial y capturas de pantalla viejas. Astrax lo evita **aislando el contexto en un archivo de estado local**: `.astrax_task_state.json`.
74
+
75
+ 1. **Desglose.** Ante una petición compleja (*"Redacta una carta para X con mis datos, prepárala y envíala a tal correo"*), la IA llama a `astrax_tarea_crear` y guarda el plan como pasos ordenados.
76
+ 2. **Lectura directa.** Para cada paso, la IA llama a `astrax_tarea_estado`: recibe solo el **paso actual, el siguiente y los datos guardados** (un JSON de unas pocas líneas) en lugar de releer toda la conversación, el prompt inicial o capturas pasadas.
77
+ 3. **Caché de salidas.** Al cerrar un paso con `astrax_tarea_completar_paso`, la IA guarda lo relevante, por ejemplo `{"pdf_generado": "/rutas/carta.pdf"}`. El paso siguiente (adjuntar al correo) consulta solo ese dato y usa la ruta exacta, sin adivinarla.
78
+ 4. **Cierre.** Al terminar el último paso la tarea queda `completada`, los permisos se **revocan** y se borran las capturas temporales. `astrax_tarea_limpiar` elimina el archivo.
79
+
80
+ Detalles que protegen al modelo:
81
+
82
+ - **Guarda rutas, no contenidos:** cada dato admite hasta 4000 caracteres; si es más, la herramienta pide guardarlo en un archivo y almacenar la ruta.
83
+ - **Anti-bucles:** un paso que falla 3 veces pasa a `bloqueada` y la IA debe parar y explicar al usuario qué ocurrió.
84
+ - **Sin imágenes pesadas en el historial:** las acciones devuelven texto corto; solo `astrax_ver_pantalla` devuelve imagen, cuando hace falta verificar.
85
+ - **Ubicación:** carpeta privada del usuario (`~/.cache/astrax`, `~/Library/Caches/astrax` o `%LOCALAPPDATA%\astrax`), con permisos restringidos. Cámbiala con `ASTRAX_HOME`.
86
+
87
+ ---
88
+
89
+ ## 🔐 Permisos: una sola autorización por tarea
90
+
91
+ Antes de ejecutar nada, la IA declara **todo lo que necesitará la tarea completa** en `astrax_tarea_crear`:
92
+
93
+ | Permiso | Habilita |
94
+ |---|---|
95
+ | `pantalla` | `astrax_ver_pantalla`, `astrax_capturar_pantalla` |
96
+ | `raton_teclado` | clic, doble clic, teclas, atajos, scroll, escribir |
97
+ | `portapapeles` | `astrax_portapapeles` y escritura de texto no ASCII (ñ, tildes, emojis) |
98
+ | `terminal` | `astrax_ejecutar_comando` |
99
+
100
+ Después muestra el plan y los permisos, **pide tu confirmación una sola vez** y llama a `astrax_tarea_autorizar`. Desde ese momento puede trabajar de forma desatendida durante la sesión (60 min por defecto, `ASTRAX_SESSION_MINUTES`). Las herramientas de acción **rechazan** cualquier uso fuera de una tarea autorizada o de un permiso no solicitado.
101
+
102
+ **Cómo evitar las confirmaciones por paso en tu cliente:** el servidor no puede saltarse las confirmaciones que muestra el cliente. Por eso `astrax-install --auto-approve` (Roo Code / Cline) marca como "permitir siempre" todas las herramientas *excepto* `astrax_tarea_autorizar`: tu cliente te pregunta **una vez**, justo en la autorización, y no durante la ejecución. En otros clientes (p. ej. Claude Desktop) elige "Permitir siempre" en esa herramienta o en el resto cuando te lo pida.
103
+
104
+ Para volver al comportamiento anterior sin tareas ni sesiones: `ASTRAX_REQUIRE_SESSION=0`.
105
+
106
+ ---
107
+
108
+ ## ✨ ¿Qué puede hacer?
109
+
110
+ | Herramienta | Descripción |
111
+ |---|---|
112
+ | `astrax_tarea_crear` | Guarda el plan por pasos y los permisos que necesita la tarea completa |
113
+ | `astrax_tarea_autorizar` | Concede los permisos tras la confirmación del usuario |
114
+ | `astrax_tarea_estado` | Lee el paso actual, el siguiente y los datos guardados |
115
+ | `astrax_tarea_guardar` | Guarda un dato clave (rutas, ids…) |
116
+ | `astrax_tarea_completar_paso` | Cierra el paso, guarda salidas y devuelve el siguiente |
117
+ | `astrax_tarea_limpiar` | Borra el estado y las capturas temporales |
118
+ | `astrax_ver_pantalla` | **La IA ve la pantalla**: captura como imagen (marca roja en el cursor) |
119
+ | `astrax_capturar_pantalla` | Guarda un PNG y devuelve la ruta |
120
+ | `astrax_info_pantalla` | Ancho y alto de la pantalla |
121
+ | `astrax_clic` / `astrax_doble_clic` | Clic en `(x, y)` con validación de límites |
122
+ | `astrax_escribir` | Teclea texto (soporta `ñ`, tildes y emojis vía portapapeles) |
123
+ | `astrax_tecla` / `astrax_atajo` | Teclas sueltas y atajos (`["ctrl", "t"]`…) |
124
+ | `astrax_scroll` | Rueda del ratón arriba/abajo |
125
+ | `astrax_esperar` | Espera a que cargue una app o página |
126
+ | `astrax_portapapeles` | Lee o escribe el portapapeles |
127
+ | `astrax_ejecutar_comando` | Ejecuta un comando de shell con timeout y salida recortada |
128
+
129
+ Ejemplo de prompt:
130
+
131
+ > *"Usa Astrax: redacta una carta para Ana con mis datos, guárdala como PDF y envíala a ana@ejemplo.com con el asunto 'Propuesta'."*
132
+
133
+ ---
134
+
135
+ ## ⚙️ Configuración manual
136
+
137
+ Si prefieres no usar el instalador, añade esto a tu `mcp_settings.json` (o al archivo equivalente de tu cliente):
138
+
139
+ ```json
140
+ {
141
+ "mcpServers": {
142
+ "astrax": {
143
+ "command": "uvx",
144
+ "args": ["--from", "git+https://github.com/AstraxOf/astrax-mcp.git", "astrax-mcp"]
145
+ }
146
+ }
147
+ }
148
+ ```
149
+
150
+ > En clientes de escritorio que no heredan tu `PATH`, usa la ruta absoluta de `uvx` (`which uvx` / `where uvx`). El instalador ya lo hace por ti.
151
+
152
+ ---
153
+
154
+ ## 🛡️ Seguridad
155
+
156
+ Astrax controla tu ratón, teclado y (si lo autorizas) tu terminal reales. Úsalo con cabeza:
157
+
158
+ - **Fail-safe activo:** mueve el ratón a una esquina de la pantalla para abortar cualquier automatización.
159
+ - **Permisos mínimos:** la IA solo recibe los permisos que declara y que tú confirmas; se revocan al terminar o al bloquearse la tarea.
160
+ - Los clics fuera de los límites de la pantalla se rechazan.
161
+ - `astrax_ejecutar_comando` bloquea patrones destructivos obvios (`rm -rf /`, `mkfs`, `format C:`, `shutdown`…). **Es una red de seguridad contra accidentes, no un sandbox.** Concede `terminal` solo si confías en la tarea y la supervisas.
162
+ - Evita ejecutarlo mientras tengas abiertos datos sensibles (contraseñas, banca, etc.).
163
+
164
+ ---
165
+
166
+ ## 🖥️ Notas por sistema operativo
167
+
168
+ - **Windows:** funciona sin configuración extra.
169
+ - **macOS:** concede permisos de *Grabación de pantalla* y *Accesibilidad* a tu terminal o editor.
170
+ - **Linux:** funciona en X11 (Wayland suele bloquear captura y control). Puede hacer falta `sudo apt install python3-tk python3-dev scrot xclip`.
171
+
172
+ ---
173
+
174
+ ## 🧩 Arquitectura
175
+
176
+ ```
177
+ astrax-mcp/
178
+ ├── pyproject.toml # entry points: astrax-mcp, astrax-install
179
+ ├── install.py # atajo para quien clona el repo
180
+ ├── mcp_settings.json # ejemplo (Roo Code / Cline)
181
+ ├── tests/
182
+ └── src/astrax_mcp/
183
+ ├── server.py # construye el servidor y registra los módulos
184
+ ├── config.py # constantes, rutas y variables ASTRAX_*
185
+ ├── state.py # motor del archivo de estado de tareas (sin dependencias de MCP)
186
+ ├── tasks.py # herramientas MCP del gestor de tareas
187
+ ├── permissions.py # verificación de permisos de sesión
188
+ ├── vision.py # captura y visión de pantalla
189
+ ├── control.py # ratón, teclado, scroll, esperas
190
+ ├── system.py # terminal y portapapeles
191
+ ├── gui.py # acceso perezoso a pyautogui + validaciones
192
+ ├── utils.py # log a stderr, errores uniformes, truncado
193
+ ├── compat.py # SDK MCP v1 (FastMCP) / v2 (MCPServer)
194
+ └── installer.py # wizard de instalación multiplataforma
195
+ ```
196
+
197
+ - Basado en el SDK oficial de MCP para Python. `compat.py` usa `MCPServer` (v2) y recurre a `FastMCP` (v1.x); `pyproject.toml` fija `mcp<2` como en la configuración original: quita el tope cuando pruebes el SDK v2.
198
+ - Transporte `stdio`; todos los logs van a `stderr` para no corromper el flujo JSON-RPC.
199
+ - Las capturas se normalizan al tamaño lógico de pantalla: las coordenadas de la imagen coinciden con las del clic, incluso en HiDPI/Retina. La calidad JPEG se ajusta con `ASTRAX_JPEG_QUALITY` (30-95, por defecto 65).
200
+ - Tests: `pip install -e ".[dev]" && pytest`
201
+
202
+ ---
203
+
204
+ ## 🤝 Contribuciones / Community
205
+
206
+ Astrax es **Open Source** y crece con la comunidad. Si quieres sumarte, eres bienvenido: puedes abrir *issues*, enviar *pull requests*, proponer ideas, probar Astrax en otros sistemas o clientes MCP y reportar errores.
207
+
208
+ - 📧 **Correo de contacto:** [avpn497@gmail.com](mailto:avpn497@gmail.com)
209
+ - 📢 **Canal oficial de Telegram:** [https://t.me/AstraxMCP](https://t.me/AstraxMCP) — únete al canal para aportar, hacer preguntas o reportar problemas.
210
+ - 📺 **YouTube:** [@AstraxOf](https://youtube.com/@AstraxOf) — tutoriales y novedades
211
+ - 💬 **Creador en Telegram:** [@RufusOficial](https://t.me/RufusOficial)
212
+
213
+ Si te sirvió el proyecto, deja una ⭐ en el repositorio y suscríbete al canal.
214
+
215
+ ---
216
+
217
+ <p align="center">Hecho con 💙 por <b>Rufus</b> · <a href="https://youtube.com/@AstraxOf">@AstraxOf</a></p>
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env python3
2
+ """Instalador para quien clonó el repo: python install.py (equivale a `astrax-install`)."""
3
+
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ sys.path.insert(0, str(Path(__file__).resolve().parent / "src"))
8
+
9
+ from astrax_mcp.installer import main # noqa: E402
10
+
11
+ if __name__ == "__main__":
12
+ sys.exit(main())
@@ -0,0 +1,50 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "astrax-mcp"
7
+ dynamic = ["version"]
8
+ description = "Agentic System Telemetry, Realtime Automation & X-control: servidor MCP que da ojos y manos a tu IA"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ keywords = ["mcp", "model-context-protocol", "ai-agents", "automation", "pyautogui", "computer-use"]
12
+ classifiers = [
13
+ "Programming Language :: Python :: 3",
14
+ "Operating System :: Microsoft :: Windows",
15
+ "Operating System :: MacOS",
16
+ "Operating System :: POSIX :: Linux",
17
+ ]
18
+ dependencies = [
19
+ # <2: misma restricción que usaba mcp_settings.json. El código ya es compatible con
20
+ # el SDK v2 (MCPServer); quita el tope cuando lo hayas probado.
21
+ "mcp[cli]>=1.2.0,<2",
22
+ "pyautogui>=0.9.54",
23
+ "Pillow>=10.0.0",
24
+ "pyperclip>=1.8.2",
25
+ ]
26
+
27
+ [project.optional-dependencies]
28
+ dev = ["pytest>=8"]
29
+
30
+ [project.urls]
31
+ Homepage = "https://github.com/AstraxOf/astrax-mcp"
32
+ Telegram = "https://t.me/AstraxMCP"
33
+ YouTube = "https://youtube.com/@AstraxOf"
34
+
35
+ [project.scripts]
36
+ astrax-mcp = "astrax_mcp:main"
37
+ astrax-install = "astrax_mcp.installer:main"
38
+
39
+ [tool.hatch.version]
40
+ path = "src/astrax_mcp/__init__.py"
41
+
42
+ [tool.hatch.build.targets.wheel]
43
+ packages = ["src/astrax_mcp"]
44
+
45
+ [tool.hatch.build.targets.sdist]
46
+ include = ["src", "tests", "install.py", "README.md", "pyproject.toml", "requirements.txt"]
47
+
48
+ [tool.pytest.ini_options]
49
+ testpaths = ["tests"]
50
+ pythonpath = ["src"]
@@ -0,0 +1,14 @@
1
+ # Astrax - Agentic System Telemetry, Realtime Automation & X-control
2
+ # Recomendado: usa `uvx` (ver README). Alternativa: pip install -r requirements.txt
3
+
4
+ # Servidor MCP (incluye FastMCP y la CLI `mcp dev`)
5
+ mcp[cli]>=1.2.0,<2
6
+
7
+ # Control de ratón/teclado y capturas de pantalla
8
+ pyautogui>=0.9.54
9
+
10
+ # Procesamiento de imágenes (captura y reescalado)
11
+ Pillow>=10.0.0
12
+
13
+ # Portapapeles: escribir caracteres no ASCII (ñ, tildes, emojis) y herramienta de portapapeles
14
+ pyperclip>=1.8.2
@@ -0,0 +1,10 @@
1
+ """Astrax - Agentic System Telemetry, Realtime Automation & X-control."""
2
+
3
+ __version__ = "0.2.0"
4
+
5
+
6
+ def main() -> None:
7
+ """Punto de entrada del servidor MCP (comando `astrax-mcp`)."""
8
+ from .server import run
9
+
10
+ run()
@@ -0,0 +1,4 @@
1
+ from . import main
2
+
3
+ if __name__ == "__main__":
4
+ main()
@@ -0,0 +1,10 @@
1
+ """Compatibilidad con el SDK de MCP v1.x (FastMCP) y v2.x (MCPServer)."""
2
+
3
+ try: # SDK v2
4
+ from mcp.server.mcpserver import MCPServer
5
+ from mcp.server.mcpserver.utilities.types import Image as MCPImage
6
+ except ImportError: # SDK v1.x
7
+ from mcp.server.fastmcp import FastMCP as MCPServer # type: ignore[assignment]
8
+ from mcp.server.fastmcp.utilities.types import Image as MCPImage # type: ignore[assignment]
9
+
10
+ __all__ = ["MCPServer", "MCPImage"]
@@ -0,0 +1,78 @@
1
+ """Constantes y configuración (sobrescribible con variables de entorno ASTRAX_*)."""
2
+
3
+ import os
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ SERVER_NAME = "Astrax"
8
+
9
+
10
+ def _env_int(nombre: str, defecto: int) -> int:
11
+ try:
12
+ return int(os.environ.get(nombre, defecto))
13
+ except ValueError:
14
+ return defecto
15
+
16
+
17
+ def _directorio_astrax() -> Path:
18
+ """Directorio privado por usuario (no /tmp compartido): guarda estado y capturas."""
19
+ override = os.environ.get("ASTRAX_HOME")
20
+ if override:
21
+ return Path(override).expanduser()
22
+ if sys.platform == "win32":
23
+ base = Path(os.environ.get("LOCALAPPDATA") or Path.home() / "AppData" / "Local")
24
+ elif sys.platform == "darwin":
25
+ base = Path.home() / "Library" / "Caches"
26
+ else:
27
+ base = Path(os.environ.get("XDG_CACHE_HOME") or Path.home() / ".cache")
28
+ return base / "astrax"
29
+
30
+
31
+ HOME_DIR = _directorio_astrax()
32
+ STATE_FILE = HOME_DIR / ".astrax_task_state.json"
33
+ SCREENSHOT_DIR = HOME_DIR / "screens"
34
+
35
+ # --- Permisos de sesión (ámbitos) ---
36
+ SCOPE_PANTALLA = "pantalla" # ver / capturar la pantalla
37
+ SCOPE_INPUT = "raton_teclado" # clics, teclas, atajos, scroll
38
+ SCOPE_PORTAPAPELES = "portapapeles" # leer / escribir el portapapeles
39
+ SCOPE_TERMINAL = "terminal" # ejecutar comandos de shell
40
+ SCOPES = (SCOPE_PANTALLA, SCOPE_INPUT, SCOPE_PORTAPAPELES, SCOPE_TERMINAL)
41
+
42
+ # Si es "0", las herramientas de acción no exigen tarea autorizada (modo legado).
43
+ REQUIRE_SESSION = os.environ.get("ASTRAX_REQUIRE_SESSION", "1") != "0"
44
+ SESSION_MINUTES = _env_int("ASTRAX_SESSION_MINUTES", 60)
45
+
46
+ # --- Límites (ahorro de tokens y anti-bucles) ---
47
+ MAX_PASOS = 30
48
+ MAX_INTENTOS = 3
49
+ MAX_DATOS = 100
50
+ MAX_DATO_CHARS = 4000
51
+ MAX_SALIDA = 4000
52
+ MAX_ESPERA_SEG = 15.0
53
+ JPEG_QUALITY = max(30, min(_env_int("ASTRAX_JPEG_QUALITY", 65), 95))
54
+
55
+ # --- Nombres de herramientas (el instalador los usa para `alwaysAllow`) ---
56
+ TOOL_AUTORIZAR = "astrax_tarea_autorizar"
57
+ TODAS_LAS_HERRAMIENTAS = (
58
+ "astrax_tarea_crear",
59
+ TOOL_AUTORIZAR,
60
+ "astrax_tarea_estado",
61
+ "astrax_tarea_guardar",
62
+ "astrax_tarea_completar_paso",
63
+ "astrax_tarea_limpiar",
64
+ "astrax_info_pantalla",
65
+ "astrax_ver_pantalla",
66
+ "astrax_capturar_pantalla",
67
+ "astrax_clic",
68
+ "astrax_doble_clic",
69
+ "astrax_escribir",
70
+ "astrax_tecla",
71
+ "astrax_atajo",
72
+ "astrax_scroll",
73
+ "astrax_esperar",
74
+ "astrax_portapapeles",
75
+ "astrax_ejecutar_comando",
76
+ )
77
+ # Todo menos la autorización: así el cliente pregunta UNA vez, justo ahí.
78
+ AUTO_APROBABLES = tuple(t for t in TODAS_LAS_HERRAMIENTAS if t != TOOL_AUTORIZAR)