MCP server for smabar (smart taskbar) — provides tools for bar state management, plugin control, screenshots, configuration, and plugin development guidance
smabar MCP server demonstrates solid definition quality with 16 well-named tools covering bar state, plugin lifecycle, settings, and UI capture. All tools have descriptions (avg 180 chars, within 10-1024 baseline) and explicit input schemas with typed parameters. Naming follows verb_noun convention (bar_get_state, plugin_set_active, settings_set). However, output schemas are not documented in the provided source, only input schemas are visible. Parameter descriptions are present but some lack constraint details (e.g., bar_set_position accepts 'top' or 'bottom' but this is stated in description, not as enum). Error handling guidance is minimal. Tool composition is strong: each tool has single responsibility, and outputs include IDs for chaining (e.g., bar_get_state returns tile IDs used by bar_screenshot). Risk annotations (READ_ONLY, WRITE, DESTRUCTIVE) are present but not formalized as toolAnnotations in the protocol.
Current bar state: layout, zOrder, language, theme, appearance, pluginOrder, pluginsHidden, pluginsDeactivated, shortcuts, effects, popups, MCP settings, settingsWindow dimensions, and all plugins with their status. The two off-switches are different things: pluginsHidden holds TILE ids that are hidden while their plugin keeps running, pluginsDeactivated holds PLUGIN ids with no process at all.
Screenshot of the bar itself — a PNG of the live window, nothing else on the desktop. Omit `target` for the whole bar, or pass a tile id from bar_get_state ("plugin:<pluginId>:<tileId>"), "shortcut:<id>", or an open surface ("flyout", "overlay", "settings", "popup"). "overlay" captures the visible secondary row in the solo layout. Scrollable content is expanded first, so a long flyout comes back complete instead of cut off at its scroll edge. Use scale 2-4 for small tiles; Windows magnifies its natural-resolution WebView2 preview, so larger scales add no detail. An unknown target answers with the list of targets that exist right now. Open a tile's flyout with bar_ui_state immediately before shooting it; the paired shot re-applies that open state through a brief render gap while a Plugin restarts.
Move the bar to the top or bottom screen edge (applies live; sets layout.position). Valid values: top, bottom.
Open or close a bar surface so it can be screenshotted: open_flyout (needs tileId), close_flyout, open_overlay (secondary row; requires the solo layout), close_overlay, open_settings (optionally with `group`; see the parameter schema for pages), close_settings. A successful open also prepares the immediately following screenshot of that surface, so a brief render gap while a Plugin restarts does not lose it.
Output schemas not documented. Tool descriptions explain what is returned (e.g., 'bar_get_state returns layout, zOrder, language, theme...') but formal output schema definitions are not visible in source. LLMs cannot reliably extract fields from unstructured descriptions.
Enum constraints stated in descriptions, not formalized in schema. bar_set_position accepts 'top' or 'bottom' (stated in description), bar_ui_state action param lists valid actions in description. Formal enum types in JSON Schema would prevent LLM hallucination of invalid values.
Risk annotations (READ_ONLY, WRITE, DESTRUCTIVE) are metadata but not formalized as MCP toolAnnotations (readOnlyHint, destructiveHint, idempotentHint). Protocol support exists but is not utilized.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 67 | <=2025-11-25 | v2 |
Search installed system families and the checked-in Google Fonts catalog. Write returned `cssStack` to the slot's family token. For Google, pair it with source token `google:<catalog-id>`; smabar canonicalizes the family, downloads it locally on theme activation, and keeps its fallback until ready. For system fonts, pair `cssStack` with source token `system`; shared themes fall back on hosts where that family is unavailable. `cached` is meaningful for Google entries because system entries are already local. Results default to 50 and are capped at 100.
Call a discovered plugin command and await its actual result (10 s timeout). Unlike plugin_action, this confirms handler completion. The plugin validates arguments and owns persistence. A timeout or disconnection means outcome UNKNOWN, not rollback: query state or retry with the SAME requestId if supported. Use plugin_commands first.
Discover a RUNNING plugin's commands, descriptions and input/output JSON Schemas. These operate on plugin data without editing code or restarting it. An empty list means the plugin has not registered commands.
Read a plugin's DATA directory (~/.smabar/data/<id>/) — what the plugin wrote at runtime: caches, downloads, SQLite databases, state. Without `path` you get a listing with sizes and modification times; with `path` (relative to that directory) you get one file's UTF-8 content. Files over 64 KiB and binary files, a SQLite database included, come back as metadata only — query those from inside the plugin and log the result with app.log, then read it via plugin_logs. Use plugin_read for the plugin's SOURCE code instead. Read-only: the plugin owns these files.
The START document for building a plugin: numbered golden-path steps, each with a checkable completion criterion and the reference it needs, plus the terms the other replies use, the markup rules in brief and the capabilities index (topics with read calls, live host services and providers). Call it without `section` first. `section` discloses one reference block instead: manifest (fields, optional app/cover icons, validation, the settings panel's renderable subset, multi-file plugins, the generated JSON Schema), sdk (every public smabar_sdk.Plugin member), storage (app.data_dir, SQLite, atomic writes, stale-while-refresh, network in a thread), lifecycle (startup order, the ONE handler lock, hot reload, no shutdown hook), debugging (plugin_list, plugin_logs, plugin_data, common failures), template (a complete multi-file plugin in write order), publishing (optional sharing of plugins AND themes), capabilities (the index alone), all (everything at once). Every reply carries the golden path. No bundled plugin is required; installed ones are worked examples readable with plugin_read.
Set the tile display order (applies live). Ids listed first appear in that order; unlisted tiles follow in registration order. Every tile id has the form `plugin:<pluginId>:<tileId>`.
PERMANENTLY delete a plugin — THIS CANNOT BE UNDONE: the code folder, the data directory (~/.smabar/data/<id>/), the log file and its entries in pluginsDeactivated, pluginOrder and pluginsHidden; only its settings block in config.plugins survives for a reinstall. Ask the user first. Reversible alternative: plugin_set_active(active=false).
Stop or start a plugin's PROCESS (persisted in `pluginsDeactivated`). active=false: no process, no polling, no popups, stays off across restarts and plugin_reload refuses it; folder, data directory and settings are kept, so active=true brings it back exactly as it was. Its tiles leave the bar meanwhile. Hide one tile while the plugin keeps running: plugin_set_visible. Delete for good: plugin_remove.
Show or hide ONE tile tile (persisted in `pluginsHidden`); ids are `plugin:<pluginId>:<tileId>` from bar_get_state. Hidden means off the bar only: the plugin keeps running and can still push popups; plugin_list names hidden tiles under hiddenTiles. Stop the process instead: plugin_set_active(active=false).
Cached values of system providers subscribed at least once. An empty result does not mean a provider is unavailable: plugin_guide(section="capabilities") lists this host's availableProviders even with no plugins installed. See plugin_guide(section="sdk") for subscription and control APIs.
Read the whole config, or the value at a dotted path such as `layout.position`, `settingsWindow.width`, `mcp.port`, or `plugins.hello.city`.
Set a config value at a dotted path. Allowed roots: zOrder, language, theme, themeExportDir, pluginOrder, plugins, mcp, rendering, layout, shortcuts, pluginsHidden, pluginsDeactivated, effects, appearance, popups, settingsWindow, audio (smabar playback volume/mute, notificationSounds, and per-plugin levels). Intermediate objects are created under `plugins` and `audio.plugins`. Everything applies live except mcp.enabled / mcp.port and rendering (auto|native|software, Linux only; app restart). Setting `theme` activates the theme: its tokens apply AND its `settings` block (if any) is applied one-shot — the user may change anything afterwards; re-activating resets to the theme again. pluginsHidden and pluginsDeactivated replace the WHOLE list; plugin_set_visible and plugin_set_active change one entry and explain what each of them actually does.
Error handling guidance minimal. Tools like plugin_call mention '10 s timeout' and 'outcome UNKNOWN' but do not specify error response format, retryability classification, or recovery steps. LLMs lack actionable error guidance.
Pagination not visible for list-like tools. plugin_data lists directory contents, font_list returns results with limit/offset, but no explicit total_count, next_cursor, or has_more fields documented in output schema.