2026-05-02 09:46:47 +00:00
|
|
|
# Génération depuis `mcp.toml`
|
|
|
|
|
|
|
|
|
|
La commande `mcp-framework generate` génère la glue Go dérivée du manifeste
|
2026-05-02 09:57:44 +00:00
|
|
|
racine d'un projet existant.
|
2026-05-02 09:46:47 +00:00
|
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
|
|
|
|
Depuis la racine du projet consommateur :
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
mcp-framework generate
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
La commande lit `./mcp.toml`, valide son contenu avec le package `manifest`, et
|
|
|
|
|
génère :
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
mcpgen/
|
|
|
|
|
manifest.go
|
2026-05-02 09:57:44 +00:00
|
|
|
metadata.go
|
|
|
|
|
update.go
|
|
|
|
|
secretstore.go
|
2026-05-02 10:02:23 +00:00
|
|
|
config.go # si [[config.fields]] existe
|
2026-05-02 09:46:47 +00:00
|
|
|
```
|
|
|
|
|
|
2026-05-02 09:57:44 +00:00
|
|
|
Le package généré expose le loader de manifeste :
|
2026-05-02 09:46:47 +00:00
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
func LoadManifest(startDir string) (manifest.File, string, error)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Cette fonction appelle `manifest.LoadDefaultOrEmbedded`. En développement, un
|
|
|
|
|
`mcp.toml` présent sur disque reste prioritaire. Pour un binaire copié seul,
|
|
|
|
|
elle utilise le contenu du manifeste embarqué au moment de la génération.
|
|
|
|
|
|
2026-05-02 09:57:44 +00:00
|
|
|
Il expose aussi des helpers dérivés du manifeste :
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
const BinaryName = "my-mcp"
|
|
|
|
|
const DefaultDescription = "..."
|
|
|
|
|
const DocsURL = "..."
|
|
|
|
|
|
|
|
|
|
func BootstrapInfo(startDir string) (manifest.BootstrapMetadata, string, error)
|
|
|
|
|
func ScaffoldInfo(startDir string) (manifest.ScaffoldMetadata, string, error)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Pour l'auto-update :
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
func UpdateOptions(version string, stdout io.Writer) (update.Options, error)
|
|
|
|
|
func UpdateOptionsFrom(startDir string, version string, stdout io.Writer) (update.Options, error)
|
|
|
|
|
func RunUpdate(ctx context.Context, args []string, version string, stdout io.Writer) error
|
|
|
|
|
func RunUpdateFrom(ctx context.Context, args []string, startDir string, version string, stdout io.Writer) error
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`RunUpdate` parse les flags de la commande `update`, refuse les arguments
|
|
|
|
|
positionnels, charge le manifeste via `LoadManifest`, puis appelle
|
|
|
|
|
`update.Run`.
|
|
|
|
|
|
|
|
|
|
Pour les secrets :
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
type SecretStoreOptions struct {
|
|
|
|
|
ServiceName string
|
|
|
|
|
LookupEnv func(string) (string, bool)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func OpenSecretStore(options SecretStoreOptions) (secretstore.Store, error)
|
|
|
|
|
func DescribeSecretRuntime(options SecretStoreOptions) (secretstore.RuntimeDescription, error)
|
|
|
|
|
func PreflightSecretStore(options SecretStoreOptions) (secretstore.PreflightReport, error)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`SecretStoreOptions` contient aussi les options techniques du package
|
|
|
|
|
`secretstore` (`KWalletAppID`, `KWalletFolder`, `BitwardenCommand`,
|
|
|
|
|
`BitwardenDebug`, `Shell`, `ExecutableResolver`). Si `ServiceName` est vide,
|
|
|
|
|
le nom du binaire déclaré dans le manifeste est utilisé.
|
|
|
|
|
|
2026-05-02 10:02:23 +00:00
|
|
|
Si le manifest déclare `[[config.fields]]`, le package généré expose aussi :
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
type ConfigFlags struct { /* champs internes */ }
|
|
|
|
|
|
|
|
|
|
func AddConfigFlags(fs *flag.FlagSet) ConfigFlags
|
|
|
|
|
func ConfigFlagValues(flags ConfigFlags) map[string]string
|
|
|
|
|
func ResolveFieldSpecs(profile string) []cli.FieldSpec
|
|
|
|
|
func SetupFields(existing map[string]string) []cli.SetupField
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`AddConfigFlags` branche les flags déclarés sur le `FlagSet` du projet.
|
|
|
|
|
`ConfigFlagValues` retourne uniquement les valeurs de flags non vides.
|
|
|
|
|
`ResolveFieldSpecs` génère les specs à passer à `cli.ResolveFields`, en
|
|
|
|
|
remplaçant `{profile}` dans les templates de secrets. `SetupFields` génère les
|
|
|
|
|
champs attendus par `cli.RunSetup`; le paramètre `existing` permet de fournir
|
|
|
|
|
les secrets déjà stockés par nom de champ.
|
|
|
|
|
|
2026-05-02 09:46:47 +00:00
|
|
|
## Flags
|
|
|
|
|
|
|
|
|
|
- `--manifest` : chemin du `mcp.toml` à lire. Par défaut, `./mcp.toml`.
|
|
|
|
|
- `--package-dir` : répertoire du package généré. Par défaut, `mcpgen`.
|
|
|
|
|
- `--package-name` : nom du package Go généré. Par défaut, dérivé du dossier.
|
|
|
|
|
- `--check` : mode CI, échoue si les fichiers générés sont absents ou obsolètes.
|
|
|
|
|
|
|
|
|
|
Exemple CI :
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
mcp-framework generate --check
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Migration d'un wrapper manuel
|
|
|
|
|
|
|
|
|
|
Pour remplacer un wrapper local du type `internal/manifest` :
|
|
|
|
|
|
|
|
|
|
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(...)`.
|
2026-05-02 09:57:44 +00:00
|
|
|
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.
|
2026-05-02 09:46:47 +00:00
|
|
|
|
|
|
|
|
Après génération, un simple `go build ./...` suffit. La compilation ne dépend
|
|
|
|
|
pas de la commande `mcp-framework`.
|