The ai-plugin.json Builder produces the manifest a plugin host reads to learn what your API is and how to call it. The manifest is small but strict — a malformed field or a wrong auth type stops installation. This tool gives you a guided form that emits a valid ai-plugin.json you can drop at /.well-known/ai-plugin.json on your domain.
How it works
The manifest is a flat JSON object with a fixed set of keys. The builder collects each one: schema_version (set to v1), name_for_human and name_for_model (the names shown to people and used by the model), description_for_human and description_for_model (short and model-facing summaries), an auth object whose type is none, user_http, service_http, or oauth, an api object pointing at your OpenAPI spec URL with type: openapi, plus logo_url, contact_email, and legal_info_url. The tool assembles these into correctly nested JSON, omitting nothing required and serializing with JSON.stringify so the output is always valid.
Understanding the key fields
name_for_human and name_for_model
These are two separate identifiers for different audiences. name_for_human is the label shown in
the plugin store or activation UI — it can include spaces, capitalisation, and punctuation. For
example: “Acme Email Assistant”.
name_for_model is the identifier the language model uses internally when it reasons about
whether to call your plugin. It should be short, lowercase or mixed case, and contain only letters,
numbers, and underscores. “acme_email” is correct; “Acme Email Assistant!” would break
identification. The model uses this name in its internal tool-calling logic, so a short, clear name
reduces ambiguity when multiple plugins are installed.
description_for_human vs description_for_model
description_for_human is the short marketing copy that users see in the plugin store — one or two
plain sentences about what the plugin does. description_for_model is different: it is instructions
to the model about when to use the plugin, what it can do, and what its limitations are. This is
the most important field for plugin behaviour, because it directly influences the model’s tool
selection. A well-written description_for_model names the situations the plugin is useful for and
the situations it is not, reducing both missing calls (the model doesn’t realise it should use the
plugin) and false calls (the model calls it when it shouldn’t).
Authentication types
The four auth types map to real API access patterns:
none— a fully public API that any caller can reach. Only appropriate if your API has no authentication at all.user_http— each user provides their own token. The host passes a user-specific bearer or basic token per API call. Use when your API has per-user accounts.service_http— a single shared service-level token. The host uses one credential for all calls. Use for service-to-service APIs where user identity is not relevant.oauth— a full OAuth flow. The most secure option for user-authorised access, and the most complex to implement.
Mismatch between the declared auth type and the API’s actual requirements is the most common cause of plugin installation succeeding but calls failing silently.
Tips and example
- Keep name_for_model short and alphanumeric. The model references the plugin by this identifier, so avoid spaces and punctuation —
acme_emailis fine,Acme Email!is not. - Write the model description for the model.
description_for_modelshould tell the model exactly when to use the plugin and any constraints, because that text steers its tool-selection behaviour. - Match the auth type to reality. If your API requires a per-user token, use
user_http; declaringnoneon a protected API breaks every call after install.
For example, a plugin named Acme Email with name_for_model set to acme_email, auth.type set to service_http, and an api.url pointing at https://acme.com/openapi.yaml produces a complete, install-ready manifest when the builder serializes it.