Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

feat(mcp): example IMcpToolProvider + AI companion wiring in the template#31

Merged
rubenvdlinde merged 1 commit into
developmentfrom
feat/example-mcp-provider
May 12, 2026
Merged

feat(mcp): example IMcpToolProvider + AI companion wiring in the template#31
rubenvdlinde merged 1 commit into
developmentfrom
feat/example-mcp-provider

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Summary

Wires the AI Chat Companion MCP-tool pattern (hydra ADR-034 + ADR-035) into the template so every new Conduction Nextcloud app generated from this scaffold gets it by default.

Closes #30 — this fully addresses the issue's "ship a minimal example IMcpToolProvider" goal.

What's added

  • lib/Mcp/ExampleToolProvider.php — a heavily-commented, copy-me provider implementing OCA\OpenRegister\Mcp\IMcpToolProvider. Class-level docblock walks through: implement the interface, register the alias in Application.php, namespace tool ids {appId}.{toolName}, run per-object auth in invokeTool BEFORE business logic, never throw from invokeTool. Links ADR-034/035 and points at decidesk's DecideskToolProvider as the production example.
  • lib/AppInfo/Application.php — registers the provider under the service alias OCA\OpenRegister\Mcp\IMcpToolProvider::{appId} (clearly commented). OpenRegister's McpToolsService discovers per-app providers by exactly that alias.
  • tests/Stubs/Mcp/IMcpToolProvider.php — stub interface mirroring openregister PR #1466 (ai-chat-companion-orchestrator) until it merges. Wired via composer.json autoload-dev (OCA\OpenRegister\tests/Stubs/) plus tests/bootstrap-unit.php / tests/bootstrap.php. Replaced transparently by the real interface once openregister is installed alongside the app.
  • tests/Unit/Mcp/ExampleToolProviderTest.php — 7-case contract test: getAppId(), two well-formed {appId}.-prefixed descriptors with valid inputSchema objects, ping echo behaviour, describeApp auth gate + payload, unknown-tool returns a structured error (does not throw).
  • README.md — new "AI Chat Companion / MCP tools" section (rename ExampleToolProvider{YourApp}ToolProvider, replace the example tools, keep the per-object-auth-before-business-logic rule) + lib/Mcp/ in the directory tree.
  • psalm.xml — adds OCA\OpenRegister\Mcp\IMcpToolProvider to the suppressed cross-app UndefinedClass references (alongside the existing DeepLinkRegistrationEvent etc.).

The two example tools

Tool id Args Returns
app-template.ping optional message (string) `{ ok: true, echo: <message
app-template.describeApp none { id, version, name } from IAppManager — requires an authenticated user (IUserSession)

Namespace / app-id placeholders

The template uses concrete naming (not {{token}} placeholders): <id> is app-template, namespace OCA\AppTemplate, Application::APP_ID = 'app-template'. The provider builds tool ids from Application::APP_ID, so renaming the app in one place flows through. Matched the template's existing docblock shape (SPDX inside the file docblock, @category/@package/author/copyright/license/version/link tags).

Widget mount

Confirmed, no bump needed. The template already mounts CnAppRoot from @conduction/nextcloud-vue (^1.0.0-beta.12; lock currently resolves to beta.30). CnAppRoot renders <CnAiCompanion /> as of the nextcloud-vue beta branch (future beta.31) — CnAiCompanion is not in the published beta.30 yet, but the ^1.0.0-beta.12 range will pick it up automatically once beta.31 ships. So the FAB auto-renders with no template change.

Quality

composer phpcs ✅ · composer psalm ✅ · composer phpstan ✅ · phpunit -c phpunit-unit.xml ✅ (11 tests, 40 assertions). composer phpmd surfaces one pre-existing finding in lib/Service/SettingsService.php (BooleanArgumentFlag on loadConfiguration($force)), untouched by this PR. composer test:unit (the phpunit.xml path) needs a live Nextcloud container to bootstrap (OC_App not found standalone) — pre-existing; CI runs it in a NC container where it works, and the stub loads there too.

ADRs

MCP coverage

Adds tool: app-template.ping
Adds tool: app-template.describeApp

🤖 Generated with Claude Code

Wires the AI Chat Companion MCP-tool pattern (hydra ADR-034/035) into the
template so new Conduction apps get it by default.

- lib/Mcp/ExampleToolProvider.php — heavily-commented copy-me provider with
  two trivial example tools: app-template.ping and app-template.describeApp
- lib/AppInfo/Application.php — registers the provider under the alias
  OCA\OpenRegister\Mcp\IMcpToolProvider::{appId}
- tests/Stubs/Mcp/IMcpToolProvider.php — stub interface until openregister
  PR #1466 ships the real one; wired via composer autoload-dev + bootstraps
- tests/Unit/Mcp/ExampleToolProviderTest.php — contract test (7 cases)
- README: new "AI Chat Companion / MCP tools" section
- psalm.xml: allow the OCA\OpenRegister\Mcp\IMcpToolProvider cross-app ref

Widget mount: the template already mounts CnAppRoot from
@conduction/nextcloud-vue (^1.0.0-beta.12), which renders the companion FAB
once nextcloud-vue beta.31 (CnAiCompanion) is published — no bump needed.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/nextcloud-app-template @ 92ab60e

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
composer ✅ 100/100
npm ✅ 427/427
PHPUnit
Newman
Playwright ⏭️

Coverage: 0% (0/3 statements)


Quality workflow — 2026-05-12 05:02 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde rubenvdlinde merged commit c622aa4 into development May 12, 2026
25 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant