board/plugin-sdk

SDK and contracts for building Board Kanban plugins (Power-Ups).

Maintainers

Package info

github.com/B-o-a-r-d/Board-Plugin-SDK

pkg:composer/board/plugin-sdk

Transparency log

Statistics

Installs: 9

Dependents: 4

Suggesters: 0

Stars: 0

Open Issues: 0

v0.2.9 2026-07-22 09:58 UTC

This package is auto-updated.

Last update: 2026-07-23 12:55:26 UTC


README

Contracts and value objects for building Board Kanban plugins (Power-Ups).

PHP 8.3 License MIT

A Board plugin is an ordinary Composer package that depends on this SDK only — never on the host application. That's what lets plugins ship and version independently: composer require board/plugin-github, and Laravel package auto-discovery makes the Power-Up available with no core changes.

The host owns storage, the configuration UI, OAuth, list rendering, caching, realtime and the MCP server. Plugins stay thin: they describe themselves and implement the capabilities they support.

Install

composer require board/plugin-sdk

Capabilities

Every plugin implements Plugin. Capabilities are opt-in interfaces — the host inspects instanceof to know what a plugin can do.

Interface What the plugin can do
Contracts\Plugin Identity, icon, config fields, OAuth requirement (required)
Contracts\ProvidesListSource Feed a list with read-only "virtual cards" (commits, PRs, pipelines…)
Contracts\EnrichesCards Attach external refs to a card and resolve them into a status widget
Contracts\DefinesActivities Log activities and get a dedicated tab in the activity slide-over
Contracts\ProvidesMcpTools Contribute tools to the host's MCP server
Contracts\ProvidesOAuth Declare a provider's OAuth endpoints; the host drives the flow
Contracts\ProvidesCardFields Inject custom fields into cards (type, options, sidebar/content placement)
Contracts\ProvidesAutomationActions Contribute actions to the automation builder, run in the host's pipeline sandbox
Contracts\PluginContext (host-bound) let decoupled plugin code read board state safely

Value objects: PluginListItem — a read-only virtual card (title, subtitle, url, badge, badgeColor, icon, timestamp) — and PluginToast — a toast an automation action returns for the host to push to the acting user (message, description, type, duration, link actions opened in a new tab).

Building a plugin

  1. Implement Plugin (plus any capabilities):
use Board\PluginSdk\Contracts\Plugin;
use Board\PluginSdk\Contracts\ProvidesListSource;
use Board\PluginSdk\PluginListItem;
use Illuminate\Support\Collection;

class HelloPlugin implements Plugin, ProvidesListSource
{
    public static function key(): string { return 'hello'; }
    public function label(): string { return 'Hello'; }
    public function description(): string { return __('hello::messages.description'); }
    public function icon(): string { return 'hand-waving'; }      // phosphor icon name
    public function requiresOAuth(): bool { return false; }
    public function oauthProvider(): ?string { return null; }
    public function configFields(array $config = []): array { return []; }

    public function sourceModes(): array
    {
        return [['key' => 'greetings', 'label' => __('hello::messages.greetings')]];
    }

    public function listConfigFields(array $config = []): array { return []; }

    public function items(array $config, string $mode, array $sourceConfig): Collection
    {
        return collect(['Bonjour', 'Hello', 'Hola'])->map(fn ($g, $i) => new PluginListItem(
            externalRef: (string) $i,
            title: $g,
            icon: 'hand-waving',
        ));
    }
}
  1. Register it from a service provider by extending the SDK base — it wires the registry and loads your package's translations under the <key>:: namespace:
use Board\PluginSdk\Contracts\Plugin;
use Board\PluginSdk\PluginServiceProvider;

class HelloServiceProvider extends PluginServiceProvider
{
    protected function plugin(): Plugin { return new HelloPlugin; }
}
  1. Expose the provider for auto-discovery in your composer.json:
{
    "require": { "board/plugin-sdk": "^0.2" },
    "extra": { "laravel": { "providers": ["Vendor\\Hello\\HelloServiceProvider"] } },
    "autoload": { "psr-4": { "Vendor\\Hello\\": "src/" } }
}

That's it — composer require vendor/hello and the Power-Up shows up in Board → Power-Ups.

Translations

Plugins ship their own strings as files (never in the host core). The base PluginServiceProvider loads lang/ under the plugin key, so use __('hello::messages.some.key'). Provide lang/{en,fr,es}/messages.php.

MCP tools

Implement ProvidesMcpTools::mcpTools() returning your tool class-strings (each extending Laravel MCP's Tool). Require laravel/mcp in your package. Tools that need host state (a board's stored config) resolve it through the host-bound Contracts\PluginContext — so your tool never depends on the app.

Versioning

Semantic versioning per package. Breaking changes to these contracts bump the SDK major; plugins pin a range ("board/plugin-sdk": "^0.2").

License

MIT. See the Board app and the GitHub plugin for full examples.