mcp-openclaw: fix loader + align with current OpenClaw plugin API (closes #4)#5
Open
clawdreyhepburn wants to merge 1 commit into
Open
Conversation
Closes aauth-dev#4. The plugin did not load against any current OpenClaw runtime. Three problems blocked discovery and activation: 1. package.json was missing the `openclaw` discovery key. OpenClaw discovers installed plugins via `package.json.openclaw.extensions` (or `runtimeExtensions`); without that key the plugin is invisible. 2. openclaw.plugin.json declared an `entry` field. The OpenClaw plugin manifest is metadata-only by design; code entry belongs in `package.json.openclaw.*`. The `entry` field was silently ignored. 3. `register(api)` called `api.getConfig()`, `api.registerTool(name, fn)`, and `api.onShutdown(fn)`. None of those exist on `OpenClawPluginApi`. The real API exposes `pluginConfig` (property), `registerTool({...})` (object), and `registerService({id, start, stop})` for lifecycle. This PR: - Adds `package.json.openclaw.{extensions, runtimeExtensions}` so the plugin is discoverable. - Drops the unused `entry` field from openclaw.plugin.json. - Rewrites src/index.ts against the real OpenClaw plugin API, using `registerService({start, stop})` for lifecycle. This also fixes the async-leaky `register()` (tools were previously registered after `register()` returned, which can miss the static catalog snapshot). - Plumbs `description` and `inputSchema` from MCP `listTools` through `ServerManager.getTools()` so registered OpenClaw tools have proper metadata. - Adds a clear logger warning when `agent_url` is missing or `mcp_servers` is empty (previously a silent no-op). - Fixes the README config example: the plugin id is `aauth-mcp`, not `aauth`. Removes the unused `delegate` field from the example. - Bumps version to 0.8.2. Tests in `server-manager.test.ts` are updated for the new `getTools()` shape and now also assert that tool description and inputSchema flow through. `vitest run` is green. Refs: https://docs.openclaw.ai/plugins/manifest https://docs.openclaw.ai/plugins/sdk-entrypoints
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #4.
Fixes the three issues blocking
@aauth/mcp-openclawfrom loading on current OpenClaw, plus the async-leakyregister()that was on the way:Discovery + activation (the blockers)
package.jsonwas missing theopenclawdiscovery key. OpenClaw discovers installed (non-bundled) plugins viapackage.json.openclaw.extensions(and optionallyruntimeExtensions). Without that key the plugin is invisible and shows up asplugin not found: aauth-mcpin gateway logs. Added:openclaw.plugin.jsondeclared an unsupportedentryfield. The manifest is metadata-only by design — OpenClaw reads it before any plugin code is loaded so config validation can run without booting plugin runtime. Code entry belongs inpackage.json.openclaw.*. Dropped.register(api)was using a non-existent OpenClaw plugin API. The plugin calledapi.getConfig(),api.registerTool(name, handler), andapi.onShutdown(fn)— none of those exist. Rewrote against the realOpenClawPluginApi:api.pluginConfig(property, not method)api.registerTool({ name, description, parameters, execute })(object)api.registerService({ id, start, stop })for connect/disconnect lifecycleBonus fixes
register()was async-leaky. It returned synchronously and registered tools later in a.then(), so tools could miss OpenClaw's static catalog snapshot used during setup-only loading. Tools are now registered inside the servicestart()lifecycle, which has a deterministic completion point.ServerManager.getTools()now returnsdescriptionandinputSchemafrom MCPlistTools, so the OpenClaw tool registration includes proper schemas instead of opaque{}everywhere.aauth-mcp, notaauth, so the example as written would fail config validation against the manifest. Fixed and removed the unuseddelegatefield from the example.agent_urland emptymcp_serverspreviously failed silently; now they emitapi.logger.{error,warn}so it's visible in the gateway log.Verification
npm run -w @aauth/mcp-openclaw buildis clean.npx vitest run --root mcp-openclawis green (6/6). ThegetToolstest was updated to match the new return shape and now also asserts that description + inputSchema flow through.openclaw/dist/plugin-sdk/src/plugins/types.d.ts, the published Plugin manifest and Plugin entry points docs, and a working reference plugin (@clawdreyhepburn/openclaw-ovid) installed alongside it. Happy to do a live load test once you've reviewed.Out of scope (followups available on request)
The following were called out in #4 as contract issues but I kept them out of this PR to keep the diff focused on closing the issue:
agent_urlwith auto-discovery vialistConfiguredAgents()delegatefield from the public config schema<server>__<tool>or single-tool dispatch)setup-entry.tsforopenclaw onboardintegrationregisterAutoEnableProbefor auto-light-up afteraauth-bootstrapHappy to file separate PRs for any subset of those.
The protocol-layer packages (
@aauth/local-keys,@aauth/mcp-agent) all worked beautifully end-to-end while debugging this — three-party flow againstwhoami.aauth.devreturned full identity claims viaperson.hello-beta.neton first real attempt. This PR is purely about the OpenClaw plugin entry; the rest of the stack is in great shape.