Farm Script Service
Reference
MCPFarmScriptService is the Script API behind the main wiki's MCP farm dashboard: it reads and writes each wiki's MCP state from wiki pages, with the rights check on every write. It is registered under the hint mcp, so pages reach it as $services.mcp. The component and the returned types are @Unstable.
#foreach ($wikiId in $services.wiki.getAllIds())
$wikiId: enabled=$services.mcp.isEnabled($wikiId) trusted=$services.mcp.isConfigurationTrusted($wikiId) guest=$services.mcp.isGuestAccessAllowed($wikiId) reach=$services.mcp.isCrossWikiReach($wikiId)
#endReading
| Method | Returns |
|---|---|
| isEnabled(wikiId) | Whether that wiki's MCP endpoint is enabled |
| isConfigurationTrusted(wikiId) | Whether that wiki's configuration page may be applied |
| getConfigurationAuthor(wikiId) | The DocumentReference of the user who last saved that wiki's configuration page, or null; administrators of that wiki only |
| getServerUrl(wikiId) | That wiki's externally reachable endpoint URL, ready to paste into an MCP client configuration, or null when it cannot be composed |
| getToolStates(wikiId) | Every togglable tool's state on that wiki, sorted by category then id for a stable tree order; an empty list when the tools cannot be looked up |
| isCrossWikiReach(wikiId) | Whether that wiki's endpoint may reach other wikis |
| isGuestAccessAllowed(wikiId) | Whether unauthenticated callers may use that wiki's endpoint |
| canAdmin(wikiId) | Whether the current user may administer that wiki |
| canFarmAdmin() | Whether the current user may administer the farm |
Reads are not rights-gated, consistently with the configuration they expose, with one exception: getConfigurationAuthor returns null unless the current user can administer that wiki, because only an administrator can act on the author. Writes are always gated.
getToolStates omits reach-gated tools such as list_wikis: they are governed by the reach grant, not by the tool tree.
Writing
| Method | Does | Rights checked on |
|---|---|---|
| setEnabled(wikiId, enabled) | Sets that wiki's MCP enabled flag | That wiki |
| setEnabledTools(wikiId, toolIds) | Stores the explicit set of enabled tool ids; a null array stores the empty list, which reads back as the default policy | That wiki |
| setGuestAccessAllowed(wikiId, allowed) | Sets that wiki's guest-access flag | That wiki |
| setCrossWikiReach(wikiId, allowed) | Sets that wiki's cross-wiki reach grant | The MAIN wiki |
| applyEnabled(managedWikiIds, enabledWikiIds) | Sets each managed wiki enabled if and only if it is also listed as enabled | Each wiki |
| applyGuestAccess(managedWikiIds, allowedWikiIds) | The same for guest access | Each wiki |
| applyReach(managedWikiIds, reachWikiIds) | The same for cross-wiki reach | The MAIN wiki, once |
| resetConfiguration(wikiId) | Removes every stored setting and takes ownership of the configuration page | That wiki |
Cross-wiki reach is a farm-level decision, which is why its rights check is on the main wiki: a subwiki administrator cannot grant reach to their own wiki.
The bulk methods write only a wiki whose state actually changes and report how many they changed. applyEnabled and applyGuestAccess skip a wiki whose configuration page is untrusted without reading its stored settings, because the dashboard does not show that wiki's values. applyReach writes nothing at all when the main wiki's page is untrusted, and counts every managed wiki as skipped.
resetConfiguration is how an administrator takes ownership of an untrusted page. It drops the stored values instead of re-trusting them, stamps the acting user as author and creator, and leaves the wiki on the defaults.
Every mutating method gates on an admin right: canAdmin(wikiId) for the per-wiki settings, canFarmAdmin() for cross-wiki reach. canAdmin requires the canonical id of an existing wiki as well as admin right on it, so a case variant of a wiki id is refused wherever it gates, and the per-wiki bulk methods count it as skipped.
Returned types
| Type | Members |
|---|---|
| MCPToolState | getId(), getCategory(), getSummary(), isMandatory(), isWrite(), isEnabled() |
| BulkResult | getChanged(), getSkipped() |
FAQ
Why is the hint mcp and not mcpFarm?
The component is named mcp, so the Script API is $services.mcp. The class name says farm because that is the scope it administers, not because it changes the binding.
Does a write take effect without a restart?
Yes. Saving a wiki's MCP configuration invalidates both cached server variants of that wiki, and the next request rebuilds them. A main-wiki save invalidates every wiki's server, because the reach list is farm-level.