mcpserver

package
v0.0.0-...-25e72f8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 3, 2026 License: AGPL-3.0 Imports: 36 Imported by: 0

Documentation

Overview

Package mcpserver serves infraharvest to AI agents over the Model Context Protocol. Its tools run the infraharvest binary itself, so they behave exactly like the command line: discover lists resources into a selection file, import generates Terraform configuration from one once a person confirms it, report reads an import's report or the drift report, drift reports what changed in the cloud since the roots were applied, and drift_accept takes the cloud's values into the code. The drift tools run Terraform on the roots, which runs their providers with the server's credentials: they refuse roots that use other providers than infraharvest generates roots with, and run once a person confirms it. Each provider's parameters are declared on the tools' inputs, with the flag each sets, and a parameter for another provider is rejected. An import is checked as the command line's --check checks it before the person is asked, so a run the command would refuse is never put to them. Nothing is ever applied, the state is never changed, and the cloud is only read.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckDefaultRoot

func CheckDefaultRoot(dir, home string) error

CheckDefaultRoot rejects dir as the root a server defaults to, the working directory, when it is the root of a filesystem or home, the user's home directory: some hosts start servers there, and the tools could then read and write files anywhere on the machine, or anywhere in the home directory. Naming it with --root still allows it.

func New

func New(version, root string, run Runner, check Checker, compiled Providers) *mcp.Server

New returns the server, which runs infraharvest with run, and checks an import with check before the user is asked to confirm it; compiled are the providers infraharvest has. The tools read and write files under root only: selection files, output directories, reports and drift decisions files.

Types

type Checker

type Checker func(ctx context.Context, args []string) error

Checker checks infraharvest's args as the command they name would before running, without running it, and returns the error the command would fail with.

type DiscoverInput

type DiscoverInput struct {
	Scope
	Selection string `json:"selection" jsonschema:"the selection file to write, such as selection.yaml"`
	// Config is --config, checked as the other paths are.
	Config string `` /* 157-byte string literal not displayed */
}

DiscoverInput is the discover tool's input.

type DriftAcceptInput

type DriftAcceptInput struct {
	DriftInput
	// Rules are accept and keep rules, in order, each as a line of drift's
	// --rules file takes it (see driftpolicy.ParseRuleLine): they become
	// --accept and --keep flags in that order, so that the last that
	// matches a change decides, as on the command line.
	Rules []string `` /* 402-byte string literal not displayed */
	// Decisions is --decisions.
	Decisions string `` /* 209-byte string literal not displayed */
	// WriteDecisions is --write-decisions.
	WriteDecisions bool `` /* 318-byte string literal not displayed */
}

DriftAcceptInput is the drift_accept tool's input.

type DriftInput

type DriftInput struct {
	Out    string `json:"out" jsonschema:"the output directory of an import, whose roots were applied"`
	Engine string `json:"engine,omitempty" flag:"engine" jsonschema:"terraform (the default) or tofu"`
	// Config is --config, checked as the other paths are.
	Config string `` /* 261-byte string literal not displayed */
	// Roots are --root patterns.
	Roots []string `` /* 211-byte string literal not displayed */
	// Parallel is --parallel, 0 for its default.
	Parallel int `` /* 127-byte string literal not displayed */
	// Environments are --environment names.
	Environments []string `` /* 320-byte string literal not displayed */
	// Catalogue is --catalogue.
	Catalogue string `` /* 196-byte string literal not displayed */
	// EngineTimeout is --engine-timeout, "" for its default.
	EngineTimeout string `` /* 221-byte string literal not displayed */
	// ForceUnlock is --force-unlock.
	ForceUnlock bool `` /* 187-byte string literal not displayed */
}

DriftInput is the drift tool's input.

type DriftResult

type DriftResult struct {
	ExitCode int `json:"exit_code"`
	// DriftFound says whether changes are left that the next apply
	// reverts, or that can't be assessed.
	DriftFound bool `json:"drift_found"`
	// Totals count the roots, and the changes by what became of them:
	// written into the code, kept, needing a hand edit (manual), and so
	// on.
	Totals report.DriftTotals `json:"totals"`
	// StaleDecisions counts the changes whose entry in the decisions file
	// was decided for other values, so that it wasn't applied.
	StaleDecisions int `json:"stale_decisions,omitempty"`
	// FailedRoots are the roots that couldn't be checked, with why.
	FailedRoots []string `json:"failed_roots,omitempty"`
	// Changes are the first changes, up to maxDriftChanges; MoreChanges
	// counts those left out, which the report has.
	Changes     []report.DriftChange `json:"changes"`
	MoreChanges int                  `json:"more_changes,omitempty"`
	// Report is drift.md; drift.json is beside it.
	Report string `json:"report"`
	// Decisions is the decisions file write_decisions wrote.
	Decisions string `json:"decisions,omitempty"`
}

DriftResult is what a drift tool found and did.

type ImportInput

type ImportInput struct {
	Scope
	Selection string `json:"selection" jsonschema:"the selection file to import, from discover"`
	Out       string `json:"out" jsonschema:"the directory to write the configuration and report to"`
	// Config is --config, checked as the other paths are.
	Config string `` /* 203-byte string literal not displayed */
	Engine string `json:"engine,omitempty" flag:"engine" jsonschema:"terraform (the default) or tofu"`
	// Incremental adds to the roots Out already has (--incremental).
	Incremental bool `` /* 248-byte string literal not displayed */
	// Regenerate generates the roots Out already has again (--regenerate).
	Regenerate bool `` /* 370-byte string literal not displayed */
}

ImportInput is the import tool's input.

type ImportResult

type ImportResult struct {
	ExitCode int                  `json:"exit_code"`
	Totals   report.CoverageTotal `json:"totals"`
	// FailedChecks are the verification checks that failed, by directory.
	FailedChecks []string `json:"failed_checks,omitempty"`
	// SkippedChecks are the verification checks that couldn't run, such
	// as the scanners check with no scanner installed.
	SkippedChecks []string `json:"skipped_checks,omitempty"`
	Failures      []string `json:"failures,omitempty"`
	Report        string   `json:"report"`
	// NotInCloud are the resources the roots have that an incremental
	// import didn't find in the cloud, where it listed everything of their
	// type: deleted since, for the user to remove from the roots or create
	// again.
	NotInCloud []report.NotInCloud `json:"not_in_cloud,omitempty"`
	// Moved are the resources that roots generated again move to other
	// addresses, and Departed those they hand over to other roots, which
	// must be applied after them.
	Moved    []report.Move `json:"moved,omitempty"`
	Departed []report.Move `json:"departed,omitempty"`
	// IncompleteHandovers are the handovers one of whose roots failed,
	// with what to do before applying either root.
	IncompleteHandovers []report.IncompleteHandover `json:"incomplete_handovers,omitempty"`
	// KeptRoots are the roots earlier imports generated that keep their
	// directories, though the configuration file's environments would put
	// their resources under envs/<env>/ now.
	KeptRoots []report.KeptRoot `json:"kept_roots,omitempty"`
	// Warnings are what people should look at before using the
	// configuration: about the run, such as environments it couldn't
	// apply, and about a directory's configuration, after its path.
	Warnings []string `json:"warnings,omitempty"`
}

ImportResult is what an import did.

type Providers

type Providers struct {
	// Profiles are their profiles, sorted by the names of their commands
	// (see harvest.Profile.Command).
	Profiles []harvest.Profile
	// Sources are, by the names of their commands, the source addresses
	// of the Terraform providers each one's roots use: its own, such as
	// hashicorp/azurerm, and those its curated modules use, such as
	// Azure/azapi (see harvest.ProviderWithModuleProviders). The drift
	// tools run Terraform on roots that use these alone (see
	// driftAllowed).
	Sources map[string][]string
	// Check rejects a name unless it names one of them, as the commands
	// that take a provider's name do.
	Check func(name string) error
}

Providers are the providers compiled into the binary the tools run. The server knows them only through what its caller passes it, so that it imports neither the listers nor their clouds' SDKs: it runs the binary.

type ReportInput

type ReportInput struct {
	Out string `json:"out" jsonschema:"the output directory of an import"`
	// Kind is the report to read: reportImport or reportDrift.
	Kind string `` /* 200-byte string literal not displayed */
}

ReportInput is the report tool's input.

type Runner

type Runner func(ctx context.Context, args []string) (stdout, stderr []byte, exitCode int, err error)

Runner runs infraharvest with args and returns its standard output, its standard error and its exit code. err is set only if it couldn't run.

type Scope

type Scope struct {
	Provider string   `json:"provider" jsonschema:"the provider command"`
	Services []string `` /* 164-byte string literal not displayed */
	// QueryTypes are the types the query service lists through Terraform's
	// list resources, which every provider has.
	QueryTypes []string `` /* 293-byte string literal not displayed */
	// Regions is for aws and google.
	Regions []string `` /* 227-byte string literal not displayed */
	// Profile and Accounts are for aws.
	Profile  string   `` /* 128-byte string literal not displayed */
	Accounts []string `` /* 157-byte string literal not displayed */
	// CloudFormationStacks and CloudFormationIgnore are for aws: the
	// stacks whose resources alone to import, and those of their resources
	// Terraform can't import that they may be deleted without.
	CloudFormationStacks []string `` /* 270-byte string literal not displayed */
	CloudFormationIgnore []string `` /* 271-byte string literal not displayed */
	// Projects, Organization and Folders are for google, which needs at
	// least one of them.
	Projects     []string `` /* 154-byte string literal not displayed */
	Organization string   `` /* 172-byte string literal not displayed */
	Folders      []string `` /* 161-byte string literal not displayed */
	// Subscriptions, ManagementGroup and ResourceGroup are for azure.
	Subscriptions   []string `` /* 157-byte string literal not displayed */
	ManagementGroup string   `` /* 197-byte string literal not displayed */
	ResourceGroup   string   `` /* 162-byte string literal not displayed */
	// Azapi is for azure.
	Azapi bool `` /* 233-byte string literal not displayed */
}

Scope is what to list: a provider command, its services, and where to list them, in the provider's own terms. Each field but Provider sets the flag its flag tag names (see flagArgs). A field with a scope tag is for the providers whose profiles declare its flag alone (see harvest.Scope.Flags), so that a provider's parameters come with it: the tools reject it for the others (see checkScopeProviders), the tools' descriptions say which provider takes which (see scopeHelp), and their schemas have it only where a provider compiled in takes it, its description naming them for {providers} (see scopeSchema), as the provider's description names the provider commands compiled in.

type SelectionSummary

type SelectionSummary struct {
	Selection string      `json:"selection"`
	Included  int         `json:"included"`
	Excluded  int         `json:"excluded"`
	Types     []TypeCount `json:"types"`
	// Exclusions are the first excluded resources, up to maxExclusions,
	// with the reasons.
	Exclusions []string `json:"exclusions,omitempty"`
	// MoreExclusions counts the excluded resources Exclusions leaves out:
	// the selection file names every one.
	MoreExclusions int `json:"more_exclusions,omitempty"`
}

SelectionSummary counts a selection file's resources.

type TypeCount

type TypeCount struct {
	Type     string `json:"type"`
	Included int    `json:"included"`
	Excluded int    `json:"excluded"`
}

TypeCount counts one type's resources in a selection.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL