Build a plugin
Build a plugin
Most plugins wrap an MCP server
Host your tools, describe the connection in two JSON files, then publish them in a public GitHub repository. Opisense reads the plugin files; it never runs code from the repository. Start with the MCP server example.
1. Host your server
Deploy your MCP server at a public HTTPS URL. Local stdio servers, localhost, and private
network endpoints are not supported in plugins. A repository containing server code alone
is not an installable plugin.
2. Create the plugin files
Put these two files at the repository root, or together in a folder:
mcp-server/
├── plugin.json
└── mcp.json
plugin.json:
{
"$schema": "https://agent-plugins.org/schemas/1.1.0/plugin.schema.json",
"name": "mcp-server",
"version": "1.0.0",
"description": "Search documentation through a hosted MCP server."
}
mcp.json:
{
"$schema": "https://agent-plugins.org/schemas/1.1.0/mcp.schema.json",
"mcpServers": {
"docs": {
"type": "streamable-http",
"url": "https://mcp.example.com/mcp"
}
}
}
Replace the example URL with your deployed endpoint; it is a placeholder, not a running
server. Each named server becomes a separate connection. streamable-http and sse are
supported. The MCP $schema version must match the plugin $schema version.
The manifest requires $schema and name. Names use 1–64 lowercase letters, digits, dots,
or hyphens, start and end with a letter or digit, and cannot contain -- or ...
version and description are optional, as are author (name, email, url),
homepage, repository, license, and keywords (an array of strings).
Authentication
MCP server entries accept only type, url, and optional headers, a map of HTTP header
names to string values. Use headers only for non-secret configuration, for example
"headers": { "X-Docs-Collection": "public" }. Never publish credentials in these files
or put them in the endpoint URL.
- OAuth: users choose Sign in on the installed server and authorize in the browser. Opisense discovers OAuth from the server; no OAuth fields belong in the plugin files. If dynamic client registration is unavailable, users can supply their registered client ID and optional secret under Manage MCP servers → Edit → Advanced.
- API key or bearer token: users open Integrations → Add custom → Manage MCP servers, choose Edit on the installed server, and expand Advanced. Use Access token (optional) for a bearer token or Header name / Header value for a custom header.
- Public tools: servers without authentication can work immediately.
There is no plugin secret declaration or setup form. ${VAR} placeholders are rejected,
not expanded or turned into prompts. Describe authentication requirements in your README.
3. Add an optional skill
A skill can teach bots when and how to use your tools. Add skills/search-docs/SKILL.md:
---
name: search-docs
description: Search the connected documentation server. Use when the user asks how a documented feature works or wants a source for an answer.
---
1. Search the documentation server's tools for the user's topic.
2. Read relevant results before answering and link the sources returned by the server.
3. If the server needs authentication, ask the user to connect it in Integrations.
Use the actual tool names and workflows your server exposes. Skills require nonempty YAML
name (up to 80 characters) and description (up to 2000). Keep skill names distinct from
each other and from Opisense's built-in skills.
4. Test in Opisense
- Publish your plugin files in a public GitHub repository. Private repositories and local folders are not supported sources.
- Open the account menu and choose Connect apps to open Integrations. Choose
Add custom → From GitHub, paste the repository URL as the Plugin GitHub URL, and
choose Preview. For a folder, use
https://github.com/example/plugins/tree/main/mcp-server. - Check the preview's servers, skills, and skipped parts. Choose Connect to install the connector and Add skills in the Skills section if you included skills.
- Sign in if needed. With a bot selected, choose Use in this bot for the server, then ask the bot to call a real tool. Verify a useful result and any companion skill.
Fix skipped parts before sharing. A valid config does not prove that tool calls or sign-in work. Installed content is pinned to a commit; if files change during preview, preview again.
5. Share it
Send people the repository or folder URL. They install it the same way, with Add custom → From GitHub in Integrations, or Add skill → From GitHub in Skills for a skills-only plugin.
Skills-only plugins
For a plugin without tools, copy the hello world example.
Keep plugin.json and at least one skills/<name>/SKILL.md; omit mcp.json. Publish and
preview it through the same GitHub flow, choose Add, then try the skill with a bot.
Optional commands/<name>.md files become skills invoked with /name; $ARGUMENTS is the
text after the command. Optional agents/<name>.md files use skill-style frontmatter and
become skills that instruct the bot to call run_subagent.
Compatibility and updates
Opisense also reads Agent Plugins 1.0.0 and legacy .cursor-plugin/plugin.json,
.grok-plugin/plugin.json or .claude-plugin/plugin.json manifests. Legacy formats use
mcp.json or .mcp.json and also accept http as an alias for streamable-http; a server
with a blank url names a connector the app supplies and is not installed. Component
locations are fixed; manifest fields cannot relocate them.
Editor hooks, rules, automations, local MCP execution, and skill scripts or binaries are
not supported. Text references beside a SKILL.md can be installed with it; symlinks and
submodules cannot. Keep the plugin small: at most 200 fetched component files, 100,000 bytes
per file, and 4,000,000 bytes total. Each skill allows up to 40 reference files totaling
400,000 bytes.
Existing installs remain pinned. To test an update, remove the installed plugin and install
again from the updated source. Changing version alone does not update installs.