# Servidor MCP: conecta Claude, ChatGPT y agentes de IA a MetaTrader 5

URL: https://docs.fxapis.com/es/guides/mcp

> Conecta Claude (claude.ai, Desktop, Code), ChatGPT y otros agentes de IA a tus cuentas de MetaTrader 5 con el servidor MCP de fxapis: inicia sesión, elige…



fxapis ejecuta un servidor alojado de [Model Context Protocol](https://modelcontextprotocol.io) (MCP). Agrégalo a una app de IA, inicia sesión en fxapis, y el asistente puede leer tus cuentas de MetaTrader 5, tus posiciones, tus órdenes y tu historial. Si lo permites, también puede operar.

```
https://api.fxapis.com/mcp
```

No hay nada que instalar. Las terminales de MT5 corren en nuestra nube de la UE, como en cada llamada a fxapis. Funciona con cualquier broker de MT5.

Todos los planes incluyen el conector: Personal ($9 al mes o $90 al año), Production ($99 al mes), Business ($749 al mes) y Enterprise. También la prueba gratuita de 14 días del plan que elijas, en hasta 5 cuentas demo, sin tarjeta. No hay plan gratuito.

<Callout type="warn" title="Una app a la que permites operar opera dinero real">
  Conecta primero en solo lectura, y prueba el trading en una **cuenta demo de un broker**. El trading está apagado a menos que lo actives al iniciar sesión. Se aplica solo a las cuentas que elijas, y requiere la verificación en dos pasos. Claude igual te pregunta antes de cada operación. Lee el [Modelo de seguridad](#safety-model) antes de permitir una cuenta real.
</Callout>

## Cómo funciona [#how-it-works]

* **Inicias sesión; no hay clave que copiar.** La primera vez que la app usa fxapis, abre la página de inicio de sesión de fxapis. Tú eliges qué puede hacer:
  * **Acceso de lectura:** cuentas, posiciones, órdenes, deals, cifras y cotizaciones. Siempre está incluido.
  * **Trading:** apagado por defecto. Actívalo por cuenta: todo lo que la app cambia —abrir, cerrar, stops, cancelar, poner en línea, desconectar— se limita a las cuentas que elijas. Requiere tener activada la verificación en dos pasos; tu sesión ya la demostró al iniciar sesión, así que aquí no hay código que escribir. También puedes definir un tamaño máximo de orden y un número de órdenes por día.
* **Revoca cuando quieras.** Cada app que conectas aparece en la [página de API keys](https://fxapis.com/dashboard/keys), en **Connected apps**, con la última vez que se usó. **Revoke** termina su acceso en su siguiente solicitud. Quitar a alguien del workspace, o cambiar su rol, revoca las apps que conectó.
* **Las mismas reglas que la API REST.** Una app conectada actúa a través de los endpoints normales de `/v1` con exactamente lo que elegiste. Se aplican el aislamiento del workspace, los límites de frecuencia, los límites del plan, la idempotencia y nuestro interruptor de emergencia de trading. Cada llamada a una herramienta cuenta como una o dos llamadas a la API en tu plan.
* **Las API keys siguen funcionando** para scripts y agentes sin supervisión: envía `Authorization: Bearer fx_live_…` o `X-API-Key`. Consulta [Agentes con una API key](#agents-with-an-api-key).
* **Lo que falta a propósito:** conectar una cuenta de MT5 y gestionar claves. Conectar requiere la contraseña del broker, que nunca debe pasar por un modelo de IA. Haz ambas cosas en la [consola](https://fxapis.com/dashboard).

Por dentro:

* el servidor habla Streamable HTTP, sin estado, en las revisiones del protocolo 2026-07-28 y 2025;
* el inicio de sesión es OAuth 2.1 con PKCE, como pide la especificación de autorización de MCP, y se descubre desde `https://api.fxapis.com/.well-known/oauth-protected-resource/mcp`;
* `initialize` y `tools/list` responden sin iniciar sesión. Una llamada a una herramienta sin credencial recibe `401` con un desafío `WWW-Authenticate` que dirige a la app al inicio de sesión.

## Conecta tu app [#connect-your-app]

### Claude (claude.ai y Claude Desktop) [#claude-claudeai-and-claude-desktop]

En cualquier plan de Claude:

1. Abre **Customize → Connectors → Add custom connector**. En Team y Enterprise, un Owner lo agrega en **Organization settings → Connectors**.
2. **Remote MCP server URL:** `https://api.fxapis.com/mcp`. Deja vacíos los campos del cliente OAuth: Claude se registra solo.
3. Haz clic en **Connect** e inicia sesión en fxapis en la ventana que se abre. Elige solo lectura o trading, y permítelo.

Los conectores que agregas en claude.ai también están en la app de escritorio de Claude.

### Claude Code [#claude-code]

```bash
claude mcp add --transport http fxapis https://api.fxapis.com/mcp
```

Luego ejecuta `/mcp`, elige **fxapis** y **Authenticate**: tu navegador abre el inicio de sesión de fxapis.

O instala el [plugin de fxapis](/es/guides/claude-plugin). Agrega el servidor, una skill de trading seguro y un hook que confirma cada operación:

```
/plugin marketplace add FXapis/fxapis-claude-plugins
/plugin install fxapis@fxapis
```

### ChatGPT [#chatgpt]

Agrégalo en ChatGPT **en la web**:

1. Abre **Plugins**, elige **+** y luego **Add custom MCP server**.
2. **URL:** `https://api.fxapis.com/mcp`, o `https://api.fxapis.com/mcp/insights` para el [conector de solo lectura](/es/guides/mcp-read-only).
3. **Authentication:** OAuth. Inicia sesión en fxapis cuando ChatGPT lo pida.

Lo que ChatGPT permite depende de tu plan de ChatGPT. La página de ayuda de OpenAI, [Connecting custom MCP servers in ChatGPT](https://help.openai.com/en/articles/12584461) (revisada el 26 de octubre de 2026), indica MCP completo, incluidas las acciones que cambian cosas, para **Business, Enterprise y Edu**, y solo lectura y consulta para **Pro**. En Business, solo los owners y admins del workspace pueden agregar uno. Configura la app para que pregunte antes de actuar.

### Cursor, VS Code y otros clientes [#cursor-vs-code-and-other-clients]

Cualquier cliente compatible con el inicio de sesión OAuth de MCP se conecta solo con la URL. fxapis acepta direcciones de retorno del inicio de sesión para Claude, ChatGPT y apps en tu propia computadora (`http://localhost` y `http://127.0.0.1`). Los clientes que vuelven a un esquema personalizado, como `cursor://` o `vscode://`, todavía no se aceptan: usa una [API key](#agents-with-an-api-key) con ellos.

Para probar desde una terminal con el [MCP Inspector](https://github.com/modelcontextprotocol/inspector):

```bash
npx @modelcontextprotocol/inspector https://api.fxapis.com/mcp
```

## Agentes con una API key [#agents-with-an-api-key]

Para un agente que corre sin supervisión, [crea una clave](https://fxapis.com/dashboard/keys) solo para él, con los mínimos alcances que hagan el trabajo:

| El agente debe…                                                    | Alcances                                        |
| ------------------------------------------------------------------ | ----------------------------------------------- |
| Informar sobre cuentas, posiciones e historial                     | `accounts:read`, `trading:read`, `history:read` |
| …y poner cuentas en línea o desconectarlas                         | agrega `accounts:write`                         |
| …y gestionar el riesgo: cerrar, mover stops, cancelar; nunca abrir | agrega `trading:reduce`                         |
| …y abrir posiciones nuevas                                         | agrega `trading:execute`                        |

Envíala como `Authorization: Bearer fx_live_…`, o como `X-API-Key: fx_live_…` para los clientes que solo ofrecen ese encabezado.

**Claude Code, con una clave:**

```bash
claude mcp add --transport http fxapis https://api.fxapis.com/mcp --header "Authorization: Bearer $FXAPIS_KEY"
```

**Cursor** (`~/.cursor/mcp.json`):

```json
{ "mcpServers": { "fxapis": { "url": "https://api.fxapis.com/mcp", "headers": { "Authorization": "Bearer ${env:FXAPIS_KEY}" } } } }
```

**VS Code** (`.vscode/mcp.json`):

```json
{
  "inputs": [{ "type": "promptString", "id": "fxapis-key", "description": "fxapis API key", "password": true }],
  "servers": { "fxapis": { "type": "http", "url": "https://api.fxapis.com/mcp", "headers": { "Authorization": "Bearer ${input:fxapis-key}" } } }
}
```

**API de OpenAI (Responses).** Pon esto en los `tools` de la solicitud:

```json
{ "type": "mcp", "server_label": "fxapis", "server_url": "https://api.fxapis.com/mcp", "authorization": "fx_live_…", "require_approval": "always" }
```

**API de Anthropic (Messages).** Usa `mcp_servers: [{ "type": "url", "url": "https://api.fxapis.com/mcp", "name": "fxapis", "authorization_token": "fx_live_…" }]`, con una herramienta `mcp_toolset` para `fxapis`, como describe la documentación del conector MCP de Anthropic.

Todas las configuraciones también están en [fxapis-mcp-examples](https://github.com/FXapis/fxapis-mcp-examples).

## Revocar el acceso [#revoking-access]

* **Una app conectada:** en la [página de API keys](https://fxapis.com/dashboard/keys), en **Connected apps**, elige **Revoke**.
  * Su acceso termina en su siguiente solicitud, su inicio de sesión ya no se puede renovar y se cancela cualquier inicio de sesión todavía en curso.
  * Los owners y admins ven y revocan las apps conectadas de todos. Los members ven las suyas.
* **Una clave:** revócala en la misma página. Se rechaza desde su siguiente solicitud.

## Herramientas [#tools]

Los argumentos están en `snake_case`. Los ids de cuenta son los UUID de fxapis que da `list_accounts`, no los logins de MT5. Los volúmenes y los precios son strings (`"0.10"`, `"1.08450"`).

Los resultados son pequeños por diseño:

* una línea para el modelo, más los datos una sola vez como JSON compacto;
* `response_format: "detailed"` agrega cada campo que tiene la API;
* las listas responden `{ items, next_cursor, total }` de 25 en 25; devuelve `next_cursor` como `cursor`.

### Responder una pregunta en una llamada [#answer-a-question-in-one-call]

| Herramienta            | Qué hace                                                                                                          | Alcance                         |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------- |
| `get_account_overview` | El estado de una cuenta, su entorno, balance, equity y sus posiciones más grandes con la ganancia o pérdida total | `accounts:read`, `trading:read` |
| `get_symbol_snapshot`  | La especificación de un símbolo, su cotización en vivo, si el mercado está abierto y el margen para un volumen    | `accounts:read`, `trading:read` |

### Solo lectura [#read-only]

| Herramienta                 | Qué hace                                                                                                                                              | Alcance         |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| `get_workspace`             | El plan, sus límites y funciones, y si el trading está apagado                                                                                        | `accounts:read` |
| `get_usage`                 | El uso de este mes frente al plan                                                                                                                     | `accounts:read` |
| `list_accounts`             | Cuentas con id, login, servidor, estado y entorno (demo o real)                                                                                       | `accounts:read` |
| `get_account`               | Una cuenta y su último balance y equity leídos                                                                                                        | `accounts:read` |
| `get_account_status`        | Solo el estado: consúltalo después de `bring_accounts_online`                                                                                         | `accounts:read` |
| `get_account_figures`       | Balance, equity, margen y nivel de margen; `fresh: true` consulta a la terminal                                                                       | `accounts:read` |
| `list_positions`            | Las posiciones abiertas tal como se vieron por última vez                                                                                             | `trading:read`  |
| `list_instruments`          | Mercados nombrados una sola vez (`XAUUSD`, `US30`…)                                                                                                   | cualquiera      |
| `search_broker_servers`     | El servidor de MT5 exacto de un broker                                                                                                                | `accounts:read` |
| `list_account_instruments`  | El símbolo de cada instrumento en el broker de una cuenta; `query` lo acota                                                                           | `accounts:read` |
| `get_market_hours`          | Si un mercado está abierto ahora, y cuándo abre o cierra                                                                                              | `accounts:read` |
| `get_quotes`                | Bid y ask en vivo para hasta 20 símbolos                                                                                                              | `trading:read`  |
| `get_price_history`         | Velas recientes (de M1 a MN1, hasta 500 barras) para análisis técnico, en columnas compactas. Disponible después del próximo mantenimiento programado | `trading:read`  |
| `list_orders`               | Órdenes, de la más reciente a la más antigua, por cuenta, estado, símbolo y fecha                                                                     | `trading:read`  |
| `get_order`                 | Una orden y la respuesta del broker; opcionalmente sus deals                                                                                          | `trading:read`  |
| `list_deals`                | El historial de deals del broker para una cuenta                                                                                                      | `history:read`  |
| `list_multi_account_orders` | Órdenes multicuenta recientes                                                                                                                         | `trading:read`  |
| `get_multi_account_order`   | Una orden multicuenta, cuenta por cuenta                                                                                                              | `trading:read`  |
| `calculate`                 | Margen o ganancia, como lo calcula el broker; no abre nada                                                                                            | `trading:read`  |

### Ciclo de vida de la cuenta [#account-lifecycle]

| Herramienta             | Qué hace                                                               | Alcance          |
| ----------------------- | ---------------------------------------------------------------------- | ---------------- |
| `bring_accounts_online` | Arranca las cuentas e inicia sesión; consulta `get_account_status`     | `accounts:write` |
| `take_account_offline`  | Detiene la terminal; las posiciones y los stops se quedan en el broker | `accounts:write` |

### Trading [#trading]

Están marcadas como `destructiveHint: true`, así que Claude y otros clientes cuidadosos preguntan antes de cada una. Cada una **requiere un `idempotency_key`**: un UUID nuevo por acción, y el mismo solo para reintentar esa acción. Con él, una orden reintentada nunca es una segunda orden, y un cierre reintentado nunca es una posición opuesta.

| Herramienta                  | Qué hace                                    | Alcance           |
| ---------------------------- | ------------------------------------------- | ----------------- |
| `place_market_order`         | Abre una posición a mercado                 | `trading:execute` |
| `place_pending_order`        | Una orden limit, stop o stop-limit          | `trading:execute` |
| `close_position`             | Cierra una posición completa o en parte     | `trading:reduce`  |
| `modify_position`            | Mueve o quita un stop loss o un take profit | `trading:reduce`  |
| `cancel_order`               | Cancela una orden pendiente                 | `trading:reduce`  |
| `place_multi_account_order`  | La misma operación en muchas cuentas        | `trading:execute` |
| `cancel_multi_account_order` | La cancela antes de que se envíe nada       | `trading:reduce`  |

Una app conectada a la que no se le permitió operar y que llama a una herramienta de trading recibe `403` con `WWW-Authenticate: Bearer error="insufficient_scope", scope="… trading:execute"`. La app entonces te pide volver a iniciar sesión, y la página de inicio de sesión se abre con **Trading** seleccionado.

## Errores [#errors]

Un fallo vuelve como un error de herramienta de MCP (`isError: true`) cuyo texto empieza con el
[código de error](/es/errors) propio de la API, seguido del mensaje, cualquier `details`, qué hacer a
continuación y el id de la solicitud (en inglés):

```
ORDER_UNRESOLVED (HTTP 503): Something went wrong and we do not know yet whether the order was sent. We are confirming it with the broker. Do not resend it.
details: [{"orderId":"5b0e7c1a-2f4d-4a8e-9c3b-1d6f0e2a7b94","state":"unknown","retryable":false}]
Next step: Do NOT resend this order. Its outcome is unknown and it may be live at the broker. Poll get_order with the orderId in details until it leaves `unknown`, and tell the user.
requestId: 3f8a1c92-7b4e-4d81-a2f6-0c5e9b3d7a14
```

El mismo código, estado, mensaje, id de solicitud y siguiente paso están en el `_meta` del resultado,
en `com.fxapis/error`, para los programas.

Los códigos que más le importan a un agente:

| Código                             | Qué significa para el agente                                                                                                                            |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ORDER_UNRESOLVED`                 | El resultado es desconocido y la orden puede estar activa. **Nunca reenviar**; consultar `get_order`                                                    |
| `SEND_FAILED`                      | Nada llegó al broker. Reintentar con el **mismo** `idempotency_key`                                                                                     |
| `ORDER_REJECTED`                   | El broker la rechazó; no se abrió nada. Decirle al usuario el motivo                                                                                    |
| `NO_PRICE`                         | El broker no tiene precio para el símbolo ahora (mercado cerrado, o no se ofrece). No se envió nada. No reintentar ahora; revisar su horario de trading |
| `MISSING_SCOPE`                    | Esta conexión no lo permite. Preguntar al usuario; no buscar otra forma                                                                                 |
| `KEY_LIMIT_EXCEEDED`               | Un límite elegido para esta conexión o clave lo rechaza; details dice cuál                                                                              |
| `ACCOUNT_NOT_READY` / `NO_RUNTIME` | Poner la cuenta en línea, esperar `ready` y luego reintentar                                                                                            |
| `RATE_LIMITED`                     | Esperar `retryAfterSeconds` y luego reintentar una vez                                                                                                  |
| `TRADING_DISABLED`                 | El trading está apagado para la cuenta o el workspace. No reintentar                                                                                    |

Cada código y su siguiente paso: [códigos de error en la skill](https://github.com/FXapis/fxapis-claude-plugins/blob/main/plugins/fxapis/skills/trading-mt5-safely/error-codes.md) (en inglés).

## Modelo de seguridad [#safety-model]

Un agente es un nuevo tipo de llamador. Puede malinterpretar una petición, actuar según un texto plantado en una página web o entrar en un bucle. Las protecciones, de la más fuerte a la más débil:

1. **Lo que permitiste.** Lo aplica la API en cada llamada, decida lo que decida el modelo:

   * lo que eligió una app conectada en la página de inicio de sesión: solo lectura, o trading en las cuentas que elegiste, dentro de los límites de tamaño y diarios que definiste;
   * los alcances y los [límites](/es/authentication#limits) de una clave.

   Una conexión de solo lectura no puede operar. Una conexión con trading no puede cambiar nada en una cuenta que no elegiste: no puede abrir, cerrar, mover stops ni cancelar órdenes ahí, ni poner esa cuenta en línea o desconectarla. Igual puede leer todas las cuentas del workspace.
2. **Verificación en dos pasos para operar.** Permitir que una app opere requiere tener activada la verificación en dos pasos; iniciar sesión con ella ya la demostró, así que no se pide nada más al dar el consentimiento.
3. **Cuentas demo.** fxapis no tiene un mercado simulado. Las cuentas demo de los brokers son la forma de probar.
4. **Los límites de tu plan y los límites de frecuencia.** Cerrar nunca se rechaza por facturación.
5. **Las confirmaciones de tu app.** Las herramientas de trading están marcadas como destructivas, así que Claude pregunta antes de cada operación. El [plugin de Claude Code](/es/guides/claude-plugin) lo convierte en una regla, y rechaza las cuentas reales hasta que lo permitas.
6. **Las descripciones de las herramientas y la [skill](/es/guides/claude-plugin#the-skill).** Le dicen al modelo que confirme cada operación y que nunca reenvíe una orden sin resolver. Eso orienta el comportamiento; no impone nada. Los puntos 1 y 2 sí.

Cada orden que envía un agente queda registrada como cualquier otra, con la clave o la app conectada que la envió. Las llamadas a herramientas se registran con el nombre de la herramienta, el workspace y el resultado, nunca con los argumentos.

## Directorios [#directories]

Los directorios de apps de Claude y de ChatGPT no listan herramientas que ejecutan transacciones financieras. Por eso:

* el servidor completo de arriba se agrega por URL, o a través del [plugin de Claude Code](/es/guides/claude-plugin);
* el [conector de solo lectura](/es/guides/mcp-read-only), que nunca opera, es el que estamos enviando a los directorios. Todavía no aparece ahí: mientras tanto, agrégalo por URL.

## Ejemplos de prompts [#example-prompts]

* "¿Cuáles de mis cuentas de MT5 están en línea, y qué posiciones hay abiertas en cada una?"
* "¿Cuál fue mi ganancia realizada en EURUSD esta semana en mi cuenta demo?"
* "¿Cuánto margen necesitarían 0.5 lotes de XAUUSD en la cuenta 2?"
* "Pon en línea todas mis cuentas y avísame cuando estén listas."
* "Mueve el stop loss de mi posición de oro a break-even." *(necesita `trading:reduce`)*
* "Cierra la mitad de cada posición abierta de EURUSD en la cuenta demo." *(necesita `trading:reduce`)*
* "Compra 0.01 lotes de EURUSD en la cuenta demo con un stop de 20 pips." *(necesita `trading:execute`)*
* "¿Algo salió mal con las órdenes de hoy? Muéstrame las que sigan en `unknown`."

## Límites actuales del servidor MCP [#limits-of-the-mcp-server-today]

* **Sin streaming ni notificaciones.** Las herramientas responden una vez. Sigue a una cuenta que se pone en línea, o a una orden multicuenta que se liquida, consultando repetidamente, como con la API REST. Para tu propio servidor, usa [webhooks](/guides/webhooks).
* **Los retornos del inicio de sesión a esquemas personalizados** (`cursor://`, `vscode://`) todavía no se aceptan. Usa una API key con esos clientes.
* **Solo MetaTrader 5.** MT4 no es compatible.
