Class ServerContext

java.lang.Object
com.eqixiac.equinix.mcp.server.ServerContext

public final class ServerContext extends Object
The shared state a ToolHandler executes against: the lazily-built SDK facades (Fabric + design engines, Customer Portal, Network Edge, IBX SmartView), the environment, the JSON mapper, and the single-process DesignStore of plans and optimization results.

Facades are created on first use, per facade, so a server launched with only the ibx toolset never constructs a Customer Portal client. All facades vend from one Equinix session (one OAuth token, one connection pool) when the context was built from a session or credentials; alternatively each facade can be injected directly - that is how tests supply Mockito-stubbed facades, and how embedders can reuse clients they already hold.

This type is part of the public tool seam: broker/extension tools registered through ToolRegistration receive the same context instance as the built-in catalog.

  • Field Details

    • ENV_PEERINGDB_KEY

      public static final String ENV_PEERINGDB_KEY
      Environment variable holding an optional PeeringDB API key for design_analyze_peering.
      See Also:
    • ENV_GCP_BILLING_KEY

      public static final String ENV_GCP_BILLING_KEY
      Environment variable holding an optional Google Cloud Billing Catalog API key.
      See Also:
    • ENV_PRICING_TIMEOUT_MS

      public static final String ENV_PRICING_TIMEOUT_MS
      Environment variable overriding the live-pricing budget of one tool call, in ms: every live pricing lookup the call makes (cloud price lists and the Equinix rate card) shares it.
      See Also:
    • DEFAULT_PRICING_TIMEOUT_MS

      public static final long DEFAULT_PRICING_TIMEOUT_MS
      Default live-pricing budget of one tool call.
      See Also:
    • MIN_PRICING_TIMEOUT_MS

      public static final long MIN_PRICING_TIMEOUT_MS
      Smallest accepted pricing budget; smaller values are raised to it with a warning.
      See Also:
    • MAX_PRICING_TIMEOUT_MS

      public static final long MAX_PRICING_TIMEOUT_MS
      Largest accepted pricing budget (2 minutes); larger values are lowered to it with a warning, because a tool call that waits longer than that is indistinguishable from a hung one.
      See Also:
    • ENV_ALLOW_UNCONFIRMED_MUTATIONS

      public static final String ENV_ALLOW_UNCONFIRMED_MUTATIONS
      Environment variable that, when true, lets fabric_confirm_change execute when the MCP client did not declare elicitation support (so no human prompt can be shown). Off by default: without it the broker refuses to execute rather than create billable resources with no human in the loop.
      See Also:
    • ENV_ELICIT_TIMEOUT_MS

      public static final String ENV_ELICIT_TIMEOUT_MS
      Environment variable overriding the hard timeout for a single elicitation round-trip, in ms.
      See Also:
    • DEFAULT_ELICIT_TIMEOUT_MS

      public static final long DEFAULT_ELICIT_TIMEOUT_MS
      Default hard timeout for a single elicitation round-trip. Generous (a human may be answering the prompt) but bounded, so a tool call can never block forever waiting on the client.
      See Also:
    • MIN_ELICIT_TIMEOUT_MS

      public static final long MIN_ELICIT_TIMEOUT_MS
      Smallest accepted elicitation timeout; smaller values are raised to it with a warning.
      See Also:
    • MAX_ELICIT_TIMEOUT_MS

      public static final long MAX_ELICIT_TIMEOUT_MS
      Largest accepted elicitation timeout (1 hour); larger values are lowered to it with a warning. The MCP SDK's request timeout is set just above this value, so it also bounds how long a stalled client can hold a server-to-client request open.
      See Also:
  • Method Details

    • builder

      public static ServerContext.Builder builder()
      Returns:
      a new context builder
    • fabric

      public FabricGateway fabric()
      Returns:
      the Fabric gateway the design engines read from
    • design

      public Design design()
      Returns:
      the design facade (optimizer, wizard, peering, savings, TCO) over fabric()
    • customerPortal

      public CustomerPortal customerPortal()
      Returns:
      the Customer Portal client
    • networkEdge

      public NetworkEdge networkEdge()
      Returns:
      the Network Edge client
    • ibxSmartView

      public IBXSmartView ibxSmartView()
      Returns:
      the IBX SmartView client
    • metroRegistry

      public MetroRegistry metroRegistry()
      Returns:
      the live metro catalogue (metros, IBXs, coordinates) shared by the design tools
    • multicloudEnvironments

      public MulticloudEnvironmentCatalog multicloudEnvironments()
      The catalog of native provider-to-provider multicloud environments the design tools read: design_list_multicloud_environments, design_compare_cloud_to_cloud and the cloud-to-cloud step of design_plan_deployment. Beta. Defaults to MulticloudEnvironmentCatalog.standard(), a dated copy of provider documentation bundled with the SDK; it is loaded on first use and is not refreshed at run time. An embedder with newer data injects MulticloudEnvironmentCatalog.standard().with(...) through the builder.
      Returns:
      the catalog; never null
    • env

      public Optional<String> env(String name)
      Looks up an environment variable from this context's environment view (the real process environment unless overridden for tests).
      Parameters:
      name - the variable name
      Returns:
      the value, or empty when unset or blank
    • objectMapper

      public com.fasterxml.jackson.databind.ObjectMapper objectMapper()
      Returns:
      the JSON mapper used for argument parsing and payload building
    • designStore

      public DesignStore designStore()
      Returns:
      the single-process store of deployment plans and optimization results the design tools chain through (plan_id, spec_fingerprint)
    • estateAnalyzer

      public EstateAnalyzer.Builder estateAnalyzer(EstateScope scope)
      A read-only estate analysis bound to scope: by default over this context's Fabric client (which must be a full Fabric, not a bare gateway) plus Network Edge when a session is available; a builder-supplied factory replaces it (tests, snapshots).
      Parameters:
      scope - the scope; must name projects, accounts or resources
      Returns:
      the analysis builder with the scope set
      Throws:
      IllegalArgumentException - when the scope is unscoped or asks for the entire account
    • providerRateCard

      public Optional<RateCard> providerRateCard(CloudProviderType provider)
      Returns the live pricing adapter for a cloud provider, if one can be constructed (GCP requires ENV_GCP_BILLING_KEY). The adapter is built once per provider and reused for the context's lifetime, so its internal offer/SKU catalogue caches actually pay off across tool calls. The returned card is not yet timeout-guarded - design_compare_cloud_egress wraps it per invocation.
      Parameters:
      provider - the cloud provider
      Returns:
      the live rate card, or empty when no adapter is available for the provider
    • pricingTimeoutMillis

      public long pricingTimeoutMillis()
      The live-pricing budget of one tool call, from ENV_PRICING_TIMEOUT_MS. A value that is not a positive whole number falls back to DEFAULT_PRICING_TIMEOUT_MS; a value outside [MIN_PRICING_TIMEOUT_MS, MAX_PRICING_TIMEOUT_MS] is clipped to the nearest bound. Either case logs one warning naming the variable (the value is a number, not a secret).
      Returns:
      the budget in milliseconds
    • elicitTimeoutMillis

      public long elicitTimeoutMillis()
      The hard timeout for one elicitation round trip, from ENV_ELICIT_TIMEOUT_MS, with the same fallback and clipping rules as pricingTimeoutMillis() over [MIN_ELICIT_TIMEOUT_MS, MAX_ELICIT_TIMEOUT_MS].
      Returns:
      the timeout in milliseconds
    • pricingBudget

      public PricingBudget pricingBudget()
      The live-pricing budget of the current tool call: started when the call began and shared by every pricing lookup it makes. Outside a served call (a direct handler invocation) a fresh budget is returned, so a handler should read this once and reuse it.
      Returns:
      the budget
    • budgetedEquinixRateCard

      public RateCard budgetedEquinixRateCard()
      The Equinix rate-card chain (live Equinix pricing, then the bundled reference figures) with the live layer under the current call's pricingBudget(): the chain extension tools such as the Safe Mutation Broker price with. A stalled live lookup falls through to the reference figures when the budget runs out.
      Returns:
      the budgeted chain
    • currentCancellation

      public CancellationSignal currentCancellation()
      Returns:
      the cancellation signal of the current tool call; a never-cancelled signal outside a served call
    • allowUnconfirmedMutations

      public boolean allowUnconfirmedMutations()
      Returns:
      true only when ENV_ALLOW_UNCONFIRMED_MUTATIONS is set to true: the operator has accepted that, on a client without elicitation, the host's own tool-approval prompt is the only human check before a create executes
    • currentExchange

      public io.modelcontextprotocol.server.McpSyncServerExchange currentExchange()
      The MCP client exchange bound for the current tool call, or null when the handler is running outside a served call (a direct unit-test invocation, or a transport that supplied none). A handler that wants to prompt the user reads this and hands it to ElicitationSupport; a null exchange means "no interactive client", and the elicitation degrades cleanly.
      Returns:
      the current call's exchange, or null
    • confirmWithHuman

      public HumanConfirmation confirmWithHuman(String message)
      Asks the person at the MCP client bound to the current tool call to approve one action, through a form elicitation with one required boolean field. This is the public seam for tools outside this package (the Safe Mutation Broker) that gate a mutation on a human decision; the elicitation helper itself stays package-private.

      Behaviour: when currentExchange() is null or the client did not declare form elicitation at initialize, nothing is sent and the result is HumanConfirmation.Status.UNSUPPORTED_BY_CLIENT. Otherwise the call blocks until the client answers or elicitTimeoutMillis() elapses. It does not throw for a client-side failure: decline, cancel, timeout and transport errors are statuses on the result. Only HumanConfirmation.Status.ACCEPTED is an approval.

      The prompt is delivered by this context's HumanConfirmer (MCP form elicitation by default) and is abandoned when the client cancels the tool call (HumanConfirmation.Status.CALL_CANCELLED).

      Parameters:
      message - the prompt shown to the user; state what will be executed and what each answer does
      Returns:
      what the client reported