docs: refresh usage documentation

This commit is contained in:
thibaud-lclr 2026-05-02 12:07:34 +02:00
parent 17b1b99686
commit afe4c681a1
10 changed files with 169 additions and 74 deletions

View file

@ -1,54 +1,90 @@
# mcp-framework
`mcp-framework` est une bibliothèque Go pour construire des binaires MCP robustes, sans imposer un runtime lourd.
`mcp-framework` est une bibliothèque Go et un petit CLI pour construire des
binaires MCP avec une base commune : CLI, configuration locale, secrets,
manifeste `mcp.toml`, diagnostic et auto-update.
## Le principal à savoir
## Installation
- Le framework fournit des briques réutilisables : config locale, secrets, résolution CLI, manifeste projet, et auto-update.
- Il peut être utilisé de manière modulaire (package par package) ou avec un bootstrap CLI prêt à l'emploi.
- Il inclut un générateur de squelette (`mcp-framework scaffold init`) pour démarrer un nouveau binaire MCP rapidement.
- Il peut générer la glue Go dérivée d'un manifeste racine (`mcp-framework generate`).
- Toute la documentation détaillée est maintenant organisée dans `docs/` par grandes parties.
## Démarrage rapide
Installer le framework dans un projet Go existant :
Dans un projet Go :
```bash
go get gitea.lclr.dev/AI/mcp-framework
```
Initialiser un nouveau projet MCP depuis un dossier vide :
Pour utiliser le CLI :
```bash
go install gitea.lclr.dev/AI/mcp-framework/cmd/mcp-framework@latest
```
## Créer un projet MCP
```bash
mcp-framework scaffold init \
--target ./my-mcp \
--module example.com/my-mcp \
--binary my-mcp \
--profiles dev,prod
```
Puis dans le projet généré :
```bash
cd my-mcp
go mod tidy
go run ./cmd/my-mcp help
```
Le scaffold crée une arborescence prête à adapter :
```text
cmd/<binary>/main.go
internal/app/app.go
mcp.toml
install.sh
README.md
```
## Générer la glue depuis `mcp.toml`
Dans un projet qui possède un `mcp.toml` à la racine :
```bash
mcp-framework generate
```
La commande génère un package `mcpgen/` avec un loader de manifeste embarqué,
des helpers de métadonnées, update, secret store, et des helpers de config si
`[[config.fields]]` est déclaré.
En CI :
```bash
mcp-framework generate --check
```
## Utiliser les packages
Les packages peuvent être utilisés séparément :
- `bootstrap` : CLI commune (`setup`, `login`, `mcp`, `config`, `update`, `version`).
- `cli` : résolution de profil, setup interactif, résolution `flag/env/config/secret`, doctor.
- `config` : stockage JSON versionné dans le répertoire de config utilisateur.
- `manifest` : lecture de `mcp.toml` et fallback embarqué.
- `secretstore` : keyring natif, environnement ou Bitwarden CLI.
- `update` : téléchargement et remplacement du binaire depuis une release.
- `scaffold` : génération d'un squelette de projet.
- `generate` : génération de code Go depuis `mcp.toml`.
## Documentation
- Vue d'ensemble : [docs/README.md](docs/README.md)
- Installation et usage type : [docs/getting-started.md](docs/getting-started.md)
- Packages : [docs/packages.md](docs/packages.md)
- Bootstrap CLI : [docs/bootstrap-cli.md](docs/bootstrap-cli.md)
- Manifeste `mcp.toml` : [docs/manifest.md](docs/manifest.md)
- Génération depuis `mcp.toml` : [docs/generate.md](docs/generate.md)
- Scaffolding : [docs/scaffolding.md](docs/scaffolding.md)
- Config JSON : [docs/config.md](docs/config.md)
- Secrets : [docs/secrets.md](docs/secrets.md)
- Helpers CLI : [docs/cli-helpers.md](docs/cli-helpers.md)
- Auto-update : [docs/auto-update.md](docs/auto-update.md)
- Exemple minimal : [docs/minimal-example.md](docs/minimal-example.md)
- Limites actuelles : [docs/limitations.md](docs/limitations.md)
- [Vue d'ensemble](docs/README.md)
- [Installation et utilisation](docs/getting-started.md)
- [Packages](docs/packages.md)
- [Bootstrap CLI](docs/bootstrap-cli.md)
- [Manifeste `mcp.toml`](docs/manifest.md)
- [Génération depuis `mcp.toml`](docs/generate.md)
- [Scaffolding](docs/scaffolding.md)
- [Config JSON](docs/config.md)
- [Secrets](docs/secrets.md)
- [Helpers CLI](docs/cli-helpers.md)
- [Auto-update](docs/auto-update.md)
- [Exemple minimal](docs/minimal-example.md)
- [Limites](docs/limitations.md)

View file

@ -1,6 +1,8 @@
# Documentation mcp-framework
Cette documentation est organisée par grandes parties pour séparer la vue d'ensemble des détails d'implémentation.
`mcp-framework` fournit des packages Go et un CLI pour construire des binaires
MCP avec une base commune : bootstrap CLI, configuration, secrets, manifeste,
génération de code, scaffold, diagnostic et auto-update.
## Navigation
@ -15,4 +17,4 @@ Cette documentation est organisée par grandes parties pour séparer la vue d'en
- [Helpers CLI](cli-helpers.md)
- [Auto-update](auto-update.md)
- [Exemple minimal](minimal-example.md)
- [Limites actuelles](limitations.md)
- [Limites](limitations.md)

View file

@ -8,7 +8,7 @@ Le parseur de release supporte :
- format `assets.links` (Gitea/GitLab)
- format `assets[]` avec `browser_download_url` (GitHub et Gitea API)
Le format attendu pour la réponse `latest release` est actuellement :
Le format attendu pour la réponse `latest release` est :
```json
{

View file

@ -5,7 +5,7 @@ racine d'un projet existant.
## Usage
Depuis la racine du projet consommateur :
Depuis la racine du projet Go :
```bash
mcp-framework generate
@ -106,22 +106,45 @@ Exemple CI :
mcp-framework generate --check
```
## Migration d'un wrapper manuel
## Utilisation dans l'application
Pour remplacer un wrapper local du type `internal/manifest` :
Importer le package généré depuis le module de l'application :
1. Déplacer le manifeste projet vers `mcp.toml` à la racine.
2. Lancer `mcp-framework generate`.
3. Remplacer les imports du wrapper local par le package généré, par exemple
`example.com/my-mcp/mcpgen`.
4. Remplacer les appels `manifest.Load(...)` du wrapper par
`mcpgen.LoadManifest(...)`.
5. Remplacer les reconstructions locales d'options update par
`mcpgen.UpdateOptions(...)` ou `mcpgen.RunUpdate(...)`.
6. Remplacer les wrappers secret store qui ne font que brancher le loader par
`mcpgen.OpenSecretStore`, `mcpgen.DescribeSecretRuntime` et
`mcpgen.PreflightSecretStore`.
7. Supprimer l'ancien wrapper manuel.
```go
import "example.com/my-mcp/mcpgen"
```
Charger le manifeste :
```go
file, source, err := mcpgen.LoadManifest(".")
if err != nil {
return err
}
_ = file
_ = source
```
Construire les options d'update :
```go
opts, err := mcpgen.UpdateOptions(version, os.Stdout)
if err != nil {
return err
}
```
Ouvrir le secret store configuré par le manifeste :
```go
store, err := mcpgen.OpenSecretStore(mcpgen.SecretStoreOptions{
LookupEnv: os.LookupEnv,
})
if err != nil {
return err
}
_ = store
```
Après génération, un simple `go build ./...` suffit. La compilation ne dépend
pas de la commande `mcp-framework`.

View file

@ -29,12 +29,20 @@ go run ./cmd/my-mcp help
## Utilisation type
Le flux typique côté application est :
Un flux complet côté application :
1. Déclarer les sous-commandes communes via `bootstrap` (optionnel).
2. Résoudre le profil actif avec `cli`.
3. Charger la config versionnée avec `config`.
4. Lire les secrets avec `secretstore`.
5. Charger le manifest runtime avec `manifest` (`mcp.toml` local, ou fallback embarqué).
6. Exécuter l'auto-update avec `update` si nécessaire.
7. Exécuter `doctor` pour diagnostiquer la configuration locale et brancher des checks métier.
1. Déclarer `mcp.toml` à la racine du module.
2. Lancer `mcp-framework generate` pour produire le package `mcpgen`.
3. Déclarer les sous-commandes communes via `bootstrap` si l'application utilise le bootstrap CLI.
4. Résoudre le profil actif avec `cli`.
5. Charger la config versionnée avec `config`.
6. Lire les secrets avec `secretstore` ou `mcpgen.OpenSecretStore`.
7. Charger le manifest runtime avec `mcpgen.LoadManifest`.
8. Exécuter l'auto-update avec `mcpgen.RunUpdate` ou `update.Run`.
9. Exécuter `doctor` pour diagnostiquer la configuration locale et brancher des checks métier.
Pour vérifier que le code généré est synchronisé avec le manifeste :
```bash
mcp-framework generate --check
```

View file

@ -1,3 +1,3 @@
# Limites actuelles
# Limites
- l'auto-update reste volontairement simple et ne supporte pas encore de scripts externes

View file

@ -1,38 +1,63 @@
# Exemple minimal
Cet exemple suppose qu'un `mcp.toml` existe à la racine du module et que le
package généré est à jour :
```bash
mcp-framework generate
```
Exemple de runner Go :
```go
package main
import (
"context"
"fmt"
"os"
"example.com/my-mcp/mcpgen"
"gitea.lclr.dev/AI/mcp-framework/config"
"gitea.lclr.dev/AI/mcp-framework/update"
)
var version = "dev"
type Profile struct {
BaseURL string `json:"base_url"`
}
var embeddedManifest = `...` // fallback utilisé si aucun mcp.toml runtime n'est trouvé
func main() {
if err := run(context.Background()); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func run(ctx context.Context, flagProfile string) error {
cfgStore := config.NewStore[Profile]("my-mcp")
func run(ctx context.Context) error {
cfgStore := config.NewStore[Profile](mcpgen.BinaryName)
cfg, _, err := cfgStore.LoadDefault()
if err != nil {
return err
}
profileName := cli.ResolveProfileName(flagProfile, os.Getenv("MY_MCP_PROFILE"), cfg.CurrentProfile)
profile := cfg.Profiles[profileName]
manifestFile, _, err := manifest.LoadDefaultOrEmbedded(".", embeddedManifest)
_, source, err := mcpgen.LoadManifest(".")
if err != nil {
return err
}
fmt.Println("manifest:", source)
err = update.Run(ctx, update.Options{
CurrentVersion: version,
BinaryName: "my-mcp",
ReleaseSource: manifestFile.Update.ReleaseSource(),
})
updateOptions, err := mcpgen.UpdateOptions(version, os.Stdout)
if err != nil {
return err
}
if err := update.Run(ctx, updateOptions); err != nil {
return err
}
_ = profile
_ = cfg
return nil
}
```

View file

@ -4,6 +4,7 @@
- `cli` : helpers pour résoudre un profil, valider une URL, demander des valeurs à l'utilisateur et exécuter un `doctor`.
- `config` : lecture/écriture atomique d'une config JSON versionnée dans `os.UserConfigDir()`.
- `manifest` : lecture de `mcp.toml` à la racine du projet, fallback embarqué pour le runtime, conversion vers `update.ReleaseSource` et exposition de métadonnées pour `bootstrap`/scaffolding.
- `generate` : génération de code Go depuis `mcp.toml` (`mcpgen/manifest.go`, metadata, update, secret store, config fields).
- `scaffold` : génération d'un squelette de projet MCP (arborescence, `main.go`, `mcp.toml`, `install.sh` wizard, wiring de base et README de démarrage).
- `secretstore` : lecture/écriture de secrets dans le wallet natif, avec helpers runtime `OpenFromManifest`, `DescribeRuntime`, `PreflightFromManifest` et formatage homogène via `FormatBackendStatus`.
- `update` : téléchargement et remplacement du binaire courant depuis un endpoint de release.

View file

@ -3,7 +3,7 @@
Le package `scaffold` génère un point de départ cohérent pour un nouveau binaire MCP :
- arborescence recommandée (`cmd/<binary>/main.go`, `internal/app/app.go`, `mcp.toml`)
- script `install.sh` prêt à publier (`curl .../install.sh | bash`) avec wizard TUI (setup, apply Claude/Codex, JSON MCP)
- script `install.sh` prêt à publier (`curl .../install.sh | bash`) avec wizard TUI, setup local et export JSON MCP
- wiring initial `bootstrap + config + secretstore + update`
- `README.md` de démarrage

View file

@ -56,7 +56,7 @@ Pour imposer KWallet sur Linux :
```go
store, err := secretstore.Open(secretstore.Options{
ServiceName: "email-mcp",
ServiceName: "my-mcp",
BackendPolicy: secretstore.BackendKWalletOnly,
})
```
@ -65,7 +65,7 @@ Pour imposer Bitwarden via son CLI :
```go
store, err := secretstore.Open(secretstore.Options{
ServiceName: "email-mcp",
ServiceName: "my-mcp",
BackendPolicy: secretstore.BackendBitwardenCLI,
// Optionnel si `bw` n'est pas dans le PATH :
// BitwardenCommand: "/usr/local/bin/bw",
@ -96,7 +96,7 @@ et le persister localement (fichier `0600` sous le répertoire de config utilisa
```go
session, err := secretstore.LoginBitwarden(secretstore.BitwardenLoginOptions{
ServiceName: "email-mcp",
ServiceName: "my-mcp",
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
@ -111,7 +111,7 @@ Pour réinjecter automatiquement une session persistée dans l'environnement cou
```go
loaded, err := secretstore.EnsureBitwardenSessionEnv(secretstore.BitwardenSessionOptions{
ServiceName: "email-mcp",
ServiceName: "my-mcp",
})
if err != nil {
return err