Connectors
Build your own connector
Connect your own MCP server, turn an OpenAPI description or a few REST calls into a connector, or import a skill. For self-hosted installations, ship a connector as a manifest. With the full manifest reference.
The catalog covers the common systems. Every company also has its own: an in-house service desk, a machine-data server from an IoT vendor, a set of written rules for quotes. You connect these yourself, without waiting for a release, and they get the same treatment as catalog connectors: rights checks on every call, confirmation before writing, keys that stay on the server.
Brandt & Söhne does both. Their IoT vendor runs an MCP server for machine data, which Mia Schulz from production adds by address and shares with the role “Fertigung” (production). Their service desk has a REST API with an OpenAPI description, which Tom Keller imports in five minutes, picking only the operations the AI Assistant should have.
Choose a way
Section titled “Choose a way”| You have | Build | Where to start |
|---|---|---|
| The address of a remote MCP server, or a configuration block from Claude Desktop, Cursor, opencode or VS Code | An MCP connector | New › MCP connector or Paste JSON |
| An API with an OpenAPI 3 or Swagger 2 description | A connector from OpenAPI | New › From OpenAPI |
| An API with documentation but no description file | A connector from REST actions | New › REST actions |
| A recurring task you can describe in words | A skill | New › Import skill |
| A self-hosted installation and a connector every tenant should get | A manifest that ships with the build | Ship a connector as a manifest |
All four start on AISet up AIConnectors: the button New in the action bar opens the menu. What you build appears on the tab My connectors and, for everyone you share it with, in the connector menu of the chat.

Before you start
Section titled “Before you start”- You need the right
ai.plugin.create. To share with anyone else, you also needai.plugin.share. - The server or API must be reachable from the nexxus server, not just from your computer. Every call, including the connection test, comes from there.
- A target inside your company network needs a release under Network allowlist. An admin sets that up, see Reach systems in your own network.
Connect an MCP server
Section titled “Connect an MCP server”MCP (Model Context Protocol) is a standard way for a server to offer tools to an AI. If a vendor or your own team runs an MCP server, nexxus can use its tools as they are. nexxus speaks to remote servers over Streamable HTTP or the older SSE. Local servers that run as a program on someone’s computer (command and args in a configuration) are not supported, because nexxus does not start foreign processes on its server.
Add the connector
Section titled “Add the connector”-
On AISet up AIConnectors, click New › MCP connector. The page New MCP connector opens on the tab Form.
-
Fill in Server:
- Name: how the connector appears in the selection, at most 120 characters.
- Address: the MCP address, usually ending in
/mcpor/sse. It must start withhttp://orhttps://. - Description: what it is for. The AI Assistant reads it too.
- Transport: Streamable HTTP, or SSE (older servers).
- Short name: the prefix of the tool names, lower-case letters, digits and hyphens, at most 40 characters. Empty means it is derived from the name.
- Sign-in: None, Headers (e.g. API key) or OAuth (dynamic registration). See Sign-in options.
-
Click Create. nexxus saves the connector and tests it right away. The save never fails because the server did not answer: the connector keeps the result and shows it.

Paste a configuration instead
Section titled “Paste a configuration instead”Many MCP servers come with a configuration block for desktop AI clients. Paste it as it is: New › Paste JSON, then Read.
{ "mcpServers": { "maschinendaten": { "url": "https://mcp.iot-vendor.example/mcp", "headers": { "Authorization": "Bearer replace-with-your-token" } }, "local-files": { "command": "npx", "args": ["some-local-mcp-server"] } }}nexxus shows One connector found for maschinendaten, marked with headers, and One entry rejected for local-files with the reason Local server (command/args): it runs on your computer, not on our server, and we do not start foreign processes there. For each found entry, click Check in form to review it or Create to save it directly. Nothing is saved until you do.
nexxus understands the formats of Claude Desktop and Cursor (mcpServers), opencode (mcp with type: remote) and VS Code (servers), single entries, lists of entries and bare "name": {...} fragments copied out of a larger file. Comments, trailing commas and single quotes are tolerated. One paste may hold up to 50 entries. An address that is still a template, such as http://IP:PORT/mcp, is rejected with The address is a placeholder (e.g. IP:PORT). Please enter the real address.

Sign-in options
Section titled “Sign-in options”| Sign-in | Credentials | How it works |
|---|---|---|
| None | The server needs no key. | |
| Headers (e.g. API key) | Shared: everyone uses the stored key | You enter header name and value once (Add header, up to 30). Everyone who uses the connector works with that key. |
| Headers (e.g. API key) | Per person: everyone stores their own | You list the header names under Headers each person fills in, comma-separated, for example Authorization. Each person enters their own values under My credentials or when connecting. Fixed headers for everyone can sit next to them. |
| OAuth (dynamic registration) | Each person signs in to the server on first use. nexxus registers itself as a client with the server, so there is no app to set up. |
Header values are stored encrypted and never shown again. Headers that the connection sets itself, such as the content type, cannot be overridden. If the address uses plain http://, the form warns The address is unencrypted http://. Keys only go there if an admin listed the target in the network allowlist.
If the server refuses dynamic registration, the connect-error dialog says {name} does not allow automatic sign-in. Switch the connector to headers if the server also takes an API key, or ask the operator to enable dynamic client registration.
Test the connection
Section titled “Test the connection”Under Test connection, click Test connection. The test runs from the server, where the real calls will come from later, and walks through six stages: DNS, Connect, TLS, HTTP, MCP start and Tool list. The result is Connection works or Connection failed with the stage that failed, plus Server, Protocol, Encrypted, Response time and the number of Tools. You can test before saving: the form’s values are used, and stored header values stand in for fields you left empty.

Choose the tools
Section titled “Choose the tools”Tools lists what the server offers, with a checkbox per tool (Use {tool}) and a choice Read or Write. A tool counts as reading only when the server marks it read-only. Everything else counts as writing, and writing tools ask before every call.
- If the connector is shared with nobody (Only me), you can switch the confirmation off for a writing tool: Off: this tool writes without a card. Only while the connector is yours alone. As soon as you share it, writing tools ask again.
- Try opens Try {tool}: a form built from the tool’s input description and Call, which makes one real call (at most 30 seconds) and shows the result as JSON. Owners and co-managers can try tools. It is available after saving.
If the list is empty, it says No tools known yet. “Test connection” fetches the list from the server.

Share it
Section titled “Share it”Sharing decides who may use the connector. Whoever may not, does not see it either.
| Option | Who may use it |
|---|---|
| Only me | Only you and the co-managers |
| Specific people | The people you pick |
| Roles | Everyone with one of the roles |
| Business unit | Everyone in the unit and below |
| Whole company | Everyone in this tenant |
Every option except Only me needs the right ai.plugin.share. Without it the options are locked: Sharing needs the permission “Share with others”. When you share a connector with a shared key, the form warns: Everyone you share with works with your key, and so with your permissions at the provider. To avoid that, use per-person credentials.
Below the sharing options:
- Co-managers may change settings and sharing, but not delete or transfer.
- Connector On or Off: switched off, it disappears from everyone’s selection and the data stays.
- Preselected in new conversations: whoever may use it has it ticked in new conversations.
- Ask before first use (on by default): data leaves this installation, so the person agrees once per conversation before the first call.
The same sharing options apply to connectors from OpenAPI, REST actions and imported skills.

Keep it running
Section titled “Keep it running”- Health check every 15 minutes. nexxus tests every switched-on connector as its owner and refreshes the tool list. When a connector that worked starts failing, the owner gets one notice in the bell and by e-mail, once per outage. Each owner decides under My profileNotifications, section Own MCP connectors unreachable.
- Moving to another server. Only the owner or a connector admin can point the address at another server. Stored header values are not carried over, and everyone’s own credentials and sign-ins for the connector are dropped. Whoever uses it connects again.
- Advanced. Timeout (ms) between 1,000 and 120,000 for slow servers. Own CA certificate (PEM) for servers with a certificate from your company’s certificate authority.
- Transfer ownership. Under Transfer ownership, pick a person who may create connectors and click Transfer. You stay a co-manager but lose the right to delete and transfer.
- When the owner leaves. A connector whose owner was deleted, has a pending invitation or became a service account passes to the tenant’s first administrator. It is never deleted, because others may depend on it.
- Limits. Each person can own up to 50 connectors (administrators have no limit).
Build a connector from an OpenAPI description
Section titled “Build a connector from an OpenAPI description”An OpenAPI description lists every operation of an API with its parameters. nexxus turns the operations you pick into actions.
-
Click New › From OpenAPI. The page Connector from OpenAPI opens.
-
Under Specification, choose Address and enter the URL of the description (for example
https://servicedesk.brandt.example/openapi.json), or choose Paste and paste it. JSON and YAML both work. If the API shows its description only to signed-in callers, choose Token or User name and password under Access to the address and enter the credentials. Click Read. -
Under Operations, pick what the AI Assistant may do. Every picked operation becomes an action. Reading operations (GET) are preselected, everything else counts as writing and asks before every call. All ({count} of {total}) picks or clears all.
-
Under Name and description, check the name and describe in one sentence what the connector is for. The AI Assistant reads the description.
-
Set Sharing and click Create. nexxus opens the new connector’s page.

What nexxus takes from the description:
| From the description | Becomes |
|---|---|
servers[0] | The base URL. If there is none, you are asked for one. |
| Each operation you pick | One action. GET reads, POST, PUT, PATCH and DELETE write. |
| Path, query and header parameters, a JSON request body | The action’s inputs |
| Security schemes | The sign-in, with the fields each person fills in when connecting. When there are several, nexxus takes the one most operations require. |
Left out: references to other files, callbacks, form-encoded bodies and cookie parameters. The description may be up to 5 MB. OpenAPI 3.0, 3.1 and Swagger 2.0 are supported. A pasted description is not stored: to change the operations later, paste it again and read it in.
nexxus sends the Access to the address only when it reads the description, never with the calls of the actions. It is stored encrypted and never shown again; an empty field keeps the stored value. If you move the address to another server, nexxus drops it. How each person signs in to the API itself is set separately, by the security schemes.
Build a connector from REST actions
Section titled “Build a connector from REST actions”When an API has documentation but no description file, you describe the calls yourself. A handful of well-described actions often serves the AI Assistant better than a full import.
-
Click New › REST actions. The page Connector from REST actions opens.
-
Under API, enter the Base URL (for example
https://servicedesk.brandt.example/api/v1) and choose the Sign-in: None, API key or User name and password. With a key or a login, each person stores their own credentials when connecting.For an API key, choose under Send the key as how the API expects it: Bearer token (Authorization header), Own header or Parameter in the address. For the last two, enter the Header or parameter name from the API’s documentation,
x-api-tokenfor Pipedrive for example. When the API refuses the key, the AI assistant says so with the provider’s reason, for example that it refused the credentials (401) withunauthorized access. If the key is right, Send the key as is usually wrong. -
Under Actions, describe each call:
- Method (GET, POST, PUT, PATCH, DELETE) and Path, for example
/tickets/{id}. Placeholders in braces need an input of the same name. - Read or Write. Writing actions always ask before they run.
- Key (e.g. search_deals): lower-case letters, digits and underscores, starting with a letter. It becomes part of the tool name.
- Name and What the action does and returns. The description decides whether the AI Assistant uses the action well, so say what it is for and what comes back.
- Inputs with Add input: Input (name), Type (string, integer, number, boolean, array, object), Location (Query, Path, Body, Header), Required and Description.
Add more calls with Add action.
- Method (GET, POST, PUT, PATCH, DELETE) and Path, for example
-
Fill in Name and description and Sharing, then click Create.

For the service desk, two actions are enough to start with:
| Key | Method and path | Kind | Inputs |
|---|---|---|---|
search_tickets | GET /tickets | Read | q (string, query, required): search text |
create_ticket | POST /tickets | Write | subject (string, body, required), body (string, body, required) |
Rules for your own connectors
Section titled “Rules for your own connectors”These apply to connectors from OpenAPI and from REST actions alike.
- They run like catalog connectors. nexxus checks them against the same rules as the connectors it ships: an
https://base URL (or a value from the configuration), confirmation for every writing action, tool names of at most 64 characters. - Their connections are their own. A connector you build always gets its own connections. It can never receive the token of a catalog connector, even if it describes the same provider.
- The address is the owner’s decision. If a change moves any address of the connector to another server, only the owner or a connector admin can save it. Stored secrets for the old address are dropped, and every connection is revoked with the note
Die Adresse des Connectors hat sich geändert. Bitte neu verbinden.(the connector’s address changed, please reconnect). - The base URL is checked on save. A fixed base URL that the network rules block is refused when you save, so you learn about it before someone tries it in a chat.
Import a skill
Section titled “Import a skill”A skill is written know-how: the steps and rules for a recurring task, in Markdown. It can name the connectors it needs, and switching the skill on in a conversation switches those on with it. As long as the skill is on, its instructions go with every message.
A skill is a SKILL.md file with a short front matter. This is the one nexxus ships for polishing a text (shortened):
---name: text-glaettendescription: Glättet einen Text sprachlich, ohne Ton und Aussage zu verändern, zum Beispiel ein diktiertes Transkript.---
# Text glätten (Lektor)
Ziel: der Text liest sich flüssig und fehlerfrei, klingt aber weiter nach der Person, die ihn geschrieben oder diktiert hat.
Korrigieren:
- Rechtschreibung, Grammatik, Zeichensetzung, Groß- und Kleinschreibung- Füllwörter, Wiederholungen und abgebrochene Sätze aus gesprochener SpracheThe front matter takes name, slug and description. A skill with extra files (templates, examples) comes as a ZIP with the SKILL.md at its root or in one folder:
Directoryangebot-wartung.zip
Directoryangebot-wartung
- SKILL.md
- vorlage-wartungsvertrag.md
Directorybeispiele/
- …
-
Click New › Import skill.
-
Under Skill file, click Choose file and pick the
.mdor.zipfile. -
Under Required integrations, tick the installed connectors the skill needs. They are switched on as soon as the skill is used in a conversation.
-
Set Sharing and click Import.

A ZIP may hold up to 2,000 files, at most 25 MB each and 100 MB unpacked. A skill can name up to 20 required connectors. To change the instructions, import the file again or use Open skill. On the connector you can change sharing, on and off, and the required connectors.
Ship a connector as a manifest
Section titled “Ship a connector as a manifest”On a self-hosted installation, developers can add a connector to the catalog itself, for every tenant. A catalog connector is a folder with a manifest and an icon in the backend resources:
Directorybackend/src/main/resources/plugins/
Directoryservicedesk/
- plugin.yml the manifest
- icon.svg or icon.png, required
- SKILL.md only for skills
nexxus reads every plugins/<key>/plugin.yml at start. The folder name must equal the manifest’s key. A manifest that does not parse or does not validate is left out with an error in the log (Plugin-Manifest plugins/<folder>/plugin.yml wird ignoriert: ...), so one broken file never stops the server. The build’s test suite rejects it before it ships. An admin then installs the connector like any other.
A minimal manifest
Section titled “A minimal manifest”This is the Perplexity connector as it ships, cut down to one of its six actions. It signs in with an API key that each person or an admin enters, calls a REST API and shortens the answer to the fields the AI Assistant needs.
schema: 1key: perplexitykind: integrationstatus: availablename: Perplexitydescription: Websuche mit Quellenangaben, schnelle Antworten und ausführliche Recherchen über die Perplexity-API.category: media_aivendor: PerplexitydocsUrl: https://docs.perplexity.ai/api-reference/agent-postdataFlow: Anfragen gehen mit dem API-Schlüssel direkt an die Perplexity-API (api.perplexity.ai); jede Anfrage wird dem Perplexity-API-Projekt berechnet.tags: [perplexity, websuche, web search, recherche, research, quellen]auth: provider: perplexity type: api_key scope: user_or_tenant inject: in: header name: Authorization value: "Bearer {connection.token}"runtime: type: rest baseUrl: https://api.perplexity.ai helper: nonedefaultActive: falsetoggleable: trueconnectionFields: - { key: token, label: "Perplexity-API-Schlüssel", type: password, required: true, description: "Schlüssel von der Seite „API Keys“ in der Perplexity API Console" }actions: - key: search_web name: Web durchsuchen description: >- Durchsucht das Web und liefert eine Trefferliste mit Titel, URL, Textauszug (snippet) und Datum, ohne eigene Antwort. Verwenden, wenn Quellen, Links oder aktuelle Fundstellen gebraucht werden. Für eine formulierte Antwort ask verwenden. kind: read confirm: never method: POST path: /search input: - { name: query, type: string, required: true, location: body, description: "Suchanfrage" } - { name: max_results, type: integer, location: body, default: 10, min: 1, max: 20, description: "Anzahl Treffer" } output: pick: ["results[].title", "results[].url", "results[].snippet", "results[].date", "results[].last_updated"]i18n: en: name: Perplexity description: "Web search with citations, quick answers and in-depth research through the Perplexity API."German is the manifest itself. English goes into i18n.en, and the English app shows it. The action becomes the tool perplexity__search_web: the connector key with - replaced by _, two underscores, the action key.
Manifest reference
Section titled “Manifest reference”Unknown fields are rejected, so a misspelt field fails instead of doing nothing. nexxus reports every problem at once.
Top level
Section titled “Top level”| Field | Type | Required | Meaning |
|---|---|---|---|
schema | number | yes | Always 1 |
key | string | yes | [a-z0-9-], 2 to 63 characters, equals the folder name |
kind | tool, integration, skill | yes | The chip in the catalog |
name, description | string | yes | German. The description is what the AI Assistant reads to decide whether the connector fits. |
category | string | yes | builtin, microsoft, google, communication, docs_knowledge, projects, dev, crm_sales, support, hr, finance, commerce, marketing, data, storage, design, automation, media_ai, systaro or custom |
vendor, docsUrl | string | no | Shown on the connector page, docsUrl as Documentation |
dataFlow | string | no | One sentence on where the data goes, shown on the connector page |
status | available, planned | no | Default available. planned is a catalog card only. |
statusHint | string | no | Why a planned connector is not there yet |
tags | list | no | Lower-case search words |
popularSeed | number | no | Tie-break for Popular while nobody is connected yet |
defaultActive | boolean | no | Preselected in new conversations once installed. Default false. |
toggleable | boolean | no | false makes it a core connector: always on in every conversation. Default true. |
adminOnly | boolean | no | Only administrators see and use it |
installByDefault | boolean | no | Installed for every tenant until an admin uninstalls it. Only for tools and skills without a sign-in. |
auth | object | no | How it signs in, see below. Default: no sign-in. |
runtime | object | yes, except for skills and planned connectors | How it runs, see below |
actions | list | for rest | What the AI Assistant can do, see below |
triggers | list | no | What can start an AI schedule, see below |
config | list of fields | no | Values an admin enters under Configuration |
connectionFields | list of fields | for api_key, basic and session | What each connection enters, for example the API key |
instructions | string | skills | The instructions, or SKILL.md for a file next to the manifest |
requires, requiresAny | list of connector keys | no | Skills: all of requires are needed, at least one of requiresAny |
setup | object | no | Help on the connector page: admin and user (lists of steps), links (label, url with https) |
permissions | list | no | Permission groups, OAuth connectors only, see below |
i18n | object | no | Translations by two-letter language code, for example en with name, description, dataFlow, statusHint, setup, actions and permissions |
| Field | Meaning |
|---|---|
type | none, api_key, basic, session (a login form that answers with a session cookie), oauth2, oauth2_dcr (OAuth with dynamic client registration) or client_credentials |
scope | user (each person connects), tenant (one connection for everyone) or user_or_tenant (both, the person’s own wins). Default user. |
provider | The connection key. Connectors with the same provider and app share one sign-in, for example microsoft. Required for every type except none and oauth2_dcr. |
authorizeUrl, tokenUrl, revokeUrl | OAuth endpoints. https://, or starting with a value from the configuration such as {config.baseUrl}. |
scopes | What the sign-in asks for |
scopeSeparator | How the scopes are joined. Default a space. |
pkce | PKCE for the sign-in. Default true. |
authorizeParams | Extra parameters for the sign-in, for example access_type: offline |
inject | Where an API key or login goes: {in: header, name, value}, {in: query, name, value} or {in: basic, username, password}. Values take {connection.<field>} and {config.<field>}. |
login | session only: the login form. path (relative to runtime.baseUrl), method (default POST), body (form or json, default form), fields (name to value, values take {connection.<field>} and {config.<field>}), cookies (names to keep, default all), failIf (text that marks a refused login in the redirect target or the answer, for example authfail), ttlMinutes (how long the session is reused, default 20). Nexxus signs in once, sends the cookies with every call and signs in again when the system answers 401. |
runtime
Section titled “runtime”type | Fields | Meaning |
|---|---|---|
rest | baseUrl (https:// or {config.x}), helper (graph, google, slack, none), pagination, errorEnvelope, headers | Each action is one HTTP call. The helpers preset paging for Microsoft Graph, Google and Slack. pagination takes type: link, cursor (with cursorParam, nextPath), page (with pageParam), offset (with offsetParam, totalPath, itemsPath) or nextlink. errorEnvelope (okPath, messagePath, reconnectOn) is for APIs that report errors inside a successful answer. headers are static, never secrets. |
mcp | url (https:// or {config.x}), transport (streamable_http, sse), headers | The tools come from a remote MCP server and are discovered by nexxus. |
builtin | tools (patterns over tool names), remote | Claims tools the nexxus backend already has. Each action names the permission it stands for. |
gateway | toolType, endpoint, tools | Tools that run in the AI gateway. |
builtin and gateway refer to tools inside nexxus itself. A new connector for an outside system uses rest or mcp.
actions[]
Section titled “actions[]”| Field | Type | Required | Meaning |
|---|---|---|---|
key | string | yes | [a-z0-9_], starting with a letter or digit. The tool name <key>__<action> may be at most 64 characters. |
name | string | yes | Shown in the connector page and on the confirmation card |
description | string | yes | What it does and when to use it. This decides whether the AI Assistant finds it. |
kind | read, write | no | Default read |
confirm | always, default, never | no | Default: always for write, never for read. default asks like always. never is not allowed on a writing action. |
method | GET, POST, PUT, PATCH, DELETE | for rest | |
path | string | for rest | Starts with /. Every {name} in it needs a path input of that name. |
input | list | no | The parameters, see below |
output | object | no | pick: a list of paths such as data[].id that shrink the answer. maxChars: a limit on the text the AI Assistant reads, 20,000 characters by default. See Long answers. |
pagination | object | no | Paging of this action when it differs from runtime.pagination, same fields. {type: none} switches paging off for the action. For APIs whose endpoints answer in different shapes. |
input[] fields: name (required), type (string, integer, number, boolean, array, object; default string), required, location (path, query, body, header; default query for GET and DELETE, body otherwise), description, enum, default, min, max, items (for array), properties and requiredProperties (for object), both see below.
A list (type: array) describes one entry with items, as a JSON schema. Without items the AI Assistant only learns that the list holds text, and it sends text even where the API expects objects. The build’s tests therefore require items on every list of a shipped connector. For a list of text, items: { type: string } is enough. The recipients of Outlook Mail look like this:
- name: toRecipients type: array required: true location: body items: &recipient type: object properties: emailAddress: type: object properties: address: { type: string } name: { type: string } required: [address] required: [emailAddress]An object (type: object) describes its fields with properties: a JSON schema per field name, as in items, nested as deep as needed. A list inside an object again needs items, and the tests check that too. requiredProperties names the fields the API demands, for example requiredProperties: [id] on the parent folder in Box; required still only says whether the object itself is required. Fields that properties does not name still pass. A YAML anchor (&recipient above) saves writing the same schema twice. The message of Outlook Mail’s send_mail:
- name: message type: object required: true location: body properties: subject: { type: string } body: type: object properties: contentType: { type: string } content: { type: string } toRecipients: { type: array, items: *recipient } ccRecipients: { type: array, items: *recipient } importance: { type: string, enum: [low, normal, high] }The AI gateway checks every call against this schema and hands any mismatch back to the AI Assistant. Set required, requiredProperties and enum only where the API really demands them, or valid calls fail too. A field the API clears with null gets no type, only a description: otherwise the gateway drops the null, and the field stays as it was.
Long answers
Section titled “Long answers”The AI Assistant reads an action’s answer as text, at most output.maxChars characters. pick runs first and keeps only the named fields, so more entries fit.
When a JSON answer is longer, nexxus cuts it at whole entries of its longest top-level list, such as value in Microsoft Graph or an answer that is a list itself. The other fields stay, and the answer stays valid JSON. A note before the data gives the number of entries shown and in total, so the AI Assistant does not take the list for complete: TEILERGEBNIS when the action can continue, UNVOLLSTÄNDIG otherwise. If the first entry alone is too long, nexxus shows it cut. Everything else is cut by characters, with UNVOLLSTÄNDIG: gekürzt auf n von m Zeichen: text, JSON without a top-level list, and a list whose only entry is too long. The notes are in German, like the manifest.
The AI Assistant reads on in a cut list. The result then ends with “Weitere Ergebnisse” (more results) and a value for the nextPage input:
Termine im Zeitraum auflisten, HTTP 200:TEILERGEBNIS: Die Liste „value“ zeigt hier Einträge 1 bis 40 von 118. Die übrigen 78 folgen mit „Weitere Ergebnisse“ am Ende. Nicht als vollständig behandeln: wo der Rest zählt, erst weiterlesen.{"value":[...]}
Weitere Ergebnisse: dieselbe Aktion mit denselben Angaben und {"nextPage":"fortsetzung:40:118:3f2a9c1d:value"} aufrufen.With that value and the same arguments, the AI Assistant calls the action again and gets the entries from the first missing one on, behind a FORTSETZUNG note. nexxus stores nothing for this: it asks the API again and refuses a continuation with other arguments. If the list changed in between, the note says so. Only once the cut list is read to the end does “Weitere Ergebnisse” lead to the API’s next page.
Only read actions get the nextPage input, and with it the continuation, and only when one of these holds:
- The key starts with
list_,search_,find_orquery_, or containssearch. - A path in
output.pickcontains[]. - The action pages with its own
pagination,runtime.paginationor a helper. This applies to GET only.
Write actions and the other reads cut with UNVOLLSTÄNDIG and no continuation.
For connectors that ship with nexxus, the test PluginListPickSpec checks in the build:
- Every read action of a REST connector whose key marks a list or a search (as above) has an
output.pick. Otherwise it is listed inWITHOUT_PICKin that test, with the reason, for example because the request already chooses its fields ($select,fields, GraphQL). - A pick comes with a sample answer in the shape the vendor documents:
backend/src/test/resources/plugins/pick-samples/<connector>/<action>.json. Every path of the pick must find something in it, and the result must be smaller than the whole answer. Otherwise a path that finds nothing would drop its field without a word.
A path splits at every dot, so fields such as @odata.etag cannot be picked. nexxus reads the next page from the uncut answer, so @odata.nextLink need not be in the pick.
triggers[]
Section titled “triggers[]”| Field | Meaning |
|---|---|
key, name, description | As for actions |
mode | poll (nexxus calls a reading action at an interval) or webhook (the sender posts to an address) |
action | For poll: an existing reading action |
intervalMinutes | For poll: the default interval, at least 5 |
itemsPath | Where the list of new items sits in the answer, for example data.items[] |
dedupeKey | For poll, required: the path of an item’s id, so each item fires once |
promptTemplate | The German heading above the new items in the schedule’s message |
pollArgs | Fixed arguments for the polled action |
config | Fields the person fills in when setting up the trigger |
Fields in config, connectionFields and trigger config
Section titled “Fields in config, connectionFields and trigger config”| Field | Meaning |
|---|---|
key | [A-Za-z][A-Za-z0-9_], unique in the list |
label | Required. Shown as written, in German. |
type | string, text, url, password, number, integer, boolean, select |
required, default, placeholder, description | As the names say |
secret | Stored encrypted and never returned. Implied for password. |
options | For select: plain values, or {value, label, en} with a German and an optional English label |
A connector that signs in with oauth2 or client_credentials gets the fields clientId and clientSecret in its configuration even if the manifest does not list them.
permissions[]
Section titled “permissions[]”Permission groups exist only for oauth2 and oauth2_dcr connectors.
| Field | Meaning |
|---|---|
key, name, description | The group as people see it, for example “Mails senden” |
scopes | The scopes this group needs, a subset of auth.scopes |
actions | The actions it unlocks. Each action belongs to at most one group. |
required | Always requested and cannot be unticked |
default | Ticked when a person connects for the first time. Default true. |
Scopes in no group are always requested. Actions in no group are always available.
Validation messages
Section titled “Validation messages”The messages are in German. A few you will meet:
| Message | Fix |
|---|---|
key '...' muss dem Ordnernamen '...' entsprechen. | Rename the folder or the key so they match. |
icon.svg oder icon.png fehlt neben plugin.yml. | Add an icon next to the manifest. |
runtime.baseUrl '...' muss https sein (Platzhalter {config.x} erlaubt). | Use https:// or a configuration value. |
auth.type api_key braucht connectionFields oder ein geheimes config-Feld. | Say where the key comes from. |
actions....: confirm never ist nur für read erlaubt. | Writing actions must confirm. |
actions....: Werkzeugname ... ist länger als 64 Zeichen. | Shorten the connector key or the action key. |
actions.....input....: path enthält {...} nicht. | A path input needs its placeholder in path. |
triggers....: poll nur über read-Aktionen. | A trigger may only read. |
permissions gibt es nur für OAuth-Connectoren. | Remove the groups or switch to OAuth. |
What happens behind the scenes
Section titled “What happens behind the scenes”You save
nexxus checks the connector with the same rules as the catalog.
nexxus tests
For connectors: from the server, and stores the tool list.
A chat uses it
Tools come from the stored list, no extra round trip.
Every call is checked
Sharing, rights, confirmation and network rules, then the answer is marked as outside content.
- Tool names. MCP connector tools are named after the connector’s short name and the server’s tool name. Tools of your REST and OpenAPI connectors carry the connector’s prefix and the action key.
- Keys and tokens stay on the server. Header values, API keys and tokens are stored encrypted and never reach the model, the gateway or the browser.
- Results from outside are marked. The AI Assistant is told that what a server returns is information, not an instruction.
- Every request passes the network rules, including tests, OpenAPI downloads and redirects.
When something goes wrong
Section titled “When something goes wrong”The connection test fails
Section titled “The connection test fails”The test names the stage that failed and gives a German explanation:
| Message | Meaning and fix |
|---|---|
Der Servername lässt sich vom Server aus nicht auflösen. | The host name does not resolve from the nexxus server. Check the address, or whether the server is in a network nexxus can see. |
Adresse vom Server aus nicht erreichbar (...) | Nothing answers on that address from the nexxus server: a firewall, a closed port or no route. |
Die verschlüsselte Verbindung (TLS) kommt nicht zustande: ... | The certificate is not trusted. For a company certificate authority, add the CA under Own CA certificate (PEM). |
Anmeldung abgelehnt (401): Header prüfen, ... | The key is missing or wrong. Check the headers or My credentials. |
Zugriff verweigert (403): ... | The server knows the key but does not allow it. |
Unter dieser Adresse gibt es keinen MCP-Server (404). ... | Check the path, it often ends in /mcp or /sse. |
Antwortet, spricht aber kein MCP (...) | Try the other Transport. |
Private Adresse (...), für diesen Mandanten nicht freigegeben. | The address is inside a private network that is not released. Ask an admin to add it to the network allowlist. |
Unverschlüsseltes http:// ist nur für freigegebene interne Adressen erlaubt; bitte https:// verwenden. | Use https://, or have the internal address released with http allowed. |
Metadaten-Dienste der Cloud sind nie erreichbar. | Cloud metadata addresses are always blocked. |
Saving fails
Section titled “Saving fails”| Message | Fix |
|---|---|
Die Adresse enthält noch einen Platzhalter (z. B. IP:PORT). Bitte die echte Adresse eintragen. | Enter the real address. |
Die Adresse muss mit http:// oder https:// beginnen und einen Server nennen. | Correct the address. |
Höchstens 50 eigene Connectoren je Person. | Delete or transfer a connector you no longer need. |
Die Bestätigung von Schreibwerkzeugen lässt sich nur bei „Nur ich“ abschalten. | Switch confirmation back on before sharing. |
Keine Berechtigung, über „Nur ich" hinaus zu teilen. | You need ai.plugin.share to share. |
Die Spezifikation ist größer als 5 MB. | Split the description or paste only what you need. |
Das ist keine OpenAPI- oder Swagger-Beschreibung (Feld openapi bzw. swagger fehlt). | The file is not an OpenAPI description. |
Die Spezifikation nennt keinen Server; bitte die Basis-URL angeben. | Enter the base URL yourself. |
Keine SKILL.md im ZIP gefunden | Put the SKILL.md at the root of the ZIP or in its one folder. |
SKILL.md enthält keine Anweisungen | Add the instructions below the front matter. |