@mcptoolshop/pianoai 1.0.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.
Potentially problematic release.
This version of @mcptoolshop/pianoai might be problematic. Click here for more details.
- package/LICENSE +21 -0
- package/README.es.md +253 -0
- package/README.fr.md +253 -0
- package/README.hi.md +253 -0
- package/README.it.md +253 -0
- package/README.ja.md +253 -0
- package/README.md +253 -0
- package/README.pt-BR.md +253 -0
- package/README.zh.md +253 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +294 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server.d.ts +3 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +324 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/note-parser.d.ts +69 -0
- package/dist/note-parser.d.ts.map +1 -0
- package/dist/note-parser.js +172 -0
- package/dist/note-parser.js.map +1 -0
- package/dist/session.d.ts +101 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +339 -0
- package/dist/session.js.map +1 -0
- package/dist/smoke.d.ts +2 -0
- package/dist/smoke.d.ts.map +1 -0
- package/dist/smoke.js +207 -0
- package/dist/smoke.js.map +1 -0
- package/dist/teaching.d.ts +106 -0
- package/dist/teaching.d.ts.map +1 -0
- package/dist/teaching.js +269 -0
- package/dist/teaching.js.map +1 -0
- package/dist/types.d.ts +206 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +22 -0
- package/dist/types.js.map +1 -0
- package/dist/vmpk.d.ts +21 -0
- package/dist/vmpk.d.ts.map +1 -0
- package/dist/vmpk.js +185 -0
- package/dist/vmpk.js.map +1 -0
- package/logo.svg +10 -0
- package/package.json +69 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 mcp-tool-shop
|
|
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.
|
package/README.es.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="README.md">English</a> | <a href="README.ja.md">日本語</a> | <a href="README.zh.md">中文</a> | <strong>Español</strong> | <a href="README.fr.md">Français</a> | <a href="README.hi.md">हिन्दी</a> | <a href="README.it.md">Italiano</a> | <a href="README.pt-BR.md">Português</a>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="logo.svg" alt="PianoAI logo" width="180" />
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<h1 align="center">PianoAI</h1>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
Servidor MCP + CLI para enseñanza de piano con IA — reproduce a través de VMPK vía MIDI con retroalimentación por voz.
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
[](https://github.com/mcp-tool-shop-org/pianoai)
|
|
16
|
+
[](https://github.com/mcp-tool-shop-org/pianoai)
|
|
17
|
+
[](https://github.com/mcp-tool-shop-org/pianoai)
|
|
18
|
+
[-blue)](https://github.com/mcp-tool-shop-org/ai-music-sheets)
|
|
19
|
+
|
|
20
|
+
## ¿Qué es esto?
|
|
21
|
+
|
|
22
|
+
Un CLI en TypeScript y servidor MCP que carga canciones de piano desde [ai-music-sheets](https://github.com/mcp-tool-shop-org/ai-music-sheets), las convierte a MIDI y las reproduce a través de [VMPK](https://vmpk.sourceforge.io/) mediante un puerto MIDI virtual. El motor de enseñanza lanza interjecciones en los límites de compás y en momentos clave, permitiendo que un LLM actúe como profesor de piano en vivo con retroalimentación por voz y notificaciones aparte.
|
|
23
|
+
|
|
24
|
+
## Características
|
|
25
|
+
|
|
26
|
+
- **4 modos de reproducción** — completa, compás por compás, manos separadas, bucle
|
|
27
|
+
- **Control de velocidad** — práctica lenta a 0.5x hasta reproducción rápida a 2x, acumulable con modificación de tempo
|
|
28
|
+
- **Seguimiento de progreso** — callbacks configurables en hitos porcentuales o por compás
|
|
29
|
+
- **7 hooks de enseñanza** — console, silent, recording, callback, voice, aside, compose
|
|
30
|
+
- **Retroalimentación por voz** — salida `VoiceDirective` para integración con mcp-voice-soundboard
|
|
31
|
+
- **Interjecciones aparte** — salida `AsideDirective` para la bandeja de mcp-aside
|
|
32
|
+
- **Análisis seguro** — las notas incorrectas se omiten con `ParseWarning`s recopilados
|
|
33
|
+
- **7 herramientas MCP** — exponen el registro, notas de enseñanza y recomendaciones de canciones a LLMs
|
|
34
|
+
- **Analizador de notas** — notación científica de altura a MIDI y viceversa
|
|
35
|
+
- **Conector simulado** — cobertura completa de tests sin hardware MIDI
|
|
36
|
+
|
|
37
|
+
## Requisitos previos
|
|
38
|
+
|
|
39
|
+
1. **[loopMIDI](https://www.tobias-erichsen.de/software/loopmidi.html)** — crea un puerto MIDI virtual (ej. "loopMIDI Port")
|
|
40
|
+
2. **[VMPK](https://vmpk.sourceforge.io/)** — configura la entrada MIDI a tu puerto loopMIDI
|
|
41
|
+
3. **Node.js 18+**
|
|
42
|
+
|
|
43
|
+
## Instalación
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm install -g @mcptoolshop/pianoai
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Inicio rápido
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Listar todas las canciones
|
|
53
|
+
pianai list
|
|
54
|
+
|
|
55
|
+
# Mostrar detalles de canción + notas de enseñanza
|
|
56
|
+
pianai info moonlight-sonata-mvt1
|
|
57
|
+
|
|
58
|
+
# Reproducir una canción a través de VMPK
|
|
59
|
+
pianai play let-it-be
|
|
60
|
+
|
|
61
|
+
# Reproducir con modificación de tempo
|
|
62
|
+
pianai play basic-12-bar-blues --tempo 80
|
|
63
|
+
|
|
64
|
+
# Avanzar compás por compás
|
|
65
|
+
pianai play autumn-leaves --mode measure
|
|
66
|
+
|
|
67
|
+
# Práctica a mitad de velocidad
|
|
68
|
+
pianai play moonlight-sonata-mvt1 --speed 0.5
|
|
69
|
+
|
|
70
|
+
# Práctica lenta con manos separadas
|
|
71
|
+
pianai play dream-on --speed 0.75 --mode hands
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Servidor MCP
|
|
75
|
+
|
|
76
|
+
El servidor MCP expone 7 herramientas para integración con LLMs:
|
|
77
|
+
|
|
78
|
+
| Herramienta | Descripción |
|
|
79
|
+
|-------------|-------------|
|
|
80
|
+
| `list_songs` | Explorar/buscar canciones por género, dificultad o consulta |
|
|
81
|
+
| `song_info` | Obtener lenguaje musical completo, objetivos de enseñanza, sugerencias de práctica |
|
|
82
|
+
| `registry_stats` | Conteo de canciones por género y dificultad |
|
|
83
|
+
| `teaching_note` | Nota de enseñanza por compás, digitación, dinámicas |
|
|
84
|
+
| `suggest_song` | Obtener una recomendación basada en criterios |
|
|
85
|
+
| `list_measures` | Vista general de compases con notas de enseñanza + advertencias de análisis |
|
|
86
|
+
| `practice_setup` | Sugerir velocidad, modo y configuración de voz para una canción |
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Iniciar el servidor MCP (transporte stdio)
|
|
90
|
+
pnpm mcp
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Configuración de Claude Desktop
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"mcpServers": {
|
|
98
|
+
"pianai": {
|
|
99
|
+
"command": "pianai-mcp"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Comandos del CLI
|
|
106
|
+
|
|
107
|
+
| Comando | Descripción |
|
|
108
|
+
|---------|-------------|
|
|
109
|
+
| `list [--genre <genre>]` | Listar canciones disponibles, opcionalmente filtradas por género |
|
|
110
|
+
| `info <song-id>` | Mostrar detalles de canción: lenguaje musical, notas de enseñanza, estructura |
|
|
111
|
+
| `play <song-id> [opts]` | Reproducir una canción a través de VMPK vía MIDI |
|
|
112
|
+
| `stats` | Estadísticas del registro (canciones, géneros, compases) |
|
|
113
|
+
| `ports` | Listar puertos de salida MIDI disponibles |
|
|
114
|
+
| `help` | Mostrar información de uso |
|
|
115
|
+
|
|
116
|
+
### Opciones de reproducción
|
|
117
|
+
|
|
118
|
+
| Bandera | Descripción |
|
|
119
|
+
|---------|-------------|
|
|
120
|
+
| `--port <name>` | Nombre del puerto MIDI (por defecto: autodetectar loopMIDI) |
|
|
121
|
+
| `--tempo <bpm>` | Modificar el tempo predeterminado de la canción (10-400 BPM) |
|
|
122
|
+
| `--speed <mult>` | Multiplicador de velocidad: 0.5 = mitad, 1.0 = normal, 2.0 = doble |
|
|
123
|
+
| `--mode <mode>` | Modo de reproducción: `full`, `measure`, `hands`, `loop` |
|
|
124
|
+
|
|
125
|
+
## Motor de enseñanza
|
|
126
|
+
|
|
127
|
+
El motor de enseñanza dispara hooks durante la reproducción. 7 implementaciones de hooks cubren todos los casos de uso:
|
|
128
|
+
|
|
129
|
+
| Hook | Caso de uso |
|
|
130
|
+
|------|-------------|
|
|
131
|
+
| `createConsoleTeachingHook()` | CLI — registra compases, momentos y finalización en consola |
|
|
132
|
+
| `createSilentTeachingHook()` | Testing — sin operación |
|
|
133
|
+
| `createRecordingTeachingHook()` | Testing — graba eventos para aserciones |
|
|
134
|
+
| `createCallbackTeachingHook(cb)` | Personalizado — redirige a cualquier callback asíncrono |
|
|
135
|
+
| `createVoiceTeachingHook(sink)` | Voz — produce `VoiceDirective` para mcp-voice-soundboard |
|
|
136
|
+
| `createAsideTeachingHook(sink)` | Aparte — produce `AsideDirective` para la bandeja de mcp-aside |
|
|
137
|
+
| `composeTeachingHooks(...hooks)` | Múltiple — despacha a múltiples hooks en serie |
|
|
138
|
+
|
|
139
|
+
### Retroalimentación por voz
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import { createSession, createVoiceTeachingHook } from "@mcptoolshop/pianoai";
|
|
143
|
+
import { getSong } from "ai-music-sheets";
|
|
144
|
+
|
|
145
|
+
const voiceHook = createVoiceTeachingHook(
|
|
146
|
+
async (directive) => {
|
|
147
|
+
// Redirigir a voice_speak de mcp-voice-soundboard
|
|
148
|
+
console.log(`[Voice] ${directive.text}`);
|
|
149
|
+
},
|
|
150
|
+
{ voice: "narrator", speechSpeed: 0.9 }
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
const session = createSession(getSong("moonlight-sonata-mvt1")!, connector, {
|
|
154
|
+
teachingHook: voiceHook,
|
|
155
|
+
speed: 0.5, // práctica a mitad de velocidad
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
await session.play();
|
|
159
|
+
// voiceHook.directives → todas las instrucciones de voz que se dispararon
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Composición de hooks
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import {
|
|
166
|
+
createVoiceTeachingHook,
|
|
167
|
+
createAsideTeachingHook,
|
|
168
|
+
createRecordingTeachingHook,
|
|
169
|
+
composeTeachingHooks,
|
|
170
|
+
} from "@mcptoolshop/pianoai";
|
|
171
|
+
|
|
172
|
+
// Los tres se disparan en cada evento
|
|
173
|
+
const composed = composeTeachingHooks(
|
|
174
|
+
createVoiceTeachingHook(voiceSink),
|
|
175
|
+
createAsideTeachingHook(asideSink),
|
|
176
|
+
createRecordingTeachingHook()
|
|
177
|
+
);
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## API programática
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
import { getSong } from "ai-music-sheets";
|
|
184
|
+
import { createSession, createVmpkConnector } from "@mcptoolshop/pianoai";
|
|
185
|
+
|
|
186
|
+
const connector = createVmpkConnector({ portName: /loop/i });
|
|
187
|
+
await connector.connect();
|
|
188
|
+
|
|
189
|
+
const song = getSong("autumn-leaves")!;
|
|
190
|
+
const session = createSession(song, connector, {
|
|
191
|
+
mode: "measure",
|
|
192
|
+
tempo: 100,
|
|
193
|
+
speed: 0.75, // 75% de velocidad para práctica
|
|
194
|
+
onProgress: (p) => console.log(p.percent), // "25%", "50%", etc.
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
await session.play(); // reproduce un compás, pausa
|
|
198
|
+
session.next(); // avanza al siguiente compás
|
|
199
|
+
await session.play(); // reproduce el siguiente compás
|
|
200
|
+
session.setSpeed(1.0); // vuelve a velocidad normal
|
|
201
|
+
await session.play(); // reproduce el siguiente compás a velocidad completa
|
|
202
|
+
session.stop(); // detiene y reinicia
|
|
203
|
+
|
|
204
|
+
// Verificar advertencias de análisis (notas incorrectas en los datos de la canción)
|
|
205
|
+
if (session.parseWarnings.length > 0) {
|
|
206
|
+
console.warn("Algunas notas no pudieron ser analizadas:", session.parseWarnings);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
await connector.disconnect();
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Arquitectura
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
ai-music-sheets (biblioteca) pianai (tiempo de ejecución)
|
|
216
|
+
┌──────────────────────┐ ┌────────────────────────────────┐
|
|
217
|
+
│ SongEntry (híbrido) │────────→│ Note Parser (seguro + estricto)│
|
|
218
|
+
│ Registry (búsqueda) │ │ Session Engine (veloc.+progreso│
|
|
219
|
+
│ 10 canciones, 10 gén.│ │ Teaching Engine (7 hooks) │
|
|
220
|
+
└──────────────────────┘ │ VMPK Connector (JZZ) │
|
|
221
|
+
│ MCP Server (7 herramientas) │
|
|
222
|
+
│ CLI (barra de progreso + voz) │
|
|
223
|
+
└─────────┬──────────────────────┘
|
|
224
|
+
│ MIDI
|
|
225
|
+
▼
|
|
226
|
+
┌─────────────────┐
|
|
227
|
+
│ loopMIDI → VMPK │
|
|
228
|
+
└─────────────────┘
|
|
229
|
+
|
|
230
|
+
Enrutamiento de hooks de enseñanza:
|
|
231
|
+
Session → TeachingHook → VoiceDirective → mcp-voice-soundboard
|
|
232
|
+
→ AsideDirective → bandeja de mcp-aside
|
|
233
|
+
→ Console log → terminal del CLI
|
|
234
|
+
→ Recording → aserciones de test
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Testing
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
pnpm test # 121 tests con Vitest (parser + session + teaching + voice + aside)
|
|
241
|
+
pnpm smoke # 20 smoke tests (integración, sin MIDI necesario)
|
|
242
|
+
pnpm typecheck # tsc --noEmit
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
El conector VMPK simulado (`createMockVmpkConnector`) registra todos los eventos MIDI sin hardware, permitiendo cobertura completa de tests. Las funciones de análisis seguro (`safeParseMeasure`) recopilan objetos `ParseWarning` en lugar de lanzar excepciones, de modo que la reproducción continúa correctamente si una canción tiene notas malformadas.
|
|
246
|
+
|
|
247
|
+
## Relacionados
|
|
248
|
+
|
|
249
|
+
- **[ai-music-sheets](https://github.com/mcp-tool-shop-org/ai-music-sheets)** — La biblioteca de canciones: 10 géneros, formato híbrido (metadatos + lenguaje musical + compases listos para código)
|
|
250
|
+
|
|
251
|
+
## Licencia
|
|
252
|
+
|
|
253
|
+
MIT
|
package/README.fr.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="README.md">English</a> | <a href="README.ja.md">日本語</a> | <a href="README.zh.md">中文</a> | <a href="README.es.md">Español</a> | <strong>Français</strong> | <a href="README.hi.md">हिन्दी</a> | <a href="README.it.md">Italiano</a> | <a href="README.pt-BR.md">Português</a>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="logo.svg" alt="PianoAI logo" width="180" />
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<h1 align="center">PianoAI</h1>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
Serveur MCP + CLI pour l'enseignement du piano par IA — joue via VMPK par MIDI avec retour vocal.
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
[](https://github.com/mcp-tool-shop-org/pianoai)
|
|
16
|
+
[](https://github.com/mcp-tool-shop-org/pianoai)
|
|
17
|
+
[](https://github.com/mcp-tool-shop-org/pianoai)
|
|
18
|
+
[-blue)](https://github.com/mcp-tool-shop-org/ai-music-sheets)
|
|
19
|
+
|
|
20
|
+
## Qu'est-ce que c'est ?
|
|
21
|
+
|
|
22
|
+
Un CLI TypeScript et un serveur MCP qui charge des morceaux de piano depuis [ai-music-sheets](https://github.com/mcp-tool-shop-org/ai-music-sheets), les convertit en MIDI et les joue via [VMPK](https://vmpk.sourceforge.io/) par un port MIDI virtuel. Le moteur pédagogique lance des interjections aux limites de mesure et aux moments clés, permettant à un LLM d'agir comme un professeur de piano en direct avec retour vocal et notifications aside.
|
|
23
|
+
|
|
24
|
+
## Fonctionnalités
|
|
25
|
+
|
|
26
|
+
- **4 modes de lecture** — complet, mesure par mesure, mains séparées, boucle
|
|
27
|
+
- **Contrôle de la vitesse** — 0.5x pour la pratique lente jusqu'à 2x en lecture rapide, cumulable avec le tempo personnalisé
|
|
28
|
+
- **Suivi de progression** — callbacks configurables par pourcentage ou par mesure
|
|
29
|
+
- **7 hooks pédagogiques** — console, silencieux, enregistrement, callback, voix, aside, composition
|
|
30
|
+
- **Retour vocal** — sortie `VoiceDirective` pour l'intégration mcp-voice-soundboard
|
|
31
|
+
- **Interjections aside** — sortie `AsideDirective` pour la boîte de réception mcp-aside
|
|
32
|
+
- **Analyse sécurisée** — les notes invalides sont ignorées avec collecte de `ParseWarning`
|
|
33
|
+
- **7 outils MCP** — exposent le registre, les notes pédagogiques et les recommandations de morceaux aux LLMs
|
|
34
|
+
- **Analyseur de notes** — notation scientifique des hauteurs vers MIDI et inversement
|
|
35
|
+
- **Connecteur mock** — couverture de test complète sans matériel MIDI
|
|
36
|
+
|
|
37
|
+
## Prérequis
|
|
38
|
+
|
|
39
|
+
1. **[loopMIDI](https://www.tobias-erichsen.de/software/loopmidi.html)** — créer un port MIDI virtuel (ex. : "loopMIDI Port")
|
|
40
|
+
2. **[VMPK](https://vmpk.sourceforge.io/)** — configurer l'entrée MIDI sur votre port loopMIDI
|
|
41
|
+
3. **Node.js 18+**
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm install -g @mcptoolshop/pianoai
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Démarrage rapide
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Lister tous les morceaux
|
|
53
|
+
pianai list
|
|
54
|
+
|
|
55
|
+
# Afficher les détails d'un morceau + notes pédagogiques
|
|
56
|
+
pianai info moonlight-sonata-mvt1
|
|
57
|
+
|
|
58
|
+
# Jouer un morceau via VMPK
|
|
59
|
+
pianai play let-it-be
|
|
60
|
+
|
|
61
|
+
# Jouer avec un tempo personnalisé
|
|
62
|
+
pianai play basic-12-bar-blues --tempo 80
|
|
63
|
+
|
|
64
|
+
# Avancer mesure par mesure
|
|
65
|
+
pianai play autumn-leaves --mode measure
|
|
66
|
+
|
|
67
|
+
# Pratique à mi-vitesse
|
|
68
|
+
pianai play moonlight-sonata-mvt1 --speed 0.5
|
|
69
|
+
|
|
70
|
+
# Pratique lente mains séparées
|
|
71
|
+
pianai play dream-on --speed 0.75 --mode hands
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Serveur MCP
|
|
75
|
+
|
|
76
|
+
Le serveur MCP expose 7 outils pour l'intégration LLM :
|
|
77
|
+
|
|
78
|
+
| Outil | Description |
|
|
79
|
+
|-------|-------------|
|
|
80
|
+
| `list_songs` | Parcourir/rechercher des morceaux par genre, difficulté ou requête |
|
|
81
|
+
| `song_info` | Obtenir le langage musical complet, les objectifs pédagogiques, les suggestions de pratique |
|
|
82
|
+
| `registry_stats` | Nombre de morceaux par genre et difficulté |
|
|
83
|
+
| `teaching_note` | Note pédagogique par mesure, doigtés, dynamiques |
|
|
84
|
+
| `suggest_song` | Obtenir une recommandation selon des critères |
|
|
85
|
+
| `list_measures` | Aperçu des mesures avec notes pédagogiques + avertissements d'analyse |
|
|
86
|
+
| `practice_setup` | Suggérer la vitesse, le mode et les réglages vocaux pour un morceau |
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Démarrer le serveur MCP (transport stdio)
|
|
90
|
+
pnpm mcp
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Configuration Claude Desktop
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"mcpServers": {
|
|
98
|
+
"pianai": {
|
|
99
|
+
"command": "pianai-mcp"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Commandes CLI
|
|
106
|
+
|
|
107
|
+
| Commande | Description |
|
|
108
|
+
|----------|-------------|
|
|
109
|
+
| `list [--genre <genre>]` | Lister les morceaux disponibles, avec filtre optionnel par genre |
|
|
110
|
+
| `info <song-id>` | Afficher les détails du morceau : langage musical, notes pédagogiques, structure |
|
|
111
|
+
| `play <song-id> [opts]` | Jouer un morceau via VMPK par MIDI |
|
|
112
|
+
| `stats` | Statistiques du registre (morceaux, genres, mesures) |
|
|
113
|
+
| `ports` | Lister les ports de sortie MIDI disponibles |
|
|
114
|
+
| `help` | Afficher les informations d'utilisation |
|
|
115
|
+
|
|
116
|
+
### Options de lecture
|
|
117
|
+
|
|
118
|
+
| Option | Description |
|
|
119
|
+
|--------|-------------|
|
|
120
|
+
| `--port <name>` | Nom du port MIDI (par défaut : détection automatique de loopMIDI) |
|
|
121
|
+
| `--tempo <bpm>` | Remplacer le tempo par défaut du morceau (10-400 BPM) |
|
|
122
|
+
| `--speed <mult>` | Multiplicateur de vitesse : 0.5 = moitié, 1.0 = normal, 2.0 = double |
|
|
123
|
+
| `--mode <mode>` | Mode de lecture : `full`, `measure`, `hands`, `loop` |
|
|
124
|
+
|
|
125
|
+
## Moteur pédagogique
|
|
126
|
+
|
|
127
|
+
Le moteur pédagogique déclenche des hooks pendant la lecture. 7 implémentations de hooks couvrent tous les cas d'usage :
|
|
128
|
+
|
|
129
|
+
| Hook | Cas d'usage |
|
|
130
|
+
|------|-------------|
|
|
131
|
+
| `createConsoleTeachingHook()` | CLI — affiche les mesures, moments et complétion dans la console |
|
|
132
|
+
| `createSilentTeachingHook()` | Test — aucune opération |
|
|
133
|
+
| `createRecordingTeachingHook()` | Test — enregistre les événements pour les assertions |
|
|
134
|
+
| `createCallbackTeachingHook(cb)` | Personnalisé — redirige vers n'importe quel callback asynchrone |
|
|
135
|
+
| `createVoiceTeachingHook(sink)` | Voix — produit des `VoiceDirective` pour mcp-voice-soundboard |
|
|
136
|
+
| `createAsideTeachingHook(sink)` | Aside — produit des `AsideDirective` pour la boîte de réception mcp-aside |
|
|
137
|
+
| `composeTeachingHooks(...hooks)` | Multi — dispatch vers plusieurs hooks en série |
|
|
138
|
+
|
|
139
|
+
### Retour vocal
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import { createSession, createVoiceTeachingHook } from "@mcptoolshop/pianoai";
|
|
143
|
+
import { getSong } from "ai-music-sheets";
|
|
144
|
+
|
|
145
|
+
const voiceHook = createVoiceTeachingHook(
|
|
146
|
+
async (directive) => {
|
|
147
|
+
// Rediriger vers voice_speak de mcp-voice-soundboard
|
|
148
|
+
console.log(`[Voice] ${directive.text}`);
|
|
149
|
+
},
|
|
150
|
+
{ voice: "narrator", speechSpeed: 0.9 }
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
const session = createSession(getSong("moonlight-sonata-mvt1")!, connector, {
|
|
154
|
+
teachingHook: voiceHook,
|
|
155
|
+
speed: 0.5, // pratique à mi-vitesse
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
await session.play();
|
|
159
|
+
// voiceHook.directives → toutes les instructions vocales émises
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Composition de hooks
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import {
|
|
166
|
+
createVoiceTeachingHook,
|
|
167
|
+
createAsideTeachingHook,
|
|
168
|
+
createRecordingTeachingHook,
|
|
169
|
+
composeTeachingHooks,
|
|
170
|
+
} from "@mcptoolshop/pianoai";
|
|
171
|
+
|
|
172
|
+
// Les trois se déclenchent à chaque événement
|
|
173
|
+
const composed = composeTeachingHooks(
|
|
174
|
+
createVoiceTeachingHook(voiceSink),
|
|
175
|
+
createAsideTeachingHook(asideSink),
|
|
176
|
+
createRecordingTeachingHook()
|
|
177
|
+
);
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## API programmatique
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
import { getSong } from "ai-music-sheets";
|
|
184
|
+
import { createSession, createVmpkConnector } from "@mcptoolshop/pianoai";
|
|
185
|
+
|
|
186
|
+
const connector = createVmpkConnector({ portName: /loop/i });
|
|
187
|
+
await connector.connect();
|
|
188
|
+
|
|
189
|
+
const song = getSong("autumn-leaves")!;
|
|
190
|
+
const session = createSession(song, connector, {
|
|
191
|
+
mode: "measure",
|
|
192
|
+
tempo: 100,
|
|
193
|
+
speed: 0.75, // 75% de la vitesse pour la pratique
|
|
194
|
+
onProgress: (p) => console.log(p.percent), // "25%", "50%", etc.
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
await session.play(); // joue une mesure, puis pause
|
|
198
|
+
session.next(); // avance à la mesure suivante
|
|
199
|
+
await session.play(); // joue la mesure suivante
|
|
200
|
+
session.setSpeed(1.0); // retour à la vitesse normale
|
|
201
|
+
await session.play(); // joue la mesure suivante à pleine vitesse
|
|
202
|
+
session.stop(); // arrêter et réinitialiser
|
|
203
|
+
|
|
204
|
+
// Vérifier les avertissements d'analyse (notes invalides dans les données du morceau)
|
|
205
|
+
if (session.parseWarnings.length > 0) {
|
|
206
|
+
console.warn("Certaines notes n'ont pas pu être analysées :", session.parseWarnings);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
await connector.disconnect();
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Architecture
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
ai-music-sheets (bibliothèque) pianai (runtime)
|
|
216
|
+
┌──────────────────────┐ ┌────────────────────────────────┐
|
|
217
|
+
│ SongEntry (hybride) │────────→│ Note Parser (sûr + strict) │
|
|
218
|
+
│ Registry (recherche) │ │ Session Engine (vitesse+suivi) │
|
|
219
|
+
│ 10 morceaux, 10 genres│ │ Teaching Engine (7 hooks) │
|
|
220
|
+
└──────────────────────┘ │ VMPK Connector (JZZ) │
|
|
221
|
+
│ MCP Server (7 outils) │
|
|
222
|
+
│ CLI (barre de progression+voix)│
|
|
223
|
+
└─────────┬──────────────────────┘
|
|
224
|
+
│ MIDI
|
|
225
|
+
▼
|
|
226
|
+
┌─────────────────┐
|
|
227
|
+
│ loopMIDI → VMPK │
|
|
228
|
+
└─────────────────┘
|
|
229
|
+
|
|
230
|
+
Routage des hooks pédagogiques :
|
|
231
|
+
Session → TeachingHook → VoiceDirective → mcp-voice-soundboard
|
|
232
|
+
→ AsideDirective → boîte de réception mcp-aside
|
|
233
|
+
→ Log console → terminal CLI
|
|
234
|
+
→ Enregistrement → assertions de test
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Tests
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
pnpm test # 121 tests Vitest (parser + session + teaching + voice + aside)
|
|
241
|
+
pnpm smoke # 20 tests d'intégration (pas de MIDI requis)
|
|
242
|
+
pnpm typecheck # tsc --noEmit
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Le connecteur VMPK mock (`createMockVmpkConnector`) enregistre tous les événements MIDI sans matériel, permettant une couverture de test complète. Les fonctions d'analyse sécurisée (`safeParseMeasure`) collectent des objets `ParseWarning` au lieu de lever des exceptions, afin que la lecture continue normalement si un morceau contient des notes malformées.
|
|
246
|
+
|
|
247
|
+
## Liens connexes
|
|
248
|
+
|
|
249
|
+
- **[ai-music-sheets](https://github.com/mcp-tool-shop-org/ai-music-sheets)** — La bibliothèque de morceaux : 10 genres, format hybride (métadonnées + langage musical + mesures prêtes pour le code)
|
|
250
|
+
|
|
251
|
+
## Licence
|
|
252
|
+
|
|
253
|
+
MIT
|