@servicialo/mcp-server 0.7.0 → 0.9.0
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.
- package/README.en.md +392 -0
- package/README.md +336 -147
- package/dist/adapter-http.d.ts +51 -0
- package/dist/adapter-http.d.ts.map +1 -0
- package/dist/adapter-http.js +187 -0
- package/dist/adapter-http.js.map +1 -0
- package/dist/adapter.d.ts +42 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +42 -0
- package/dist/adapter.js.map +1 -0
- package/dist/client.d.ts +5 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -0
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +63 -59
- package/dist/index.js.map +1 -1
- package/dist/mandate.d.ts +321 -0
- package/dist/mandate.d.ts.map +1 -0
- package/dist/mandate.js +349 -0
- package/dist/mandate.js.map +1 -0
- package/dist/provider-profile.d.ts +985 -0
- package/dist/provider-profile.d.ts.map +1 -0
- package/dist/provider-profile.js +210 -0
- package/dist/provider-profile.js.map +1 -0
- package/dist/tools/authenticated/cerrar.d.ts +5 -5
- package/dist/tools/authenticated/cerrar.d.ts.map +1 -1
- package/dist/tools/authenticated/cerrar.js.map +1 -1
- package/dist/tools/authenticated/comprometer.d.ts +4 -4
- package/dist/tools/authenticated/comprometer.d.ts.map +1 -1
- package/dist/tools/authenticated/comprometer.js.map +1 -1
- package/dist/tools/authenticated/delivery.d.ts +4 -4
- package/dist/tools/authenticated/delivery.d.ts.map +1 -1
- package/dist/tools/authenticated/delivery.js.map +1 -1
- package/dist/tools/authenticated/entender.d.ts +3 -3
- package/dist/tools/authenticated/entender.d.ts.map +1 -1
- package/dist/tools/authenticated/entender.js.map +1 -1
- package/dist/tools/authenticated/lifecycle.d.ts +5 -5
- package/dist/tools/authenticated/lifecycle.d.ts.map +1 -1
- package/dist/tools/authenticated/lifecycle.js.map +1 -1
- package/dist/tools/authenticated/resolve-auth.d.ts +118 -0
- package/dist/tools/authenticated/resolve-auth.d.ts.map +1 -0
- package/dist/tools/authenticated/resolve-auth.js +62 -0
- package/dist/tools/authenticated/resolve-auth.js.map +1 -0
- package/dist/tools/authenticated/resource.d.ts +295 -0
- package/dist/tools/authenticated/resource.d.ts.map +1 -0
- package/dist/tools/authenticated/resource.js +125 -0
- package/dist/tools/authenticated/resource.js.map +1 -0
- package/dist/tools/public/a2a.d.ts +18 -0
- package/dist/tools/public/a2a.d.ts.map +1 -0
- package/dist/tools/public/a2a.js +15 -0
- package/dist/tools/public/a2a.js.map +1 -0
- package/dist/tools/public/availability.d.ts +2 -2
- package/dist/tools/public/availability.d.ts.map +1 -1
- package/dist/tools/public/availability.js.map +1 -1
- package/dist/tools/public/registry.d.ts +8 -3
- package/dist/tools/public/registry.d.ts.map +1 -1
- package/dist/tools/public/registry.js +8 -0
- package/dist/tools/public/registry.js.map +1 -1
- package/dist/tools/public/resolve.d.ts +60 -0
- package/dist/tools/public/resolve.d.ts.map +1 -0
- package/dist/tools/public/resolve.js +60 -0
- package/dist/tools/public/resolve.js.map +1 -0
- package/dist/tools/public/services.d.ts +2 -2
- package/dist/tools/public/services.d.ts.map +1 -1
- package/dist/tools/public/services.js.map +1 -1
- package/package.json +4 -2
- package/dist/__tests__/client.test.d.ts +0 -2
- package/dist/__tests__/client.test.d.ts.map +0 -1
- package/dist/__tests__/client.test.js +0 -136
- package/dist/__tests__/client.test.js.map +0 -1
- package/dist/__tests__/mode.test.d.ts +0 -2
- package/dist/__tests__/mode.test.d.ts.map +0 -1
- package/dist/__tests__/mode.test.js +0 -25
- package/dist/__tests__/mode.test.js.map +0 -1
- package/dist/__tests__/schemas.test.d.ts +0 -2
- package/dist/__tests__/schemas.test.d.ts.map +0 -1
- package/dist/__tests__/schemas.test.js +0 -53
- package/dist/__tests__/schemas.test.js.map +0 -1
- package/dist/__tests__/tools.test.d.ts +0 -2
- package/dist/__tests__/tools.test.d.ts.map +0 -1
- package/dist/__tests__/tools.test.js +0 -241
- package/dist/__tests__/tools.test.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,32 +1,156 @@
|
|
|
1
1
|
# @servicialo/mcp-server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **Entrada canónica en el registro MCP:** `com.servicialo/mcp-server`
|
|
4
|
+
> La entrada `io.github.danioni/servicialo` está deprecated desde marzo 2026.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
> **[English version](./README.en.md)**
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
**La capa de protocolo que falta para agentes de IA que coordinan servicios profesionales.**
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
No existe una forma estándar para que un agente de IA reserve, verifique y liquide un servicio profesional. Servicialo es un protocolo abierto que resuelve esto — y este MCP server es su implementación de referencia. Piensa en HTTP para coordinación de servicios: cualquier agente, cualquier plataforma, un solo protocolo.
|
|
10
11
|
|
|
11
|
-
##
|
|
12
|
+
## El Problema
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
Los agentes de IA pueden navegar la web, escribir código y mantener conversaciones. Pero pídele a uno que reserve una sesión de kinesiología, verifique que ocurrió, y procese el pago — y se desmorona.
|
|
15
|
+
|
|
16
|
+
Hoy, cada plataforma es un silo. No hay estándar para:
|
|
17
|
+
|
|
18
|
+
- **Descubrimiento** — qué prestador, en qué organización, ofrece lo que necesito?
|
|
19
|
+
- **Identidad** — en nombre de quién actúa este agente, y qué está autorizado a hacer?
|
|
20
|
+
- **Ciclo de vida** — en qué estado está este servicio? Quién confirmó? Quién asistió?
|
|
21
|
+
- **Prueba de entrega** — ocurrió realmente la sesión? Por cuánto tiempo? Dónde?
|
|
22
|
+
- **Liquidación** — cuánto, a quién, bajo qué términos contractuales?
|
|
23
|
+
|
|
24
|
+
Sin un protocolo compartido, cada integración es artesanal. Cada conexión agente-plataforma es un API custom. Esto no escala.
|
|
25
|
+
|
|
26
|
+
## Qué es Servicialo
|
|
27
|
+
|
|
28
|
+
Servicialo es un **protocolo abierto**, no una plataforma. Define cómo los servicios profesionales se mueven a través de su ciclo de vida — desde el descubrimiento hasta el pago — de una forma que cualquier agente de IA o plataforma puede implementar.
|
|
29
|
+
|
|
30
|
+
La relación es como HTTP con Apache, o SMTP con Gmail: Servicialo define las reglas, las implementaciones les dan vida.
|
|
31
|
+
|
|
32
|
+
El protocolo modela cada servicio a través de **8 dimensiones ortogonales** (identidad, prestador, cliente, agenda, ubicación, ciclo de vida, prueba de entrega, facturación) y define **8 estados de ciclo de vida** universales entre verticales — salud, legal, educación, servicios domiciliarios:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
Solicitado → Agendado → Confirmado → En Curso → Entregado → Documentado → Cobrado → Verificado
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Cualquier servicio, en cualquier vertical, sigue esta secuencia. La lógica específica del vertical vive *dentro* de cada estado, pero la máquina de estados es invariante.
|
|
39
|
+
|
|
40
|
+
## Qué Hace Este MCP Server
|
|
41
|
+
|
|
42
|
+
Este paquete expone el protocolo Servicialo como 33 herramientas MCP organizadas por **8 fases** del ciclo de vida de un servicio (incluyendo resolución DNS), más herramientas de gestión de recursos y administración del resolver. Un agente no llama endpoints por entidad de base de datos — sigue el flujo natural de coordinar un servicio.
|
|
43
|
+
|
|
44
|
+
### Fase 0 — Resolución DNS (3 herramientas públicas, sin autenticación)
|
|
45
|
+
|
|
46
|
+
| Herramienta | Descripción |
|
|
47
|
+
|---|---|
|
|
48
|
+
| `resolve.lookup` | Resolver un orgSlug a su endpoint MCP/REST y nivel de confianza (equivalente a DNS lookup) |
|
|
49
|
+
| `resolve.search` | Buscar organizaciones registradas por país y vertical en el resolver global |
|
|
50
|
+
| `trust.get_score` | Obtener puntaje de confianza de una organización (score 0-100, nivel, última actividad) |
|
|
51
|
+
|
|
52
|
+
### Fase 1 — Descubrimiento (6 herramientas públicas, sin autenticación)
|
|
53
|
+
|
|
54
|
+
| Herramienta | Descripción |
|
|
55
|
+
|---|---|
|
|
56
|
+
| `registry.search` | Buscar organizaciones por vertical, ubicación, país |
|
|
57
|
+
| `registry.get_organization` | Obtener detalles públicos: servicios, prestadores, configuración de reservas |
|
|
58
|
+
| `registry.manifest` | Obtener manifiesto del servidor: capacidades, versión del protocolo, metadata de organización |
|
|
59
|
+
| `scheduling.check_availability` | Consultar disponibilidad (3 variables: prestador ∧ cliente ∧ recurso) |
|
|
60
|
+
| `services.list` | Listar el catálogo público de servicios de una organización |
|
|
61
|
+
| `a2a.get_agent_card` | Obtener la Agent Card A2A de una organización para descubrimiento inter-agente |
|
|
62
|
+
|
|
63
|
+
### Fase 2 — Entender (2 herramientas)
|
|
64
|
+
|
|
65
|
+
| Herramienta | Descripción | Scopes |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| `service.get` | Obtener las 8 dimensiones de un servicio | `service:read` |
|
|
68
|
+
| `contract.get` | Obtener términos del contrato: evidencia requerida, política de cancelación, ventana de disputa | `service:read` `order:read` |
|
|
69
|
+
|
|
70
|
+
### Fase 3 — Comprometer (3 herramientas)
|
|
71
|
+
|
|
72
|
+
| Herramienta | Descripción | Scopes |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| `clients.get_or_create` | Resolver identidad del cliente por email/teléfono — buscar o crear en una sola llamada | `patient:write` |
|
|
75
|
+
| `scheduling.book` | Reservar sesión → estado `solicitado`. `resource_id` opcional para recursos físicos | `schedule:write` |
|
|
76
|
+
| `scheduling.confirm` | Confirmar sesión reservada → estado `confirmado` | `schedule:write` |
|
|
77
|
+
|
|
78
|
+
### Fase 4 — Ciclo de Vida (4 herramientas)
|
|
79
|
+
|
|
80
|
+
| Herramienta | Descripción | Scopes |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| `lifecycle.get_state` | Obtener estado actual, transiciones disponibles e historial | `service:read` |
|
|
83
|
+
| `lifecycle.transition` | Ejecutar transición de estado con evidencia | `service:write` |
|
|
84
|
+
| `scheduling.reschedule` | Reagendar a nueva fecha/hora (política contractual puede aplicar) | `schedule:write` |
|
|
85
|
+
| `scheduling.cancel` | Cancelar sesión (se aplica política de cancelación del contrato) | `schedule:write` |
|
|
86
|
+
|
|
87
|
+
### Fase 5 — Verificar Entrega (3 herramientas)
|
|
88
|
+
|
|
89
|
+
| Herramienta | Descripción | Scopes |
|
|
90
|
+
|---|---|---|
|
|
91
|
+
| `delivery.checkin` | Check-in con GPS + timestamp → estado `en_curso` | `evidence:write` |
|
|
92
|
+
| `delivery.checkout` | Check-out con GPS + timestamp → estado `entregado` (duración auto-calculada) | `evidence:write` |
|
|
93
|
+
| `delivery.record_evidence` | Registrar evidencia: `gps`, `firma`, `foto`, `documento`, `duración`, `notas` | `evidence:write` |
|
|
94
|
+
|
|
95
|
+
### Fase 6 — Cerrar (4 herramientas)
|
|
96
|
+
|
|
97
|
+
| Herramienta | Descripción | Scopes |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| `documentation.create` | Generar registro del servicio (nota clínica, informe de inspección, etc.) → estado `documentado` | `document:write` |
|
|
100
|
+
| `payments.create_sale` | Crear cargo por servicio documentado → estado `cobrado` | `payment:write` |
|
|
101
|
+
| `payments.record_payment` | Registrar pago recibido contra una venta | `payment:write` |
|
|
102
|
+
| `payments.get_status` | Obtener estado de pago de una venta o saldo de cuenta del cliente | `payment:read` |
|
|
103
|
+
|
|
104
|
+
### Gestión de Recursos (6 herramientas)
|
|
105
|
+
|
|
106
|
+
| Herramienta | Descripción | Scopes |
|
|
107
|
+
|---|---|---|
|
|
108
|
+
| `resource.list` | Listar recursos físicos de una organización | `resource:read` |
|
|
109
|
+
| `resource.get` | Obtener detalles de un recurso con sus slots de disponibilidad | `resource:read` |
|
|
110
|
+
| `resource.create` | Crear un nuevo recurso físico (sala, box, equipamiento) | `resource:write` |
|
|
111
|
+
| `resource.update` | Actualizar recurso (patch semántico) | `resource:write` |
|
|
112
|
+
| `resource.delete` | Desactivar recurso (soft delete: `is_active = false`) | `resource:write` |
|
|
113
|
+
| `resource.get_availability` | Consultar disponibilidad de un recurso por rango de fechas | `resource:read` |
|
|
114
|
+
|
|
115
|
+
### Administración del Resolver (3 herramientas)
|
|
116
|
+
|
|
117
|
+
| Herramienta | Descripción | Scopes |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| `resolve.register` | Registrar organización en el resolver global con endpoints MCP/REST | `resolve:write` |
|
|
120
|
+
| `resolve.update_endpoint` | Actualizar endpoints registrados (portabilidad entre backends) | `resolve:write` |
|
|
121
|
+
| `telemetry.heartbeat` | Enviar heartbeat al resolver indicando que el nodo está activo | `telemetry:write` |
|
|
122
|
+
|
|
123
|
+
## Instalación y Quickstart
|
|
124
|
+
|
|
125
|
+
### Opción 1: Modo descubrimiento (zero config)
|
|
14
126
|
|
|
15
127
|
```bash
|
|
16
128
|
npx -y @servicialo/mcp-server
|
|
17
129
|
```
|
|
18
130
|
|
|
19
|
-
|
|
131
|
+
Sin API key. Sin org ID. 9 herramientas públicas disponibles de inmediato (resolver + descubrimiento). Pruébalo:
|
|
20
132
|
|
|
21
|
-
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"tool": "registry.search",
|
|
136
|
+
"arguments": {
|
|
137
|
+
"vertical": "kinesiologia",
|
|
138
|
+
"location": "santiago"
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Opción 2: Modo completo (autenticado)
|
|
22
144
|
|
|
23
145
|
```bash
|
|
24
|
-
SERVICIALO_API_KEY=
|
|
146
|
+
SERVICIALO_API_KEY=tu_key SERVICIALO_ORG_ID=tu_org npx -y @servicialo/mcp-server
|
|
25
147
|
```
|
|
26
148
|
|
|
27
|
-
|
|
149
|
+
Las 33 herramientas habilitadas.
|
|
150
|
+
|
|
151
|
+
### Claude Desktop / Cursor / cualquier cliente MCP
|
|
28
152
|
|
|
29
|
-
|
|
153
|
+
Agregar a tu configuración MCP:
|
|
30
154
|
|
|
31
155
|
```json
|
|
32
156
|
{
|
|
@@ -35,198 +159,263 @@ Requires `SERVICIALO_API_KEY` and `SERVICIALO_ORG_ID`. Enables all 20 tools acro
|
|
|
35
159
|
"command": "npx",
|
|
36
160
|
"args": ["-y", "@servicialo/mcp-server"],
|
|
37
161
|
"env": {
|
|
38
|
-
"SERVICIALO_API_KEY": "
|
|
39
|
-
"SERVICIALO_ORG_ID": "
|
|
162
|
+
"SERVICIALO_API_KEY": "tu_api_key",
|
|
163
|
+
"SERVICIALO_ORG_ID": "tu_org_id"
|
|
40
164
|
}
|
|
41
165
|
}
|
|
42
166
|
}
|
|
43
167
|
}
|
|
44
168
|
```
|
|
45
169
|
|
|
46
|
-
|
|
170
|
+
Omitir el bloque `env` para modo solo-descubrimiento.
|
|
47
171
|
|
|
48
|
-
|
|
172
|
+
### Variables de Entorno
|
|
49
173
|
|
|
50
|
-
| Variable |
|
|
51
|
-
|
|
52
|
-
| `SERVICIALO_API_KEY` | No | Bearer token
|
|
53
|
-
| `SERVICIALO_ORG_ID` | No |
|
|
54
|
-
| `SERVICIALO_BASE_URL` | No | API
|
|
174
|
+
| Variable | Requerida | Default | Descripción |
|
|
175
|
+
|---|---|---|---|
|
|
176
|
+
| `SERVICIALO_API_KEY` | No | — | Bearer token. Habilita modo autenticado |
|
|
177
|
+
| `SERVICIALO_ORG_ID` | No | — | Slug de organización. Habilita modo autenticado |
|
|
178
|
+
| `SERVICIALO_BASE_URL` | No | `http://localhost:3000` | Endpoint del API de la plataforma compatible con Servicialo |
|
|
179
|
+
| `SERVICIALO_ADAPTER` | No | `coordinalo` | Adapter de backend: `coordinalo` o `http` |
|
|
180
|
+
|
|
181
|
+
`SERVICIALO_API_KEY` y `SERVICIALO_ORG_ID` deben configurarse juntas. Si solo una está presente, el servidor cae a modo descubrimiento con un warning.
|
|
182
|
+
|
|
183
|
+
## Conectar una implementación propia
|
|
184
|
+
|
|
185
|
+
Este MCP server soporta cualquier backend compatible con Servicialo a través de la capa de adaptadores pluggable. Dos adaptadores están incluidos:
|
|
186
|
+
|
|
187
|
+
- **`coordinalo`** (default) — se conecta a un backend Coordinalo/Digitalo con rutas org-scoped bajo `/api/organizations/{orgId}`.
|
|
188
|
+
- **`http`** — se conecta a cualquier implementación que exponga los endpoints canónicos de `HTTP_PROFILE.md` bajo `/v1/*`.
|
|
189
|
+
|
|
190
|
+
### 3 pasos para conectar tu implementación
|
|
191
|
+
|
|
192
|
+
**Paso 1.** Implementar los endpoints REST definidos en [`HTTP_PROFILE.md`](../../HTTP_PROFILE.md) en tu plataforma.
|
|
55
193
|
|
|
56
|
-
|
|
194
|
+
**Paso 2.** Configurar el MCP server para usar el adaptador HTTP:
|
|
57
195
|
|
|
196
|
+
```bash
|
|
197
|
+
SERVICIALO_ADAPTER=http \
|
|
198
|
+
SERVICIALO_BASE_URL=https://tu-plataforma.com \
|
|
199
|
+
SERVICIALO_API_KEY=tu_key \
|
|
200
|
+
npx -y @servicialo/mcp-server
|
|
58
201
|
```
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
202
|
+
|
|
203
|
+
**Paso 3.** Agregar a la configuración de tu cliente MCP:
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"mcpServers": {
|
|
208
|
+
"servicialo": {
|
|
209
|
+
"command": "npx",
|
|
210
|
+
"args": ["-y", "@servicialo/mcp-server"],
|
|
211
|
+
"env": {
|
|
212
|
+
"SERVICIALO_ADAPTER": "http",
|
|
213
|
+
"SERVICIALO_BASE_URL": "https://tu-plataforma.com",
|
|
214
|
+
"SERVICIALO_API_KEY": "tu_api_key",
|
|
215
|
+
"SERVICIALO_ORG_ID": "tu_org_id"
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
65
220
|
```
|
|
66
221
|
|
|
67
|
-
|
|
222
|
+
El adaptador HTTP traduce las rutas internas a endpoints canónicos `/v1/*` y envía el contexto de organización via el header `X-Servicialo-Org`. Consulta `HTTP_PROFILE.md` para el contrato REST completo.
|
|
68
223
|
|
|
69
|
-
##
|
|
224
|
+
## Modelo de Agencia Delegada
|
|
70
225
|
|
|
71
|
-
|
|
72
|
-
|---|---|
|
|
73
|
-
| `registry.search` | Search organizations by vertical and location |
|
|
74
|
-
| `registry.get_organization` | Get public details of an organization |
|
|
75
|
-
| `scheduling.check_availability` | Check available slots without authentication. If the service has `resource_id` in its location, also verifies physical resource availability (3-variable scheduler: provider ∧ client ∧ resource) |
|
|
76
|
-
| `services.list` | List the public service catalog |
|
|
226
|
+
El protocolo trata a los agentes de IA como actores de primera clase — pero nunca confía en ellos implícitamente. Cada acción de agente requiere un **ServiceMandate**: una delegación explícita de capacidad de un humano principal a un agente.
|
|
77
227
|
|
|
78
|
-
|
|
228
|
+
### Cómo funciona
|
|
79
229
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
230
|
+
1. Un humano (profesional, paciente u organización) emite un mandato a un agente
|
|
231
|
+
2. El mandato especifica **para quién** actúa el agente, **qué** puede hacer (scopes), y **por cuánto tiempo**
|
|
232
|
+
3. En cada tool call, el MCP server valida el mandato contra 8 checks antes de ejecutar
|
|
233
|
+
4. Cada acción produce una entrada de auditoría — éxito o fallo
|
|
84
234
|
|
|
85
|
-
|
|
235
|
+
### Ejemplo de mandato
|
|
86
236
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
237
|
+
```json
|
|
238
|
+
{
|
|
239
|
+
"mandate_id": "550e8400-e29b-41d4-a716-446655440000",
|
|
240
|
+
"principal_id": "dra_barbara",
|
|
241
|
+
"principal_type": "professional",
|
|
242
|
+
"agent_id": "agent_booking_bot",
|
|
243
|
+
"agent_name": "Asistente de Agendamiento",
|
|
244
|
+
"acting_for": "professional",
|
|
245
|
+
"context": "org:clinica-kinesia",
|
|
246
|
+
"scopes": ["schedule:read", "schedule:write", "patient:write"],
|
|
247
|
+
"constraints": {
|
|
248
|
+
"max_actions_per_day": 50,
|
|
249
|
+
"allowed_hours": {
|
|
250
|
+
"start": "08:00",
|
|
251
|
+
"end": "20:00",
|
|
252
|
+
"timezone": "America/Santiago"
|
|
253
|
+
},
|
|
254
|
+
"require_confirmation_above": {
|
|
255
|
+
"amount": 100000,
|
|
256
|
+
"currency": "CLP"
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
"issued_at": "2026-03-01T00:00:00Z",
|
|
260
|
+
"expires_at": "2026-06-01T00:00:00Z",
|
|
261
|
+
"status": "active"
|
|
262
|
+
}
|
|
263
|
+
```
|
|
92
264
|
|
|
93
|
-
|
|
265
|
+
### Uso de mandatos en tool calls
|
|
94
266
|
|
|
95
|
-
|
|
96
|
-
|---|---|
|
|
97
|
-
| `lifecycle.get_state` | Get current lifecycle state, available transitions, and transition history |
|
|
98
|
-
| `lifecycle.transition` | Execute a state transition with evidence. Valid: requested→scheduled, scheduled→confirmed, confirmed→in_progress, in_progress→delivered, delivered→documented, documented→charged, charged→verified, any→cancelled |
|
|
99
|
-
| `scheduling.reschedule` | Exception flow: reschedule to new datetime. Contract rescheduling policy may apply |
|
|
100
|
-
| `scheduling.cancel` | Exception flow: cancel with contract cancellation policy applied |
|
|
267
|
+
Cuando `actor.type` es `"agent"`, incluir el `mandate_id`:
|
|
101
268
|
|
|
102
|
-
|
|
269
|
+
```json
|
|
270
|
+
{
|
|
271
|
+
"tool": "scheduling.book",
|
|
272
|
+
"arguments": {
|
|
273
|
+
"service_id": "srv_123",
|
|
274
|
+
"provider_id": "prov_111",
|
|
275
|
+
"client_id": "cli_789",
|
|
276
|
+
"starts_at": "2026-03-03T10:00:00",
|
|
277
|
+
"actor": {
|
|
278
|
+
"type": "agent",
|
|
279
|
+
"id": "agent_booking_bot",
|
|
280
|
+
"mandate_id": "550e8400-e29b-41d4-a716-446655440000"
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
103
285
|
|
|
104
|
-
|
|
105
|
-
|---|---|
|
|
106
|
-
| `delivery.checkin` | Provider/client check-in with GPS + timestamp → state "En Curso" |
|
|
107
|
-
| `delivery.checkout` | Check-out with GPS + timestamp → state "Entregado". Duration auto-calculated |
|
|
108
|
-
| `delivery.record_evidence` | Record delivery evidence per vertical: GPS, signature, photo, document, duration, notes |
|
|
286
|
+
### Los 8 checks de validación
|
|
109
287
|
|
|
110
|
-
|
|
288
|
+
Cada tool call de un agente se valida contra:
|
|
111
289
|
|
|
112
|
-
|
|
|
113
|
-
|
|
114
|
-
|
|
|
115
|
-
|
|
|
116
|
-
|
|
|
117
|
-
|
|
|
290
|
+
| # | Check | Qué previene |
|
|
291
|
+
|---|---|---|
|
|
292
|
+
| 1 | **Estado** — mandato debe ser `active` | Uso de mandatos revocados o expirados |
|
|
293
|
+
| 2 | **Validez temporal** — `issued_at ≤ now < expires_at` | Ataques basados en tiempo |
|
|
294
|
+
| 3 | **Identidad del agente** — `mandate.agent_id === agente solicitante` | Suplantación de agente |
|
|
295
|
+
| 4 | **Cobertura de scopes** — scopes del mandato cubren los requisitos de la herramienta | Escalación de privilegios |
|
|
296
|
+
| 5 | **Contexto** — contexto del mandato coincide con la solicitud | Acceso cross-org a datos |
|
|
297
|
+
| 6 | **Conflicto de interés** — agente no puede actuar para ambas partes | Violaciones de doble agencia |
|
|
298
|
+
| 7 | **Restricciones** — horarios permitidos, límites diarios, umbrales financieros | Agentes sobre-autónomos |
|
|
299
|
+
| 8 | **Auditoría** — cada acción registrada con inputs sanitizados | No repudio |
|
|
300
|
+
|
|
301
|
+
Actores no-agente (`client`, `provider`, `organization`) no pasan por validación de mandato.
|
|
302
|
+
|
|
303
|
+
## Descubrimiento de Prestadores
|
|
118
304
|
|
|
119
|
-
|
|
305
|
+
Los agentes pueden buscar en el registro y hacer matching de prestadores con las necesidades de un paciente usando consultas estructuradas.
|
|
120
306
|
|
|
307
|
+
### Buscar en el registro
|
|
308
|
+
|
|
309
|
+
```json
|
|
310
|
+
{
|
|
311
|
+
"tool": "registry.search",
|
|
312
|
+
"arguments": {
|
|
313
|
+
"vertical": "kinesiologia",
|
|
314
|
+
"location": "santiago",
|
|
315
|
+
"country": "cl"
|
|
316
|
+
}
|
|
317
|
+
}
|
|
121
318
|
```
|
|
122
|
-
registry.search({ vertical: "kinesiologia", location: "santiago" })
|
|
123
|
-
→ find org "clinica-kinesia"
|
|
124
319
|
|
|
125
|
-
|
|
126
|
-
→ list services, providers
|
|
320
|
+
Retorna organizaciones que coinciden con sus servicios y prestadores.
|
|
127
321
|
|
|
128
|
-
|
|
129
|
-
→ available slots
|
|
322
|
+
### Consultar disponibilidad
|
|
130
323
|
|
|
131
|
-
|
|
132
|
-
|
|
324
|
+
```json
|
|
325
|
+
{
|
|
326
|
+
"tool": "scheduling.check_availability",
|
|
327
|
+
"arguments": {
|
|
328
|
+
"org_slug": "clinica-kinesia",
|
|
329
|
+
"service_id": "srv_rehab_pelvica",
|
|
330
|
+
"provider_id": "prov_111",
|
|
331
|
+
"date_from": "2026-03-10",
|
|
332
|
+
"date_to": "2026-03-14"
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
```
|
|
133
336
|
|
|
134
|
-
|
|
135
|
-
→ evidence: check_in + check_out + clinical_record
|
|
136
|
-
→ cancellation: 0% if >24h, 50% if 2-24h, 100% if <2h
|
|
137
|
-
→ dispute window: 48 hours
|
|
337
|
+
El scheduler de 3 variables verifica disponibilidad de prestador, cliente y recurso físico simultáneamente.
|
|
138
338
|
|
|
139
|
-
|
|
140
|
-
→ client_id: "cli_789"
|
|
339
|
+
### Ejemplo de punta a punta
|
|
141
340
|
|
|
142
|
-
|
|
143
|
-
|
|
341
|
+
```
|
|
342
|
+
1. registry.search({ vertical: "kinesiologia", location: "santiago" })
|
|
343
|
+
→ encuentra org "clinica-kinesia"
|
|
144
344
|
|
|
145
|
-
|
|
146
|
-
|
|
345
|
+
2. services.list({ org_slug: "clinica-kinesia" })
|
|
346
|
+
→ lista servicios disponibles
|
|
147
347
|
|
|
148
|
-
|
|
149
|
-
|
|
348
|
+
3. scheduling.check_availability({ org_slug: "clinica-kinesia", date_from: "2026-03-10", date_to: "2026-03-14" })
|
|
349
|
+
→ retorna slots disponibles
|
|
150
350
|
|
|
151
|
-
|
|
152
|
-
|
|
351
|
+
4. contract.get({ service_id: "srv_123", org_id: "org_456" })
|
|
352
|
+
→ cancelación: 0% si >24h, 50% si 2-24h, 100% si <2h
|
|
353
|
+
→ evidencia requerida: check_in + check_out + registro_clinico
|
|
153
354
|
|
|
154
|
-
|
|
155
|
-
|
|
355
|
+
5. clients.get_or_create({ email: "maria@mail.com", name: "Maria", last_name: "Lopez" })
|
|
356
|
+
→ client_id: "cli_789"
|
|
156
357
|
|
|
157
|
-
|
|
158
|
-
|
|
358
|
+
6. scheduling.book({ service_id: "srv_123", provider_id: "prov_111", client_id: "cli_789", starts_at: "2026-03-12T10:00:00" })
|
|
359
|
+
→ session_id: "ses_001", estado: "solicitado"
|
|
159
360
|
|
|
160
|
-
|
|
161
|
-
|
|
361
|
+
7. scheduling.confirm({ session_id: "ses_001" })
|
|
362
|
+
→ estado: "confirmado"
|
|
162
363
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
```
|
|
364
|
+
8. delivery.checkin({ session_id: "ses_001", location: { lat: -33.45, lng: -70.66 } })
|
|
365
|
+
→ estado: "en_curso"
|
|
166
366
|
|
|
167
|
-
|
|
367
|
+
9. delivery.checkout({ session_id: "ses_001", location: { lat: -33.45, lng: -70.66 } })
|
|
368
|
+
→ estado: "entregado", duración: 42min
|
|
168
369
|
|
|
169
|
-
|
|
370
|
+
10. documentation.create({ session_id: "ses_001", content: "Sesión de rehabilitación de piso pélvico..." })
|
|
371
|
+
→ estado: "documentado"
|
|
170
372
|
|
|
171
|
-
|
|
373
|
+
11. payments.create_sale({ client_id: "cli_789", service_id: "srv_123", unit_price: 35000 })
|
|
374
|
+
→ sale_id: "sale_001", estado: "cobrado"
|
|
172
375
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
| `scheduling.book` | Now accepts optional `resource_id` — reserves physical resource alongside session |
|
|
177
|
-
| New types | `ResourceSchema`, `ResourceAvailabilitySchema`, `ServiceLocationSchema` with `resource_id` |
|
|
178
|
-
| New exception flow | 5.7 Resource Conflict — when a resource is double-booked or unavailable |
|
|
376
|
+
12. lifecycle.transition({ session_id: "ses_001", to_state: "verified" })
|
|
377
|
+
→ estado: "verificado" ✓
|
|
378
|
+
```
|
|
179
379
|
|
|
180
|
-
|
|
380
|
+
## Especificación del Protocolo
|
|
181
381
|
|
|
182
|
-
|
|
382
|
+
La especificación completa del protocolo Servicialo está disponible en:
|
|
183
383
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
| `clients.get` | `clients.get_or_create` |
|
|
189
|
-
| `clients.create` | `clients.get_or_create` |
|
|
190
|
-
| `clients.history` | `lifecycle.get_state` |
|
|
191
|
-
| `payments.list_sales` | `payments.get_status` |
|
|
192
|
-
| `payments.client_balance` | `payments.get_status` |
|
|
193
|
-
| `notifications.send_session_reminder` | `lifecycle.transition` |
|
|
194
|
-
| `notifications.send_payment_reminder` | `lifecycle.transition` |
|
|
195
|
-
| `providers.list` | Removed (not part of service lifecycle) |
|
|
196
|
-
| `providers.get` | Removed (not part of service lifecycle) |
|
|
197
|
-
| `providers.get_commission` | Removed (not part of service lifecycle) |
|
|
198
|
-
| `payroll.*` (5 tools) | Removed (not part of service lifecycle) |
|
|
384
|
+
- **Repositorio:** [github.com/servicialo/protocol](https://github.com/servicialo/protocol)
|
|
385
|
+
- **Sitio web:** [servicialo.com](https://servicialo.com)
|
|
386
|
+
- **Versión estable actual:** 0.9
|
|
387
|
+
- **JSON Schemas:** [`service.schema.json`](https://github.com/servicialo/protocol/blob/main/schema/service.schema.json), [`service-order.schema.json`](https://github.com/servicialo/protocol/blob/main/schema/service-order.schema.json), [`service-mandate.schema.json`](https://github.com/servicialo/protocol/blob/main/schema/service-mandate.schema.json), [`resolution.schema.json`](https://github.com/servicialo/protocol/blob/main/schema/resolution.schema.json), [`servicialo-config.schema.json`](https://github.com/servicialo/protocol/blob/main/schema/servicialo-config.schema.json)
|
|
199
388
|
|
|
200
|
-
|
|
389
|
+
La spec cubre las 8 dimensiones del servicio, 9 estados de ciclo de vida, 7 flujos de excepción, la arquitectura de dos entidades (Servicio atómico + Orden de Servicio), el Modelo de Agencia Delegada, resolución DNS, e interoperabilidad A2A.
|
|
201
390
|
|
|
202
|
-
|
|
391
|
+
## Implementación de Referencia
|
|
203
392
|
|
|
204
|
-
|
|
393
|
+
**Digitalo** es la primera implementación en producción del protocolo Servicialo, operando en salud en Chile. Implementa el ciclo de vida completo — desde descubrimiento de prestadores hasta liquidación de pagos — y sirve como terreno de validación para la evolución del protocolo.
|
|
205
394
|
|
|
206
|
-
|
|
395
|
+
Este MCP server se conecta a cualquier backend compatible con Servicialo a través de `SERVICIALO_BASE_URL`. Digitalo es uno de esos backends. El protocolo está diseñado para que cualquier CRM, HIS, o plataforma lo implemente como un nodo soberano.
|
|
207
396
|
|
|
208
|
-
|
|
209
|
-
|---|---|---|
|
|
210
|
-
| Completed | Delivered | Renamed — provider marks delivery, not completion |
|
|
211
|
-
| Documented | Documented | Unchanged — comes after Delivered |
|
|
212
|
-
| Invoiced | — | Removed from lifecycle — tracked in billing.status |
|
|
213
|
-
| Collected | — | Removed from lifecycle — tracked in billing.status |
|
|
214
|
-
| — | Charged | New — charge applied 1:1 with delivered + documented session |
|
|
215
|
-
| Verified (pos 6) | Verified (pos 8) | Moved to final — client confirms or auto-verified after silence window |
|
|
397
|
+
## Contribuir al Protocolo
|
|
216
398
|
|
|
217
|
-
|
|
399
|
+
Servicialo sigue versionado semántico para la especificación del protocolo:
|
|
218
400
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
401
|
+
- **Patch** (0.7.x) — clarificaciones, correcciones de typos, adiciones no-breaking
|
|
402
|
+
- **Minor** (0.x.0) — nuevos campos opcionales, nuevas definiciones de herramientas, nuevos flujos de excepción
|
|
403
|
+
- **Major** (x.0.0) — cambios breaking a schemas, máquina de estados, o semántica core
|
|
222
404
|
|
|
223
|
-
|
|
224
|
-
npm run build
|
|
405
|
+
### Cómo proponer cambios
|
|
225
406
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
407
|
+
1. Abrir un issue describiendo el problema y la solución propuesta
|
|
408
|
+
2. Para cambios significativos, escribir un RFC en `spec/` con el número de sección que afecta
|
|
409
|
+
3. Los cambios al protocolo requieren al menos una implementación de referencia antes de merge
|
|
410
|
+
4. Los cambios a schemas deben incluir JSON Schema actualizado y tipos Zod en el MCP server
|
|
411
|
+
|
|
412
|
+
### Áreas buscando input activamente
|
|
413
|
+
|
|
414
|
+
- Requisitos de evidencia específicos por vertical (más allá de salud)
|
|
415
|
+
- Soporte multi-idioma para nombres de estados del ciclo de vida
|
|
416
|
+
- Federación inter-nodo (cómo dos implementaciones Servicialo interoperan)
|
|
417
|
+
- Patrones de Agent SDK para Python y TypeScript
|
|
229
418
|
|
|
230
|
-
##
|
|
419
|
+
## Licencia
|
|
231
420
|
|
|
232
|
-
|
|
421
|
+
Apache-2.0 — cualquier implementación, comercial o no, es bienvenida. Ver [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HttpAdapter — generic adapter for any Servicialo-compatible implementation
|
|
3
|
+
* that exposes the canonical HTTP_PROFILE.md REST endpoints.
|
|
4
|
+
*
|
|
5
|
+
* Path translation:
|
|
6
|
+
* Coordinalo internal paths (used by tool handlers) are translated to
|
|
7
|
+
* canonical /v1/* paths defined in HTTP_PROFILE.md.
|
|
8
|
+
*
|
|
9
|
+
* Public endpoints:
|
|
10
|
+
* /api/servicialo/registry → /v1/registry
|
|
11
|
+
* /api/servicialo/{slug}/services → /v1/organizations/{slug}/services
|
|
12
|
+
* /api/servicialo/{slug}/availability → /v1/organizations/{slug}/availability
|
|
13
|
+
*
|
|
14
|
+
* Authenticated endpoints:
|
|
15
|
+
* /coordinalo/* → /v1/*
|
|
16
|
+
* /relacionalo/clients/upsert → /v1/clients
|
|
17
|
+
* /planificalo/* → /v1/*
|
|
18
|
+
*
|
|
19
|
+
* Unlike CoordinaloClient, this adapter does NOT prefix paths with
|
|
20
|
+
* /api/organizations/{orgId}. The org context is communicated via
|
|
21
|
+
* the X-Servicialo-Org header (or the implementation's own mechanism).
|
|
22
|
+
*/
|
|
23
|
+
import type { ServicialoAdapter } from './adapter.js';
|
|
24
|
+
export interface HttpAdapterConfig {
|
|
25
|
+
baseUrl: string;
|
|
26
|
+
apiKey?: string;
|
|
27
|
+
orgId?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare class HttpAdapter implements ServicialoAdapter {
|
|
30
|
+
private baseUrl;
|
|
31
|
+
private apiKey;
|
|
32
|
+
private orgId;
|
|
33
|
+
constructor(config: HttpAdapterConfig);
|
|
34
|
+
get isAuthenticated(): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Translate a Coordinalo-internal path to a canonical HTTP_PROFILE.md path.
|
|
37
|
+
*/
|
|
38
|
+
private translatePath;
|
|
39
|
+
private authHeaders;
|
|
40
|
+
private publicHeaders;
|
|
41
|
+
private buildUrl;
|
|
42
|
+
readonly pub: {
|
|
43
|
+
get: (path: string, params?: Record<string, string | number | undefined>) => Promise<unknown>;
|
|
44
|
+
};
|
|
45
|
+
get(path: string, params?: Record<string, string | number | undefined>): Promise<unknown>;
|
|
46
|
+
post(path: string, body?: unknown): Promise<unknown>;
|
|
47
|
+
put(path: string, body?: unknown): Promise<unknown>;
|
|
48
|
+
patch(path: string, body?: unknown): Promise<unknown>;
|
|
49
|
+
delete(path: string): Promise<unknown>;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=adapter-http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-http.d.ts","sourceRoot":"","sources":["../src/adapter-http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,WAAY,YAAW,iBAAiB;IACnD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,KAAK,CAAqB;gBAEtB,MAAM,EAAE,iBAAiB;IAMrC,IAAI,eAAe,IAAI,OAAO,CAE7B;IAID;;OAEG;IACH,OAAO,CAAC,aAAa;IA2CrB,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,QAAQ;IAMhB,QAAQ,CAAC,GAAG;oBACQ,MAAM,WAAW,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,KAAG,OAAO,CAAC,OAAO,CAAC;MAsBjG;IAII,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAuBzF,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAepD,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAenD,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAerD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAa7C"}
|