Build a Plugin
Plugins let a Navigic agent call an external service through a reviewed,
versioned contract. A plugin is not loaded into Navigic as arbitrary code. It is
a service you operate, described by a manifest, and called through the
navigic.plugin/v1 protocol.
Current Availability
Plugin development is in managed preview. You can build a conforming plugin service and share its manifest URL with Navigic for review. Self-serve plugin registration, marketplace discovery, and dashboard installation for third-party plugins are not generally available yet.
If your goal is to connect a reviewed plugin to a workspace, start with Install a Plugin.
Scaffolded Development Loop
Navigic's public development loop is being introduced in stages. The first developer-facing milestone is scaffolding and local validation:
navigic plugin init hello-action
cd hello-action
npm install
npm test
navigic plugin validate
navigic plugin dev
navigic plugin execute create_ticket --input fixtures/execute/create-ticket.jsonThis loop should let you build a conforming remote HTTP plugin without access to
private Navigic repositories. It validates the manifest, starts a local host
simulator, issues fake operation-scoped credential leases, and executes the
plugin through the same navigic.plugin/v1 envelope used by hosted workspaces.
Local success is not production approval. Production installation still requires Navigic review, verified publisher metadata, link and manifest checks, and a workspace install path enabled by Navigic.
What You Build
A remote HTTP plugin should expose these routes:
| Route | Purpose |
|---|---|
GET /.well-known/navigic-plugin.json | Returns the immutable plugin manifest. |
GET /health | Reports whether the plugin service is ready. |
POST /navigic/plugin/v1/execute | Executes one manifest operation for the Navigic host. |
Provider-facing routes, such as OAuth callbacks or webhooks, are plugin-specific.
For example, a Slack plugin may also expose /slack/oauth/callback and
/slack/events.
Build Steps
-
Choose the narrow job the plugin performs.
Start with one or two operations. Give each operation a stable
operationId, model-facingtoolName, JSON input schema, side effect, risk level, required scopes, approval default, and idempotency behavior. -
Publish a manifest.
The manifest declares the plugin's protocol version, package version, structured publisher, required license, trust links, release metadata, runtime routes, auth scheme, permissions, data use, operations, events, outbound domains, and redaction fields.
{ "apiVersion": "navigic.plugin/v1", "kind": "PluginManifest", "metadata": { "name": "example-support", "version": "0.1.0", "displayName": "Example Support", "description": "Create and read support tickets.", "license": "Proprietary", "publisher": { "id": "example-inc", "displayName": "Example Inc.", "type": "community_preview", "website": "https://example.com", "verifiedDomain": "example.com", "verificationStatus": "pending", "supportUrl": "https://example.com/support", "contactEmail": "support@example.com" } }, "links": { "homepageUrl": "https://example.com/navigic-plugin", "docsUrl": "https://example.com/navigic-plugin/docs", "installGuideUrl": "https://example.com/navigic-plugin/install", "configurationGuideUrl": "https://example.com/navigic-plugin/configure", "changelogUrl": "https://example.com/navigic-plugin/changelog", "supportUrl": "https://example.com/support", "privacyPolicyUrl": "https://example.com/privacy", "termsUrl": "https://example.com/terms", "securityUrl": "https://example.com/security", "repositoryUrl": "https://github.com/example/example-support-plugin" }, "release": { "version": "0.1.0", "releasedAt": "2026-07-22T00:00:00.000Z", "releaseNotes": "Initial preview release.", "breakingChanges": [], "migrationNotes": [] }, "hostCompatibility": { "protocolVersions": ["navigic.plugin/v1"], "navigicMinVersion": "0.1.0" }, "runtime": { "kind": "remote-http", "wellKnownPath": "/.well-known/navigic-plugin.json", "executePath": "/navigic/plugin/v1/execute", "healthPath": "/health" }, "auth": { "schemes": [ { "type": "service-token", "purpose": "Authenticate Navigic host-to-plugin execute requests." }, { "type": "api-key", "provider": "example-support", "location": "credentialLease", "scopes": ["tickets:write"], "purpose": "Use a short-lived operation-scoped provider credential lease.", "credentialLeaseFields": ["apiKey"] } ] }, "operations": [ { "operationId": "create_ticket", "toolName": "example_support__create_ticket", "displayName": "Create Ticket", "description": "Create a customer support ticket.", "inputSchema": { "type": "object", "properties": { "subject": { "type": "string" }, "body": { "type": "string" } }, "required": ["subject", "body"], "additionalProperties": false }, "outputSchema": { "type": "object" }, "sideEffect": "external-send", "risk": "external-write", "requiredScopes": ["tickets:write"], "approval": { "defaultMode": "ask" }, "idempotency": "required", "modelHints": { "readOnlyHint": false, "destructiveHint": false, "openWorldHint": true } } ], "permissions": { "providerScopes": [ { "provider": "example-support", "scope": "tickets:write", "purpose": "Let an approved agent create a ticket for handoff.", "dataAccess": ["ticket subject", "ticket body", "workspace metadata"], "operations": ["create_ticket"], "required": true, "risk": "external-write", "providerDocsUrl": "https://example.com/docs/scopes/tickets-write" } ], "outboundDomains": [ { "domain": "api.example.com", "purpose": "Create tickets through the Example Support API.", "dataCategories": ["ticket subject", "ticket body", "workspace metadata"] } ] }, "dataUse": { "collectedDataCategories": ["ticket subject", "ticket body", "workspace metadata"], "processedDataCategories": ["ticket subject", "ticket body"], "storedDataCategories": ["installation metadata", "activity and audit records"], "retention": "Retained as needed to operate the workspace and support audit or deletion requests.", "sharedWith": ["Example Support"], "humanAccess": "Example and Navigic support operators may inspect redacted operation metadata for support.", "modelExposure": "Ticket subject and body may be model-visible when the agent invokes the operation.", "deletionInstructions": "Revoke the plugin installation and request ticket deletion in Example Support." }, "outboundDomains": ["api.example.com"], "observability": { "redactFields": ["authorization", "access_token", "credentialLease"] } } -
Implement the execute endpoint.
Accept only authenticated host calls. Validate the request, enforce operation support, reject expired credential leases, require idempotency keys for write operations, and return a structured success or failure result.
{ "protocolVersion": "navigic.plugin/v1", "requestId": "req_123", "workspaceId": "workspace_123", "installationId": "install_123", "pluginId": "example-support", "pluginVersion": "0.1.0", "operationId": "create_ticket", "toolName": "example_support__create_ticket", "input": { "subject": "Billing question", "body": "The customer needs help with an invoice." }, "idempotencyKey": "workspace_123:req_123:create_ticket", "deadlineAt": "2026-07-21T20:00:00.000Z" } -
Keep credentials out of model-visible data.
Long-lived customer credentials belong in Navigic's host-side installation store or in the provider account you operate. Runtime calls should use a short-lived
credentialLeaseor a host service token, not raw customer secrets in prompts, transcripts, or logs. -
Test the plugin as a protocol boundary.
At minimum, test manifest validation, health, authentication failure, unknown operations, invalid input, expired leases, write idempotency, provider rate limits, and redacted logs.
Agent Enablement
An agent should grant specific plugin operations, not the whole provider. In an agent spec, the capability is operation-level:
capabilities:
pluginOperations:
- pluginId: example-support
operationId: create_ticket
versionRange: ^0.1.0The compiler lowers that into a bundle tool entry and a policy allowlist such as
example-support.create_ticket.