Plugins
Plugin providers are the packages that expose tools through Gestalt. Operators
configure them under plugins, while the host takes care of catalog
loading, token storage, connection management, HTTP routing, and MCP exposure.
How plugin providers work
A plugin package includes a manifest that defines metadata, connections, and optional passthrough API surfaces. Some plugins are fully executable, some are fully declarative, and some are hybrid packages that combine both models.
From a deployment point of view, source chooses the package, config
passes provider-specific settings such as OAuth app credentials,
allowedOperations publishes only part of a large catalog,
egress.allowedHosts declares outbound egress policy, and execution opts an
executable plugin into hosted execution.
If the manifest enables MCP, the same operations are also exposed through the
server’s /mcp endpoint.
How plugin invocation uses authorization
Gestalt resolves every plugin request to a canonical subject before it invokes the target operation. Authorization then decides whether that subject may use the plugin or operation at all. A plugin can be configured and healthy, but a particular subject may still be denied at request time if their static policy memberships or dynamic grants do not allow that operation.
Connections are still stored per subject. Authorization answers whether the subject may invoke the plugin, while authentication and connection management answer how that subject proves itself to the upstream system.
First-party plugin packages
First-party plugins live under
valon-technologies/gestalt-providers/plugins.
Examples include:
| Provider |
|---|
github.com/valon-technologies/gestalt-providers/plugins/github |
github.com/valon-technologies/gestalt-providers/plugins/jira |
github.com/valon-technologies/gestalt-providers/plugins/httpbin |
See the repository directory for the broader catalog of first-party plugins and their package layouts.
Configuring a plugin provider
plugins:
github:
displayName: GitHub
source: https://artifacts.example.com/plugin/github/v0.0.1-alpha.1/provider-release.yaml
config:
apiBaseUrl: https://api.github.com
clientId: ${GITHUB_CLIENT_ID}
clientSecret:
secret:
provider: default
name: github-client-secretDuring local development, point at a source manifest instead:
plugins:
support:
source: ./plugins/support/manifest.yamlHosted HTTP endpoints, such as webhooks and Slack slash-command routes, are
declared by the plugin package in its manifest. Server config selects the
package and provides deployment-specific settings; the mounted URL is built
from the configured plugin key and the binding path. For example, a
plugins.slack entry with a binding path of /commands/support is served at
/api/v1/slack/commands/support.
Use plugins.<name>.securitySchemes or plugins.<name>.http only when the
deployment needs to override package-provided hosted HTTP metadata or add a
deployment-local binding. This example overrides fields on package-defined
metadata:
plugins:
slack:
source: https://artifacts.example.com/plugin/slack/v1.2.3/provider-release.yaml
securitySchemes:
slack_signed:
secret:
env: SLACK_SIGNING_SECRET
http:
support_command:
path: /commands/supportBy default, executable plugins run on the same machine as gestaltd. A plugin
only uses a hosted runtime when it sets execution.mode: hosted. Use execution.mode: hosted with execution.runtime; legacy plugins.<name>.runtime is no longer accepted.
Choosing a runtime
Runtime selection is explicit and per-plugin:
runtime:
providers:
modal:
source:
path: ./vendor/gestalt-providers/runtime/modal/manifest.yaml
default: true
config:
app: gestalt-runtime
environment: main
server:
runtime:
defaultHostedProvider: modal
plugins:
support:
source: ./plugins/support/manifest.yaml
execution:
mode: hosted
runtime:
template: python-dev
image: ghcr.io/example/support-plugin:2026-04-21
metadata:
environment: productionplugins.<name>.execution.runtime.provider selects a named backend from
runtime.providers. When provider is omitted, Gestalt uses
server.runtime.defaultHostedProvider or the one runtime entry marked
default: true.
template, image, and metadata are forwarded to the runtime backend. Their
meaning is backend-specific: one runtime may ignore them, while another may use
them to choose a sandbox template, container image, or lifecycle labels.
A built-in local runtime is always available for same-machine execution. The
first installable hosted runtime provider is modal. It requires
runtime.providers.<name>.config.app and
plugins.<name>.execution.runtime.image.
Gestalt only uses it for plain executable plugins today. Modal can still run
plugins that need Gestalt-owned services or hostname-based egress when the host
is configured for the public relay and proxy path. In practice that means
server.baseURL and server.encryptionKey must be set, and the runtime must
report a compatible support profile. Without those prerequisites, plugins that
need indexeddb, cache, s3, workflow-manager access when workflows are
configured, nested invokes, egress.allowedHosts, or
server.egress.defaultAction: deny stay on local.
For the runtime-provider model itself, see Providers > Runtime.
Connections and credentials
Plugin packages declare connection models in their manifests, and the server stores credentials per subject.
| Mode | Behavior |
|---|---|
none | No upstream credential is required |
user | The calling subject stores its own credential (user:<id>, service_account:<id>, or another canonical subject ID) |
Common auth types are oauth2, mcp_oauth, bearer, manual, and none.
Operator-supplied app credentials such as clientId and clientSecret go in
the plugin’s config block when the provider requires them.
Filtering operations and egress
Use allowedOperations to publish only a subset of a large plugin catalog:
plugins:
support:
source: https://artifacts.example.com/plugin/support/v2.4.0/provider-release.yaml
allowedOperations:
tickets.list:
alias: list_tickets
tickets.get:
alias: get_ticketUse egress.allowedHosts when a plugin needs explicit outbound access:
plugins:
github:
egress:
allowedHosts:
- api.github.com
- "*.github.com"For executable plugins, egress.allowedHosts is only a complete security
boundary when the plugin is running inside a runtime backend that preserves
Gestalt’s hostname-based policy model. Provider-level allowedHosts is no
longer accepted; use egress.allowedHosts. The current host-local wrappers are OS-dependent, so
operators should treat egress.allowedHosts as declarative policy plus
best-effort enforcement unless the selected runtime explicitly supports
hostname-based egress controls.
Building your own plugin
Plugin implementation details, declarative surfaces, local testing, and custom release packaging now live under Custom Providers > Plugin.
What to read next
For configuration, see Configuration. For operation invocation, see HTTP API. For manifest fields, see Provider Manifests. For authorization behavior, see Authorization. To build a plugin, see Custom Plugin.