Skip to content
Remote Control
Build plugins2-0Antigravity AppFeaturesBuild plugins Antigravity App FeaturesAntigravity AppAntigravity CLIAntigravity IDE
Available on:
Antigravity AppAntigravity CLIAntigravity IDE

You can package skills, Model Context Protocol (MCP) servers, custom agents and subagents, rules, and lifecycle hooks into a single versioned plugin directory. Once validated locally with agy plugin validate --strict, you can share your plugin across workspaces, distribute it from a GitHub repository, or submit it to the Antigravity Marketplace.

Create a working Antigravity plugin with a custom skill and validate it locally in three steps:

  1. Create the plugin directory and plugin.json manifest

    Every plugin requires a plugin.json manifest at <plugin-root>/plugin.json (or <plugin-root>/.antigravity-plugin/plugin.json):

    mkdir -p my-first-plugin/skills/hello

    Create my-first-plugin/plugin.json:

    {
      "$schema": "https://antigravity.google/schemas/v1/plugin.json",
      "name": "my-first-plugin",
      "displayName": "My First Plugin",
      "version": "1.0.0",
      "description": "Starter plugin that greets the user in Antigravity.",
      "suggestedPrompts": [
        "Greet me and explain how this plugin is structured"
      ]
    }
  2. Add a skill (skills/hello/SKILL.md)

    Create my-first-plugin/skills/hello/SKILL.md:

    ---
    name: hello
    description: >-
      Greet the user warmly and explain how this plugin works. Use when
      the user asks for a greeting or wants to test my-first-plugin.
    ---
    
    Greet the user by name if known, confirm that `my-first-plugin` is
    active, and briefly summarize the components an Antigravity plugin
    can bundle (skills, MCP servers, subagents, rules, and hooks).
  3. Validate and install locally

    Use the agy plugin CLI to validate your manifest and install the plugin locally:

    # Validate plugin.json, MCP servers, and component discovery
    agy plugin validate --strict ./my-first-plugin
    
    # Install the plugin into your local Antigravity environment
    agy plugin install ./my-first-plugin
    
    # Verify the plugin is installed and enabled
    agy plugin list

Once installed, open Antigravity and invoke /hello in chat, or click the starter prompt chip on the plugin’s detail page under Customizations > Installed.

A plugin is a directory containing a required manifest file (plugin.json) and optional files or subdirectories for documentation, visual assets, and customization components:

plugins/<plugin-name>/
├── plugin.json               # Required manifest (or .antigravity-plugin/plugin.json)
├── README.md                 # Optional pre-install documentation in Marketplace UI
├── assets/                   # Optional visual assets (for example, assets/logo.svg)
│   └── logo.svg
├── scripts/                  # Optional helper scripts (executable 0755 in Marketplace bundles)
├── mcp.json                  # Optional MCP server definitions
├── hooks.json                # Optional lifecycle hooks definition
├── skills/                   # Optional skills directory
│   └── <skill-name>/
│       ├── SKILL.md          # Required skill instructions and YAML frontmatter
│       ├── scripts/          # Optional skill-scoped helper scripts (executable 0755)
│       └── references/       # Optional reference docs loaded on demand
├── agents/                   # Optional custom agent and subagent templates
│   └── <agent-name>.md
└── rules/                    # Optional rules directory
    ├── AGENTS.md             # Optional always-on plugin rule
    └── <rule-name>.md        # Optional frontmatter-configured rule
  • Manifest location (plugin.json or .antigravity-plugin/plugin.json): Place plugin.json at <plugin-root>/plugin.json for standalone Antigravity plugins, or inside <plugin-root>/.antigravity-plugin/plugin.json for multi-provider repositories that also ship .claude-plugin/plugin.json or .cursor-plugin/plugin.json (.antigravity-plugin/plugin.json takes precedence over root plugin.json). Keep component directories (skills/, agents/, rules/, scripts/, mcp.json, and hooks.json) at <plugin-root>.

  • Pre-install documentation (README.md): Include a README.md at <plugin-root>/README.md (or .antigravity-plugin/README.md) to document setup prerequisites, included tools, and example workflows in the Marketplace detail view before installation:

    Plugin details view showing suggestedPrompts chips, component tabs, and rendered README.md

Every plugin requires a plugin.json file to identify the directory as a plugin and define its metadata, presentation fields, and attribution:

{
  "$schema": "https://antigravity.google/schemas/v1/plugin.json",
  "name": "acme-cloud",
  "displayName": "Acme Cloud",
  "version": "1.2.0",
  "description": "Deploy and monitor Acme Cloud services in Antigravity.",
  "logo": "assets/logo.svg",
  "suggestedPrompts": [
    "List my failing Acme Cloud deployments from the last 24 hours",
    "Create a staging environment for the current branch",
    "Audit our Acme Cloud IAM policies for overly broad permissions"
  ],
  "author": {
    "name": "Acme Corp",
    "url": "https://acme.example.com"
  },
  "homepage": "https://docs.acme.example.com/antigravity-plugin",
  "repository": "https://github.com/acme/acme-antigravity-plugin",
  "license": "Apache-2.0",
  "keywords": ["acme", "cloud", "deployments", "monitoring"]
}
FieldTypeRequiredDescription
nameStringYes (CLI and Marketplace) / Optional (local folders)The unique, machine-readable lowercase kebab-case identifier of the plugin (^[a-z0-9]+(-[a-z0-9]+)*$). Required by agy plugin validate --strict, agy plugin install, and the Marketplace; defaults to the folder name when loaded from a local directory without a name. Namespaces bundled MCP servers (<name>_<server>).
displayNameStringYes (Marketplace) / Optional (local)Human-readable product or brand title shown in Marketplace cards and plugin lists instead of name (for example, "Acme Cloud"). Omit suffixes like "Plugin" or "MCP", and do not prefix with "Antigravity", "Gemini", "Claude", or "Cursor".
descriptionStringYes (Marketplace) / Optional (local)A concise 1–2 sentence summary of the plugin’s purpose and capabilities, displayed on Marketplace cards and plugin listings (120–160 characters recommended).
versionStringYes (Marketplace) / Optional (local)Plugin version string (MAJOR.MINOR.PATCH Semantic Versioning recommended, such as "1.2.0"). Increment on every release so installed clients detect updates.
logoStringYes (Marketplace) / Optional (local)Relative path to a bundled 1:1 square icon inside the plugin (.svg, .png, .jpg, .jpeg, or .webp, >= 128x128px with ~10% transparent padding, such as "assets/logo.svg"). Must remain legible on both Light and Dark themes.
suggestedPromptsString[]RecommendedUp to 3 actionable starter prompts displayed as clickable chips on the plugin detail page.
skillsString or String[]NoExtra skill directories, relative to <plugin-root>, loaded in addition to the default skills/ folder (for example, ["./extra-skills"]). Omit when using the default skills/ directory.
disabledBooleanNoWhether the plugin starts disabled when first installed (false by default). User enable or disable choices take precedence.
authorString or ObjectYes (Marketplace) / Optional (local)Publisher attribution as a string or { "name": "Org Name", "url": "https://example.com" } (url must use https://).
homepageStringRecommendedPublic https:// URL pointing to the plugin’s documentation or product landing page.
repositoryStringNoPublic https:// source code repository URL (for example, "https://github.com/acme/acme-antigravity-plugin").
licenseStringRecommendedSPDX license identifier (for example, "Apache-2.0", "MIT", or "Proprietary").
keywordsString[]RecommendedLowercase search keywords used for Marketplace search and filtering.

To enable automatic autocomplete and validation in editors like VS Code or JetBrains IDEs, include the $schema key pointing to the official schema URL:

"$schema": "https://antigravity.google/schemas/v1/plugin.json"

You can also validate your manifest and all bundled components from your terminal using agy plugin validate:

agy plugin validate --strict ./my-plugin

The official JSON schema is hosted at https://antigravity.google/schemas/v1/plugin.json:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://antigravity.google/schemas/v1/plugin.json",
  "title": "Antigravity plugin manifest",
  "type": "object",
  "required": ["name"],
  "additionalProperties": false,
  "properties": {
    "$schema": { "type": "string" },
    "name": {
      "type": "string",
      "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
    },
    "displayName": { "type": "string" },
    "description": { "type": "string" },
    "version": { "type": "string" },
    "disabled": { "type": "boolean", "default": false },
    "logo": { "type": "string" },
    "suggestedPrompts": {
      "type": "array",
      "items": { "type": "string", "pattern": "\\S" },
      "maxItems": 3
    },
    "skills": {
      "oneOf": [
        { "type": "string", "pattern": "\\S" },
        { "type": "array", "items": { "type": "string", "pattern": "\\S" } }
      ]
    },
    "author": {
      "anyOf": [
        { "type": "string" },
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "name": { "type": "string" },
            "email": { "type": "string" },
            "url": { "type": "string" }
          }
        }
      ]
    },
    "homepage": { "type": "string" },
    "repository": { "type": "string" },
    "license": { "type": "string" },
    "keywords": {
      "type": "array",
      "items": { "type": "string" }
    },
    "extensions": {
      "type": "object",
      "additionalProperties": { "type": "object" }
    }
  }
}

A plugin can bundle any combination of the following components relative to <plugin-root>:

ComponentDefault pathPurpose
Skillsskills/<skill-name>/SKILL.mdTask-specific procedural instructions, scripts, and reference docs loaded on demand or via /<skill-name>.
MCP serversmcp.jsonRemote HTTPS or local stdio Model Context Protocol tool servers, including OAuth and user-prompted credential variables.
Subagentsagents/<agent-name>.mdSpecialized custom agents and subagents with dedicated system prompts, model tiers, and tool allowlists.
Rulesrules/AGENTS.md or rules/<rule-name>.mdPersistent behavioral constraints, domain guardrails, or glob-scoped coding standards.
Lifecycle hookshooks.jsonSynchronous shell commands or prompt evaluations that inspect, block, or augment agent lifecycle events and tool calls.

Installed plugins are unpacked into a read-only plugin directory (~/.gemini/config/plugins/<plugin-name>) that is replaced when the plugin updates. To keep your plugin self-contained across machines and operating systems, reference these variables in your plugin’s MCP server configuration instead of hardcoding absolute paths:

VariableResolves to
${PLUGIN_ROOT}The absolute path of the read-only plugin root directory (~/.gemini/config/plugins/<plugin-name>). Expanded in args, cwd, and custom env values in MCP server definitions, and automatically exported as PLUGIN_ROOT in every plugin MCP server environment.
${PLUGIN_DATA}The absolute path of a persistent, writable data directory created for the plugin outside your workspace. Expanded in args, cwd, and custom env values in MCP server definitions, and automatically exported as PLUGIN_DATA in every plugin MCP server environment.
${VARIABLE_NAME}A user-supplied credential or configuration value declared in mcpServers.<server>.variables (expanded in command, args, env, url, headers, and oauth).

Antigravity automatically sets the PLUGIN_ROOT and PLUGIN_DATA environment variables for every plugin MCP server process, and expands ${PLUGIN_ROOT} and ${PLUGIN_DATA} inside args, cwd, and custom env keys in your MCP server configuration:

{
  "mcpServers": {
    "my-local-mcp-server": {
      "command": "python3",
      "args": ["${PLUGIN_ROOT}/scripts/mcp_server.py"],
      "env": {
        "CACHE_DIR": "${PLUGIN_DATA}/cache"
      }
    }
  }
}

For all supported MCP server properties, refer to MCP configuration structure.


Skills package domain-specific instructions, scripts, and reference files at skills/<skill-name>/SKILL.md. At session startup, only each skill’s name and description are loaded into context; the full SKILL.md body is loaded on demand when the agent triggers the skill or the user runs /<skill-name>.

skills/
└── deploy-service/
    ├── SKILL.md           # Required: YAML frontmatter and instructions
    ├── scripts/           # Optional: helper scripts (executable 0755)
    ├── references/        # Optional: reference docs read on demand
    └── assets/            # Optional: templates or static files
---
name: deploy-service
description: >-
  Deploy and verify a service on Acme Cloud. Use when the user asks to
  deploy, roll out, or promote a service to staging or production.
---

## Instructions
1. Run `node scripts/check-credentials.mjs` from this skill directory to
   verify active Acme Cloud credentials.
2. Follow the rollout checklist in `references/rollout-checklist.md`.
Frontmatter fieldRequiredDescription
nameYesLowercase kebab-case identifier (1–64 characters) that must match the parent directory name (skills/<name>/SKILL.md). Exposed as /<name> in chat.
descriptionYesExplains both what the skill does and when the agent should trigger it (1–1,024 characters).
disable-model-invocationNoWhen true, prevents automatic model invocation so the skill runs only when invoked explicitly via /<name>. Defaults to false.
license / compatibilityNoOptional license identifier or environment prerequisites (such as required CLI tools or network access).

Plugins can bundle MCP server definitions using the standard mcpServers object structure in <plugin-root>/mcp.json. At runtime, each server key <server-key> is namespaced with the plugin name as <plugin-name>_<server-key>.

  • Remote HTTPS (url / serverUrl) vs. local stdio (command + args): Prefer remote HTTPS MCP endpoints or cross-platform Node.js scripts ("command": "node") so your plugin works across macOS, Linux, and Windows.
  • User-prompted credentials (variables) and OAuth (oauth): Declare variables inside a server entry (mcpServers.<server>.variables) to prompt users for API keys in a setup dialog before enabling the plugin, or configure oauth for browser-based sign-in.
{
  "mcpServers": {
    "cloud-oauth": {
      "url": "https://mcp.acme.example.com/v1/mcp",
      "oauth": {
        "clientId": "antigravity-marketplace-client"
      }
    },
    "cloud-token": {
      "url": "https://api.acme.example.com/mcp",
      "headers": {
        "Authorization": "Bearer ${ACME_API_TOKEN}"
      },
      "variables": [
        {
          "name": "ACME_API_TOKEN",
          "title": "Acme Cloud API Token",
          "description": "Personal access token with read:services and deploy scopes.",
          "link": "https://console.acme.example.com/settings/tokens"
        }
      ]
    },
    "local-helper": {
      "command": "node",
      "args": [
        "${PLUGIN_ROOT}/scripts/mcp-server.mjs",
        "--data-dir",
        "${PLUGIN_DATA}"
      ]
    }
  }
}
Variable fieldTypeRequiredDescription
nameStringYesVariable identifier (for example, "ACME_API_TOKEN"), interpolated as ${ACME_API_TOKEN} in command, args, env, url, or headers.
titleStringNoHuman-readable label shown in the credential setup prompt (defaults to name).
descriptionStringNoHelp text explaining what value to provide and any required token scopes.
linkStringNoURL opened when the user clicks to create or look up the credential.

Bundled MCP servers appear in the MCP tab on the plugin detail page:

Plugin detail view showing the MCP tab for a bundled MCP server

Define specialized custom agents and subagents as Markdown files under agents/<agent-name>.md (or agents/<agent-name>/agent.md). A bundled agent can run as a background subagent delegated tasks by the main agent (subagent: true) and/or be selected directly by the user as the primary session agent (mainAgent: true):

---
name: security-reviewer
description: >-
  Reviews code changes and infrastructure configs for security
  vulnerabilities. Delegate to this agent before deploying.
model: pro
mainAgent: true
subagent: true
commandExecutionPolicy: sandbox
tools:
  - view_file
  - grep_search
  - find_by_name
  - code_search
  - send_message
inheritMcp: true
---

You are a read-only security specialist. Audit the requested files for
hardcoded secrets, injection risks, and overly permissive IAM roles.
Return a prioritized findings table with file paths and line numbers.
Frontmatter fieldDefaultDescription
name(Required)Unique agent identifier (kebab-case).
description(Required)Explains when and why the parent agent should delegate work to this agent (or what the agent does when selected in the UI/CLI).
mainAgenttrueWhen true, users can select this agent as their primary session agent in the App, via /agents in the CLI, or via agy --agent <name> from the terminal.
subagenttrueWhen true, the primary agent can spawn this agent in the background via invoke_subagent.
model"inherit"Model tier when invoked as a subagent ("inherit", "flash_lite", "flash", or "pro").
toolsAll toolsAllowlist of built-in tools (send_message is always included). Omit file-edit and shell tools to create a read-only reviewer.
commandExecutionPolicy"sandbox"Auto-execution policy for shell commands ("off", "auto", "eager", or "sandbox").
skills[]Optional list of skill paths (such as skills/deploy-service) that this agent loads.
inheritMcp / inheritCustomizationstrueControls whether the agent inherits workspace MCP servers (inheritMcp) and skills, rules, and hooks (inheritCustomizations).

Bundled custom agents and subagents appear in the Agents tab on the plugin detail page:

Plugin detail view showing the Agents tab for a bundled custom agent

Rules define persistent coding standards or domain guardrails in <plugin-root>/rules/:

  • rules/AGENTS.md (or rules/GEMINI.md): Loaded automatically as an always-on rule whenever the plugin is enabled (no YAML frontmatter required).
  • Named rule files (rules/<rule-name>.md): Include YAML frontmatter with a trigger mode (always_on, model_decision, glob, or manual). For glob triggers, globs must be a comma-separated string:
---
trigger: glob
globs: "**/*.tf, **/*.tfvars, infra/**/*.yaml"
description: Terraform and infrastructure naming conventions
---

- All Terraform resources must include `environment` and `owner` tags.
- Never use `0.0.0.0/0` in ingress security group rules without an
  explicit waiver comment.
trigger valueRequired fieldsBehavior
always_on(none)Injected into every conversation session while the plugin is enabled.
model_decisiondescriptionLoaded dynamically when the agent determines the rule’s description matches the current task.
globglobs (String)Activated automatically when files matching the comma-separated glob patterns are in context.
manual(none)Activated only when explicitly referenced by the user with @<rule-name>.

Bundled rules appear in the Rules tab on the plugin detail page:

Plugin detail view showing the Rules tab for a bundled rule

Define synchronous lifecycle hooks in <plugin-root>/hooks.json. Each top-level key in hooks.json is a named hook group mapping to lifecycle event arrays (PreToolUse and PostToolUse wrap handlers in { "matcher": "...", "hooks": [...] }, whereas SessionStart, PreInvocation, PostInvocation, and Stop take a flat array of hook handler objects).

Command hooks run with their working directory (cwd) set to <plugin-root>, receive event context as JSON on stdin, and must exit with code 0 and write a JSON response object to stdout (for example, {"decision": "deny", "reason": "..."} in PreToolUse or {"decision": "block", "reason": "..."} in Stop). Any non-zero exit code is logged as a hook execution error and ignored (failing open):

{
  "policy-guard": {
    "enabled": true,
    "PreToolUse": [
      {
        "matcher": "run_command|edit_file",
        "hooks": [
          {
            "type": "command",
            "command": "node ./scripts/policy.mjs",
            "timeout": 10
          }
        ]
      }
    ],
    "Stop": [
      {
        "type": "command",
        "command": "node ./scripts/verify.mjs",
        "timeout": 15
      }
    ]
  }
}
EventFires when"matcher" targetCommon stdout JSON response (exit 0)
SessionStartA new conversation is initialized(none — flat handler array)Return {"injectSteps": [{"userMessage": "..."}]} to inject startup context.
PreInvocationBefore the model processes a user turn(none — flat handler array)Return {"injectSteps": [...]} to attach dynamic context before model generation.
PostInvocationAfter the model finishes its response turn(none — flat handler array)Return {"injectSteps": [...], "terminationBehavior": "force_continue"} for post-turn checks.
PreToolUseBefore a tool executesTool name regex ("run_command", "mcp:.*")Return {"decision": "deny", "reason": "..."} to block, "ask" / "force_ask" to prompt, or "overwrite": {...} to rewrite arguments.
PostToolUseAfter a tool completesTool name regexReturn {"overwriteResult": "..."} to redact or transform tool output ("command" hooks only).
StopBefore the agent loop finishes(none — flat handler array)Return {"decision": "block", "reason": "..."} to prevent completion until checks pass, or "continue".

Validate and test locally (agy plugin validate)

Section titled “Validate and test locally (agy plugin validate)”

Before distributing a plugin or submitting it to the Marketplace, run strict validation and test installation locally:

# Run strict schema and component validation (treats warnings as errors)
agy plugin validate --strict ./my-plugin

# Install the local plugin folder into your profile
agy plugin install ./my-plugin

# Inspect discovered components in JSON format
agy plugin list --json

Verify the following requirements before sharing or submitting your plugin:

CheckRequirement and fix
Strict CLI validationagy plugin validate --strict ./my-plugin exits with 0 errors and 0 warnings.
Plugin naming & brandingname is lowercase kebab-case (^[a-z0-9]+(-[a-z0-9]+)*$), and name / displayName represent your product or service without leading with "Antigravity", "Gemini", "Claude", or "Cursor".
Skill folder namesEach SKILL.md frontmatter name matches its parent directory name (skills/<name>/SKILL.md).
Rule globs formatglobs in rules/<rule>.md is a comma-separated string ("**/*.tf, **/*.yaml"), not a YAML array.
MCP variables scopevariables is declared inside mcpServers.<server>.variables (not at the root of mcp.json), and PLUGIN_ROOT / PLUGIN_DATA are not duplicated in "env".
Hooks structure & paths<plugin-root>/hooks.json wraps event arrays in a named hook object, uses relative script paths (./scripts/...) rather than ${PLUGIN_ROOT}, and uses a flat handler array for Stop, SessionStart, PreInvocation, and PostInvocation.
Bundled local logo & executableslogo in plugin.json points to a bundled 1:1 square file inside the plugin (such as "assets/logo.svg"), and helper executables are placed under scripts/ so they retain 0755 permissions in Marketplace bundles.

Once your plugin passes agy plugin validate --strict and includes a complete plugin.json (name, displayName, description, version, logo, suggestedPrompts, and author), README.md, and bundled logo asset, submit it through the Antigravity Marketplace partner intake form.


  • Plugins: Learn how to install, configure, and use plugins across the Antigravity App, Antigravity CLI, and Antigravity IDE.
  • Marketplace: Browse and install curated Google and partner plugins from the Antigravity Marketplace.
  • Skills, MCP, Custom subagents, Rules, and Lifecycle hooks: Dive deeper into each individual customization component.