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
Merged
Conversation
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.
Contributor
Quality Report — ConductionNL/nextcloud-app-template @
|
| 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.
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
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 exampleIMcpToolProvider" goal.What's added
lib/Mcp/ExampleToolProvider.php— a heavily-commented, copy-me provider implementingOCA\OpenRegister\Mcp\IMcpToolProvider. Class-level docblock walks through: implement the interface, register the alias inApplication.php, namespace tool ids{appId}.{toolName}, run per-object auth ininvokeToolBEFORE business logic, never throw frominvokeTool. Links ADR-034/035 and points at decidesk'sDecideskToolProvideras the production example.lib/AppInfo/Application.php— registers the provider under the service aliasOCA\OpenRegister\Mcp\IMcpToolProvider::{appId}(clearly commented). OpenRegister'sMcpToolsServicediscovers 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 viacomposer.jsonautoload-dev(OCA\OpenRegister\→tests/Stubs/) plustests/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 validinputSchemaobjects,pingecho behaviour,describeAppauth gate + payload, unknown-tool returns a structurederror(does not throw).README.md— new "AI Chat Companion / MCP tools" section (renameExampleToolProvider→{YourApp}ToolProvider, replace the example tools, keep the per-object-auth-before-business-logic rule) +lib/Mcp/in the directory tree.psalm.xml— addsOCA\OpenRegister\Mcp\IMcpToolProviderto the suppressed cross-appUndefinedClassreferences (alongside the existingDeepLinkRegistrationEventetc.).The two example tools
app-template.pingmessage(string)app-template.describeApp{ id, version, name }fromIAppManager— requires an authenticated user (IUserSession)Namespace / app-id placeholders
The template uses concrete naming (not
{{token}}placeholders):<id>isapp-template, namespaceOCA\AppTemplate,Application::APP_ID = 'app-template'. The provider builds tool ids fromApplication::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
CnAppRootfrom@conduction/nextcloud-vue(^1.0.0-beta.12; lock currently resolves tobeta.30).CnAppRootrenders<CnAiCompanion />as of the nextcloud-vuebetabranch (futurebeta.31) —CnAiCompanionis not in the publishedbeta.30yet, but the^1.0.0-beta.12range will pick it up automatically oncebeta.31ships. 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 phpmdsurfaces one pre-existing finding inlib/Service/SettingsService.php(BooleanArgumentFlagonloadConfiguration($force)), untouched by this PR.composer test:unit(thephpunit.xmlpath) needs a live Nextcloud container to bootstrap (OC_App not foundstandalone) — 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.pingAdds tool:
app-template.describeApp🤖 Generated with Claude Code