Skip to main content
Endpoint Provider Registry lets you plug custom server-side providers (recipe, agents-api, MCP, A2A, openai-compat, and your own) into PraisonAI via a single Python entry-point group — no fork required. Publish once under praisonai.endpoint_providers. One plugin is then visible to get_provider(), praisonai endpoints types, and praisonai endpoints invoke --type.
A plugin published once under praisonai.endpoint_providers reaches both the provider registry and the CLI dispatch surface.

Quick Start

1

Use a built-in provider

2

Register at runtime

3

Distribute as a pip plugin


How It Works

The registry is thread-safe and loads plugins lazily. Built-ins are discovered on first access, entry points are loaded when needed, and aliases are case-insensitive. The singleton registry is obtained via get_default_registry().

One Group, Two Readers

There is one canonical entry-point group: praisonai.endpoint_providers. Two readers scan it — the top-level provider registry (instantiates BaseProvider classes for serve / discovery) and the CLI dispatch registry (resolves endpoints invoke --type). One plugin contract serves both surfaces; the CLI adapts your BaseProvider subclass into its internal dispatch shape.

Built-in Dispatch Keys

praisonai.endpoints.providers is a deprecated alias. It is still scanned, but importing a plugin published under it emits a DeprecationWarning naming the canonical group. On a name clash the canonical group wins.Since PraisonAI PR #4185 the built-in guard also applies to this legacy path: a plugin published under the deprecated praisonai.endpoints.providers group cannot replace the built-in mcp provider either. The only override path is runtime register(...). Publish new plugins under praisonai.endpoint_providers.

Which Group Do I Publish Under?


Migration From the Deprecated Group

Rename the entry-point group in your pyproject.toml. The class and its methods are unchanged.
Deprecated-group or not, built-in names stay protected — a plugin named mcp under the legacy group cannot replace the built-in mcp provider (since PR #4185). Constants exported by praisonai/endpoints/registry.py:

Streaming

Implement invoke_streamnot invoke(stream=True) — to support --stream. When --stream is passed the CLI adapter calls provider.invoke_stream(name, input_data, config), which yields {"event": ..., "data": ...} frames. An event == "error" frame prints the error and returns exit code 3 (runtime error); other frames print as [event] data and it returns 0.

Configuration / API

Functions

ProviderRegistry Class

Built-in Provider Types


Common Patterns

The runtime register_provider() path is last-write-wins — it can replace a built-in in the current process:
A pip-installed plugin cannot override a built-in. The CLI dispatch registry re-asserts its built-in loaders after entry-point discovery, so an entry point may add a new type but never replace a shipped one (recipe, mcp, openai-compat, …). This inverts the base PluginRegistry precedence, where entry points normally override built-ins. Only the runtime register_provider() call above overrides.
Use the underlying PluginRegistry for alias support:
Instantiate ProviderRegistry directly for isolation:

Best Practices

Never import your provider class at module top-level — defeats lazy loading and breaks the no-heavy-deps-at-import-time guarantee:
Required for type compatibility and consistent API:
get_provider("unknown") returns None, but import failures propagate:
Use pyproject.toml entry points instead of register_provider() calls:

Integration Registry

The sibling plugin registry for CLI tools / managed agents

Framework Adapter Plugins

Third sibling plugin registry, for framework adapters