docs: refresh usage documentation
This commit is contained in:
parent
17b1b99686
commit
afe4c681a1
10 changed files with 169 additions and 74 deletions
94
README.md
94
README.md
|
|
@ -1,54 +1,90 @@
|
||||||
# mcp-framework
|
# 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.
|
Dans un projet Go :
|
||||||
- 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 :
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go get gitea.lclr.dev/AI/mcp-framework
|
go get gitea.lclr.dev/AI/mcp-framework
|
||||||
```
|
```
|
||||||
|
|
||||||
Initialiser un nouveau projet MCP depuis un dossier vide :
|
Pour utiliser le CLI :
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go install gitea.lclr.dev/AI/mcp-framework/cmd/mcp-framework@latest
|
go install gitea.lclr.dev/AI/mcp-framework/cmd/mcp-framework@latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## Créer un projet MCP
|
||||||
|
|
||||||
|
```bash
|
||||||
mcp-framework scaffold init \
|
mcp-framework scaffold init \
|
||||||
--target ./my-mcp \
|
--target ./my-mcp \
|
||||||
--module example.com/my-mcp \
|
--module example.com/my-mcp \
|
||||||
--binary my-mcp \
|
--binary my-mcp \
|
||||||
--profiles dev,prod
|
--profiles dev,prod
|
||||||
```
|
|
||||||
|
|
||||||
Puis dans le projet généré :
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd my-mcp
|
cd my-mcp
|
||||||
go mod tidy
|
go mod tidy
|
||||||
go run ./cmd/my-mcp help
|
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
|
## Documentation
|
||||||
|
|
||||||
- Vue d'ensemble : [docs/README.md](docs/README.md)
|
- [Vue d'ensemble](docs/README.md)
|
||||||
- Installation et usage type : [docs/getting-started.md](docs/getting-started.md)
|
- [Installation et utilisation](docs/getting-started.md)
|
||||||
- Packages : [docs/packages.md](docs/packages.md)
|
- [Packages](docs/packages.md)
|
||||||
- Bootstrap CLI : [docs/bootstrap-cli.md](docs/bootstrap-cli.md)
|
- [Bootstrap CLI](docs/bootstrap-cli.md)
|
||||||
- Manifeste `mcp.toml` : [docs/manifest.md](docs/manifest.md)
|
- [Manifeste `mcp.toml`](docs/manifest.md)
|
||||||
- Génération depuis `mcp.toml` : [docs/generate.md](docs/generate.md)
|
- [Génération depuis `mcp.toml`](docs/generate.md)
|
||||||
- Scaffolding : [docs/scaffolding.md](docs/scaffolding.md)
|
- [Scaffolding](docs/scaffolding.md)
|
||||||
- Config JSON : [docs/config.md](docs/config.md)
|
- [Config JSON](docs/config.md)
|
||||||
- Secrets : [docs/secrets.md](docs/secrets.md)
|
- [Secrets](docs/secrets.md)
|
||||||
- Helpers CLI : [docs/cli-helpers.md](docs/cli-helpers.md)
|
- [Helpers CLI](docs/cli-helpers.md)
|
||||||
- Auto-update : [docs/auto-update.md](docs/auto-update.md)
|
- [Auto-update](docs/auto-update.md)
|
||||||
- Exemple minimal : [docs/minimal-example.md](docs/minimal-example.md)
|
- [Exemple minimal](docs/minimal-example.md)
|
||||||
- Limites actuelles : [docs/limitations.md](docs/limitations.md)
|
- [Limites](docs/limitations.md)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
# Documentation mcp-framework
|
# 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
|
## 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)
|
- [Helpers CLI](cli-helpers.md)
|
||||||
- [Auto-update](auto-update.md)
|
- [Auto-update](auto-update.md)
|
||||||
- [Exemple minimal](minimal-example.md)
|
- [Exemple minimal](minimal-example.md)
|
||||||
- [Limites actuelles](limitations.md)
|
- [Limites](limitations.md)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ Le parseur de release supporte :
|
||||||
- format `assets.links` (Gitea/GitLab)
|
- format `assets.links` (Gitea/GitLab)
|
||||||
- format `assets[]` avec `browser_download_url` (GitHub et Gitea API)
|
- 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
|
```json
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ racine d'un projet existant.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Depuis la racine du projet consommateur :
|
Depuis la racine du projet Go :
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mcp-framework generate
|
mcp-framework generate
|
||||||
|
|
@ -106,22 +106,45 @@ Exemple CI :
|
||||||
mcp-framework generate --check
|
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.
|
```go
|
||||||
2. Lancer `mcp-framework generate`.
|
import "example.com/my-mcp/mcpgen"
|
||||||
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
|
Charger le manifeste :
|
||||||
`mcpgen.LoadManifest(...)`.
|
|
||||||
5. Remplacer les reconstructions locales d'options update par
|
```go
|
||||||
`mcpgen.UpdateOptions(...)` ou `mcpgen.RunUpdate(...)`.
|
file, source, err := mcpgen.LoadManifest(".")
|
||||||
6. Remplacer les wrappers secret store qui ne font que brancher le loader par
|
if err != nil {
|
||||||
`mcpgen.OpenSecretStore`, `mcpgen.DescribeSecretRuntime` et
|
return err
|
||||||
`mcpgen.PreflightSecretStore`.
|
}
|
||||||
7. Supprimer l'ancien wrapper manuel.
|
_ = 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
|
Après génération, un simple `go build ./...` suffit. La compilation ne dépend
|
||||||
pas de la commande `mcp-framework`.
|
pas de la commande `mcp-framework`.
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,20 @@ go run ./cmd/my-mcp help
|
||||||
|
|
||||||
## Utilisation type
|
## 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).
|
1. Déclarer `mcp.toml` à la racine du module.
|
||||||
2. Résoudre le profil actif avec `cli`.
|
2. Lancer `mcp-framework generate` pour produire le package `mcpgen`.
|
||||||
3. Charger la config versionnée avec `config`.
|
3. Déclarer les sous-commandes communes via `bootstrap` si l'application utilise le bootstrap CLI.
|
||||||
4. Lire les secrets avec `secretstore`.
|
4. Résoudre le profil actif avec `cli`.
|
||||||
5. Charger le manifest runtime avec `manifest` (`mcp.toml` local, ou fallback embarqué).
|
5. Charger la config versionnée avec `config`.
|
||||||
6. Exécuter l'auto-update avec `update` si nécessaire.
|
6. Lire les secrets avec `secretstore` ou `mcpgen.OpenSecretStore`.
|
||||||
7. Exécuter `doctor` pour diagnostiquer la configuration locale et brancher des checks métier.
|
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
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
# Limites actuelles
|
# Limites
|
||||||
|
|
||||||
- l'auto-update reste volontairement simple et ne supporte pas encore de scripts externes
|
- l'auto-update reste volontairement simple et ne supporte pas encore de scripts externes
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,63 @@
|
||||||
# Exemple minimal
|
# 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
|
```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 {
|
type Profile struct {
|
||||||
BaseURL string `json:"base_url"`
|
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 {
|
func run(ctx context.Context) error {
|
||||||
cfgStore := config.NewStore[Profile]("my-mcp")
|
cfgStore := config.NewStore[Profile](mcpgen.BinaryName)
|
||||||
|
|
||||||
cfg, _, err := cfgStore.LoadDefault()
|
cfg, _, err := cfgStore.LoadDefault()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
profileName := cli.ResolveProfileName(flagProfile, os.Getenv("MY_MCP_PROFILE"), cfg.CurrentProfile)
|
_, source, err := mcpgen.LoadManifest(".")
|
||||||
profile := cfg.Profiles[profileName]
|
|
||||||
|
|
||||||
manifestFile, _, err := manifest.LoadDefaultOrEmbedded(".", embeddedManifest)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
fmt.Println("manifest:", source)
|
||||||
|
|
||||||
err = update.Run(ctx, update.Options{
|
updateOptions, err := mcpgen.UpdateOptions(version, os.Stdout)
|
||||||
CurrentVersion: version,
|
|
||||||
BinaryName: "my-mcp",
|
|
||||||
ReleaseSource: manifestFile.Update.ReleaseSource(),
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := update.Run(ctx, updateOptions); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
_ = profile
|
_ = cfg
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
- `cli` : helpers pour résoudre un profil, valider une URL, demander des valeurs à l'utilisateur et exécuter un `doctor`.
|
- `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()`.
|
- `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.
|
- `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).
|
- `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`.
|
- `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.
|
- `update` : téléchargement et remplacement du binaire courant depuis un endpoint de release.
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
Le package `scaffold` génère un point de départ cohérent pour un nouveau binaire MCP :
|
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`)
|
- 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`
|
- wiring initial `bootstrap + config + secretstore + update`
|
||||||
- `README.md` de démarrage
|
- `README.md` de démarrage
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ Pour imposer KWallet sur Linux :
|
||||||
|
|
||||||
```go
|
```go
|
||||||
store, err := secretstore.Open(secretstore.Options{
|
store, err := secretstore.Open(secretstore.Options{
|
||||||
ServiceName: "email-mcp",
|
ServiceName: "my-mcp",
|
||||||
BackendPolicy: secretstore.BackendKWalletOnly,
|
BackendPolicy: secretstore.BackendKWalletOnly,
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
@ -65,7 +65,7 @@ Pour imposer Bitwarden via son CLI :
|
||||||
|
|
||||||
```go
|
```go
|
||||||
store, err := secretstore.Open(secretstore.Options{
|
store, err := secretstore.Open(secretstore.Options{
|
||||||
ServiceName: "email-mcp",
|
ServiceName: "my-mcp",
|
||||||
BackendPolicy: secretstore.BackendBitwardenCLI,
|
BackendPolicy: secretstore.BackendBitwardenCLI,
|
||||||
// Optionnel si `bw` n'est pas dans le PATH :
|
// Optionnel si `bw` n'est pas dans le PATH :
|
||||||
// BitwardenCommand: "/usr/local/bin/bw",
|
// BitwardenCommand: "/usr/local/bin/bw",
|
||||||
|
|
@ -96,7 +96,7 @@ et le persister localement (fichier `0600` sous le répertoire de config utilisa
|
||||||
|
|
||||||
```go
|
```go
|
||||||
session, err := secretstore.LoginBitwarden(secretstore.BitwardenLoginOptions{
|
session, err := secretstore.LoginBitwarden(secretstore.BitwardenLoginOptions{
|
||||||
ServiceName: "email-mcp",
|
ServiceName: "my-mcp",
|
||||||
Stdin: os.Stdin,
|
Stdin: os.Stdin,
|
||||||
Stdout: os.Stdout,
|
Stdout: os.Stdout,
|
||||||
Stderr: os.Stderr,
|
Stderr: os.Stderr,
|
||||||
|
|
@ -111,7 +111,7 @@ Pour réinjecter automatiquement une session persistée dans l'environnement cou
|
||||||
|
|
||||||
```go
|
```go
|
||||||
loaded, err := secretstore.EnsureBitwardenSessionEnv(secretstore.BitwardenSessionOptions{
|
loaded, err := secretstore.EnsureBitwardenSessionEnv(secretstore.BitwardenSessionOptions{
|
||||||
ServiceName: "email-mcp",
|
ServiceName: "my-mcp",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue