Skip to main content
Glama

Orca — Servidor MCP de accesibilidad ATK

Captura el árbol de widgets ATK (Accessibility Toolkit) de aplicaciones GTK en ejecución en Linux, lo normaliza a roles/tipos ARIA, aplica una política de seguridad declarativa configurable y expone el resultado como herramientas MCP a cualquier cliente MCP estándar (Claude, Cursor, Windsurf, etc.).

Inicio rápido

cd orca
just shell        # enter nix-shell with all dependencies
just server       # start the MCP server on stdio

O manualmente:

nix-shell
PYTHONPATH=src python3 -m src

Related MCP server: claude-workman

Arquitectura

orca/
├── shell.nix                 # nix-shell environment
├── pyproject.toml            # package config
├── Justfile                  # task runner
├── docs/
│   ├── README.md             # this file
│   ├── usage.md              # client integration guide
│   ├── policy.md             # policy engine reference
│   ├── atk.md                # ATK capture internals
│   └── contribute.md         # development guide
└── src/
    ├── __init__.py
    ├── __main__.py           # entry point
    ├── atk.py                # ATK tree capture
    ├── normalize.py          # ATK→ARIA normalization
    ├── policy.py             # declarative security policy
    ├── server.py             # MCP server
    └── default_policy.yaml   # ship-default policy

Herramientas MCP

Tool

Params

Description

get_tree

none

Árbol completo normalizado a ARIA, filtrado por política

get_tree_for_app

app_name: str

Árbol limitado a una app (glóbulo fnmatch)

get_node_info

node_id: str

Consulta de un único nodo por obj_id

list_apps

none

Objetos app de nivel superior (nombre, pid, rol)

Configuración

Política

Los archivos de política se cargan con esta prioridad:

  1. ~/.config/atk-mcp/policy.yaml (anulación del usuario)

  2. src/default_policy.yaml (predeterminado incluido)

Si ninguno existe o alguno falla al analizarse, el servidor se inicia con default_action: allow y sin reglas de usuario.

La política se carga una sola vez al arrancar: reinicia el servidor para que los cambios surtan efecto.

Consulta docs/policy.md para ver el esquema completo y ejemplos.

Entorno Nix

Todas las dependencias se gestionan mediante shell.nix. No hay uv, ni virtualenv. Paquetes clave:

  • python314 — tiempo de ejecución

  • python314Packages.pyatspi — acceso al árbol ATK

  • python314Packages.pygobject3 — introspección GI

  • python314Packages.mcp — SDK MCP v2

  • python314Packages.pydantic-settings — configuración de políticas

  • python314Packages.pyyaml — análisis de políticas

  • at-spi2-core, at-spi2-atk, atk, gtk3 — librerías de tiempo de ejecución

Uso

Con Cursor

Añade a ~/.cursor/mcp.json:

{
  "mcpServers": {
    "atk-accessibility": {
      "command": "nix-shell",
      "args": ["--run", "python -m src"],
      "cwd": "/path/to/orca"
    }
  }
}

Con Claude Desktop

Añade a ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "atk-accessibility": {
      "command": "nix-shell",
      "args": ["--run", "python -m src"],
      "cwd": "/path/to/orca"
    }
  }
}

Con Windsurf

Añade a .mcp.json en tu proyecto:

{
  "mcpServers": {
    "atk-accessibility": {
      "command": "nix-shell",
      "args": ["--run", "python -m src"],
      "cwd": "/path/to/orca"
    }
  }
}

Desde la línea de comandos (prueba interactiva)

just shell
python -m src    # runs indefinitely on stdio

Pasa una solicitud MCP bruta para probar herramientas individuales:

echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
  | python -m src

Motor de políticas

Consulta docs/policy.md como referencia completa.

Ejemplo rápido: deniega todos los nodos heading y redacta los nombres de textbox:

default_action: allow
built_in_deny:
  aria_roles:
    - "password"
  state_keywords:
    - "hidden"
    - "invisible"
rules:
  - id: deny-headings
    conditions:
      role: "heading"
    action: deny
  - id: redact-forms
    conditions:
      role: "textbox"
    action: redact
    redact_fields:
      - "name"
      - "description"

Captura ATK

Consulta docs/atk.md para conocer los detalles internos. Puntos clave:

  • Recorre recursivamente la raíz de escritorio gi.repository.Atspi

  • Fail-closed: el aislamiento de subprocesos evita que una anulación de GLib bloquee el servidor cuando no hay bus AT-SPIA disponible

  • Cada nodo captura: obj_id, role (int), role_name, name, description, state_set, attributes, child_count, index_in_parent, app_name, pid

Normalización

Consulta docs/ify.md para el mapa de roles.

Los roles enteros ATK (0–123) se asignan a cadenas de rol ARIA. Los roles no asignados pasan como su cadena role_name. Los nombres de estado se traducen (p. ej. FOCUSED → focused, CHECKED → checked).

Desarrollo

Consulta docs/contribute.md para la guía de desarrollo.

just shell        # enter dev environment
just test         # run verification suite
just compile      # syntax check
just lint         # import + smoke check
just server       # start server for manual testing

Limitaciones

  • Aplicaciones Wayland sin AT-SPI: algunas aplicaciones GTK nativas de Wayland no exponen interfaces AT-SPI. get_tree_for_app devuelve [] para esas aplicaciones. Esperado, no es un bug.

  • Sin recarga en caliente: la política se carga una sola vez al arrancar.

  • Requiere bus AT-SPI: sin un bus de accesibilidad en ejecución (p. ej. at-spi-bus-launcher), el módulo ATK devuelve [] de forma controlada.

  • Python 3.14+: no hay de dependencia typing-extensions.

Licencia

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables MCP clients to control a Linux/X11 desktop like a human: see the screen, move the mouse, click UI elements via the accessibility tree, type text, and manage windows.
    MIT
  • -
    license
    Not graded
    quality
    C
    maintenance
    Standalone MCP server for desktop GUI automation on macOS and Windows, exposing a unified tool for accessibility-tree snapshots, input, app control, and browser CDP fast path, driven by any MCP host.
    -