open-neko · 3 plugins

OpenNeko Official

First-party plugins for OpenNeko. Published by the maintainers under @open-neko/* on npm. Written, tested, and supported by the OpenNeko team.

Third parties: publish your own marketplace.json at any HTTPS URL — see the publish guide for the schema, integrity-hash recipe, and CI checks.

How operators install

openneko install <name> writes the manifest entry and pulls the pinned version from npm. On the next worker start, every listed plugin boots in its own microsandbox VM.

Marketplace URL

open-neko.github.io/plugins/marketplace.json

Trusted by default — the openneko CLI fetches it on every install. Third parties: openneko marketplace add <url>.

Plugins listed

3

Plugins

Click view source for each plugin's repository. Every plugin runs inside a microsandbox microVM with outbound network limited to the hosts shown on the card — the manifest declaration is enforced at the VM boundary.

Parallel.ai Search MCP

@open-neko/plugin-parallel-search v0.2.0

Web search + page fetch via Parallel.ai's Search MCP over Streamable HTTP. Anonymous tier supported; Bearer-token authenticated tier optional. Two actions: web_search and web_fetch.

web_searchweb_fetchsearch.parallel.ai
openneko install @open-neko/plugin-parallel-search view source ↗

Scalekit SSO

@open-neko/plugin-scalekit v0.1.0

Enterprise SSO via Scalekit. One integration that fronts Okta, Entra ID, Google Workspace, JumpCloud, and other identity providers. Implements OpenNeko's generic OIDC auth contract — install this plugin and the 'Sign in with Scalekit' button lights up in the web app.

SSO provider: Scalekit*.scalekit.com
prompts at install for:
SCALEKIT_ENVIRONMENT_URLSCALEKIT_CLIENT_ID🔒 SCALEKIT_CLIENT_SECRET
openneko install @open-neko/plugin-scalekit view source ↗

Slack actions

@open-neko/plugin-slack v0.1.0

Post messages, send DMs, react with emoji, and look up users/channels in Slack. Four actions, each separately approvable by operator rules. Authenticated via Slack bot token (xoxb-) stored in the per-user secrets file.

send_slack_messagesend_slack_dmreact_slack_messagelookup_slack_entityslack.com
prompts at install for:
🔒 SLACK_BOT_TOKEN
openneko install @open-neko/plugin-slack view source ↗

Trust model

This is the official OpenNeko marketplace — written, tested, and supported by the OpenNeko team. Anyone else who ships plugins to OpenNeko users publishes their own marketplace.json. Operators trust each one explicitly.

First-party

Listed here

The OpenNeko maintainers write these. Code lives in open-neko/plugins; we yank a version if it ever turns malicious.

Third-party

Add your own

Publish your marketplace.json at any HTTPS URL, then operators trust it with openneko marketplace add <url>. OpenNeko makes no representation about non-official marketplaces.

Bypass

openneko install <name> --unverified

Skip every marketplace and install straight from npm. Loud warning. For plugin authoring or emergency hotfixes — the integrity hash is taken on trust, but sandboxing and capability enforcement still apply.

For developers

The exact bytes the openneko CLI fetches when an operator runs openneko marketplace add or openneko install. Use the schema if you're publishing your own marketplace.json. Each block is also served at a stable URL so you can curl it.

marketplace.json GET https://open-neko.github.io/plugins/marketplace.json · 5.9 KB
{
  "$schema": "https://open-neko.github.io/plugins/marketplace.schema.json",
  "name": "OpenNeko Official",
  "owner": "open-neko",
  "homepage": "https://open-neko.github.io/plugins/",
  "description": "First-party plugins for OpenNeko. Published by the maintainers under @open-neko/* on npm. Written, tested, and supported by the OpenNeko team.",
  "plugins": [
    {
      "name": "@open-neko/plugin-parallel-search",
      "title": "Parallel.ai Search MCP",
      "description": "Web search + page fetch via Parallel.ai's Search MCP over Streamable HTTP. Anonymous tier supported; Bearer-token authenticated tier optional. Two actions: web_search and web_fetch.",
      "source": "https://github.com/open-neko/plugins/tree/main/packages/parallel-search",
      "homepage": "https://docs.parallel.ai/integrations/mcp/search-mcp",
      "maintainers": [
        {
          "name": "open-neko",
          "url": "https://github.com/open-neko"
        }
      ],
      "versions": [
        {
          "version": "0.2.0",
          "integrity": "sha512-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa==",
          "permissions": {
            "network": [
              "search.parallel.ai"
            ],
            "env": []
          },
          "capabilities": {
            "action": {
              "kinds": [
                {
                  "kind": "web_search",
                  "description": "Search the web via Parallel.ai's Search MCP.",
                  "default_mode": "auto"
                },
                {
                  "kind": "web_fetch",
                  "description": "Fetch a single page via Parallel.ai's Search MCP.",
                  "default_mode": "auto"
                }
              ]
            }
          },
          "publishedAt": "2026-05-17"
        }
      ]
    },
    {
      "name": "@open-neko/plugin-scalekit",
      "title": "Scalekit SSO",
      "description": "Enterprise SSO via Scalekit. One integration that fronts Okta, Entra ID, Google Workspace, JumpCloud, and other identity providers. Implements OpenNeko's generic OIDC auth contract — install this plugin and the 'Sign in with Scalekit' button lights up in the web app.",
      "source": "https://github.com/open-neko/plugins/tree/main/packages/scalekit",
      "homepage": "https://docs.scalekit.com/sso/quickstart",
      "maintainers": [
        {
          "name": "open-neko",
          "url": "https://github.com/open-neko"
        }
      ],
      "versions": [
        {
          "version": "0.1.0",
          "integrity": "sha512-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa==",
          "permissions": {
            "network": [
              "*.scalekit.com"
            ],
            "env": [
              {
                "key": "SCALEKIT_ENVIRONMENT_URL",
                "required": true,
                "secret": false,
                "description": "Your Scalekit environment URL, e.g. https://your-app.scalekit.com — copied from the Scalekit dashboard."
              },
              {
                "key": "SCALEKIT_CLIENT_ID",
                "required": true,
                "secret": false,
                "description": "OAuth client_id from the Scalekit dashboard."
              },
              {
                "key": "SCALEKIT_CLIENT_SECRET",
                "required": true,
                "secret": true,
                "description": "OAuth client_secret from the Scalekit dashboard. Stored in the per-user secrets file."
              }
            ]
          },
          "capabilities": {
            "auth": {
              "providerLabel": "Scalekit"
            }
          },
          "publishedAt": "2026-05-18"
        }
      ]
    },
    {
      "name": "@open-neko/plugin-slack",
      "title": "Slack actions",
      "description": "Post messages, send DMs, react with emoji, and look up users/channels in Slack. Four actions, each separately approvable by operator rules. Authenticated via Slack bot token (xoxb-) stored in the per-user secrets file.",
      "source": "https://github.com/open-neko/plugins/tree/main/packages/slack",
      "homepage": "https://api.slack.com/web",
      "maintainers": [
        {
          "name": "open-neko",
          "url": "https://github.com/open-neko"
        }
      ],
      "versions": [
        {
          "version": "0.1.0",
          "integrity": "sha512-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa==",
          "permissions": {
            "network": [
              "slack.com"
            ],
            "env": [
              {
                "key": "SLACK_BOT_TOKEN",
                "required": true,
                "secret": true,
                "description": "xoxb-... bot token from your Slack app. Needs scopes: chat:write, im:write, reactions:write, users:read, users:read.email, channels:read, groups:read (depending on which actions you'll allow)."
              }
            ]
          },
          "capabilities": {
            "action": {
              "kinds": [
                {
                  "kind": "send_slack_message",
                  "description": "Post a message to a Slack channel.",
                  "default_mode": "ask"
                },
                {
                  "kind": "send_slack_dm",
                  "description": "Send a direct message to a Slack user.",
                  "default_mode": "ask"
                },
                {
                  "kind": "react_slack_message",
                  "description": "Add an emoji reaction to a Slack message.",
                  "default_mode": "ask"
                },
                {
                  "kind": "lookup_slack_entity",
                  "description": "Look up a Slack user or channel by name or ID.",
                  "default_mode": "auto"
                }
              ]
            }
          },
          "publishedAt": "2026-05-17"
        }
      ]
    }
  ]
}
marketplace.schema.json GET https://open-neko.github.io/plugins/marketplace.schema.json · 7.4 KB
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://open-neko.github.io/plugins/marketplace.schema.json",
  "title": "OpenNeko plugin marketplace",
  "description": "Single-file catalog of plugins, modeled on Claude Code's marketplace.json plus the security fields the OpenNeko CLI enforces (integrity, permissions, capabilities). Publish your own marketplace.json at a stable URL and operators can trust it with `openneko marketplace add <url>`.",
  "type": "object",
  "required": ["name", "owner", "description", "plugins"],
  "additionalProperties": true,
  "properties": {
    "$schema": { "type": "string" },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 80,
      "description": "Human-readable name. Shown when the operator adds this marketplace."
    },
    "owner": {
      "type": "string",
      "minLength": 1,
      "description": "GitHub org / individual / company that publishes this marketplace."
    },
    "homepage": { "type": "string", "format": "uri" },
    "description": {
      "type": "string",
      "minLength": 10,
      "maxLength": 800
    },
    "plugins": {
      "type": "array",
      "items": { "$ref": "#/$defs/plugin" }
    }
  },
  "$defs": {
    "plugin": {
      "type": "object",
      "required": ["name", "title", "description", "source", "versions"],
      "additionalProperties": false,
      "properties": {
        "name": {
          "type": "string",
          "pattern": "^(@[a-z0-9-]+/)?[a-z0-9][a-z0-9-_]*$",
          "description": "npm package name."
        },
        "title": { "type": "string", "minLength": 3, "maxLength": 80 },
        "description": { "type": "string", "minLength": 10, "maxLength": 800 },
        "source": {
          "type": "string",
          "format": "uri",
          "pattern": "^https://(github\\.com|gitlab\\.com|codeberg\\.org)/"
        },
        "homepage": { "type": "string", "format": "uri" },
        "maintainers": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "object",
            "required": ["name"],
            "additionalProperties": false,
            "properties": {
              "name": { "type": "string" },
              "url": { "type": "string", "format": "uri" }
            }
          }
        },
        "versions": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/$defs/version" }
        }
      }
    },
    "version": {
      "type": "object",
      "required": ["version", "integrity", "permissions", "capabilities", "publishedAt"],
      "additionalProperties": false,
      "properties": {
        "version": {
          "type": "string",
          "pattern": "^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z-.]+)?$",
          "description": "Pinned semver — no ranges."
        },
        "integrity": {
          "type": "string",
          "pattern": "^sha512-[A-Za-z0-9+/=]+$"
        },
        "permissions": { "$ref": "#/$defs/permissions" },
        "capabilities": { "$ref": "#/$defs/capabilities" },
        "publishedAt": { "type": "string", "format": "date" },
        "yanked": { "type": "boolean", "default": false },
        "yanked_reason": { "type": "string" }
      }
    },
    "permissions": {
      "type": "object",
      "description": "What the plugin needs from the runtime: outbound network hosts and operator-supplied env vars. Same shape lives in the installed manifest entry.",
      "additionalProperties": false,
      "properties": {
        "network": {
          "type": "array",
          "default": [],
          "items": {
            "type": "string",
            "pattern": "^[a-z0-9*]([a-z0-9-.*])*[a-z0-9*]$"
          },
          "description": "Hostnames the sandbox is allowed to reach. Enforced at the VM boundary."
        },
        "env": {
          "type": "array",
          "default": [],
          "items": { "$ref": "#/$defs/envRequirement" },
          "description": "Env vars the operator must supply. `openneko install` prompts for required ones and refuses to complete if missing."
        }
      }
    },
    "envRequirement": {
      "type": "object",
      "required": ["key", "description"],
      "additionalProperties": false,
      "properties": {
        "key": {
          "type": "string",
          "pattern": "^[A-Z][A-Z0-9_]*$",
          "maxLength": 64,
          "description": "UPPER_SNAKE_CASE env var name the plugin reads."
        },
        "required": { "type": "boolean", "default": true },
        "secret": {
          "type": "boolean",
          "default": true,
          "description": "Hide the value at prompt; the CLI will not echo it back."
        },
        "description": {
          "type": "string",
          "minLength": 1,
          "maxLength": 280
        }
      }
    },
    "capabilities": {
      "type": "object",
      "description": "Surfaces this plugin contributes. The keyset declares what the plugin does — `action` and/or `auth`. At least one must be present.",
      "additionalProperties": false,
      "minProperties": 1,
      "properties": {
        "action": {
          "type": "object",
          "description": "The plugin contributes one or more named action handlers.",
          "required": ["kinds"],
          "additionalProperties": false,
          "properties": {
            "kinds": {
              "type": "array",
              "minItems": 1,
              "items": { "$ref": "#/$defs/actionDeclaration" }
            }
          }
        },
        "auth": {
          "type": "object",
          "description": "The plugin acts as the SSO provider. Singleton — only one installed plugin may declare this.",
          "additionalProperties": false,
          "properties": {
            "providerLabel": {
              "type": "string",
              "minLength": 1,
              "description": "Short label rendered on the sign-in button (e.g. \"Scalekit\", \"Okta\")."
            }
          }
        }
      }
    },
    "actionDeclaration": {
      "type": "object",
      "required": ["kind", "description"],
      "additionalProperties": false,
      "properties": {
        "kind": {
          "type": "string",
          "pattern": "^[a-z][a-z0-9_]*$",
          "description": "Snake_case action identifier."
        },
        "description": {
          "type": "string",
          "minLength": 1,
          "description": "Short description the agent uses to pick this kind."
        },
        "default_mode": {
          "description": "Seeded approval policy when the plugin is freshly installed. auto = run inline with no human gate (read-only kinds). ask = suspend agent turn, render approval card to the user (externally observable kinds). deny = never invokable without explicit opt-in. Operators can override later in /settings/rules. Defaults to ask when omitted — safer to surprise the user with a prompt than a side effect. Accepts either a scalar (applies to all scopes) or a per-scope object {external?, internal?} when the kind needs different defaults depending on the scope it's invoked under.",
          "oneOf": [
            { "type": "string", "enum": ["auto", "ask", "deny"] },
            {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "external": { "type": "string", "enum": ["auto", "ask", "deny"] },
                "internal": { "type": "string", "enum": ["auto", "ask", "deny"] }
              }
            }
          ]
        }
      }
    }
  }
}