Skip to main content

MCP

🚧Documentation Under Construction

We are actively working to improve this documentation. The content you see here may be incomplete, subject to change, or may not fully reflect the current state of the feature. We appreciate your understanding as we continue to enhance our docs.

The Brightspot AI plugin can expose CMS content over the Model Context Protocol (MCP), letting external AI clients—IDE assistants, chat apps, custom agents—search, read, create, update, and delete content through a tool-calling interface.

The MCP server is a separate module that runs inside the Brightspot web application. It is implemented as an ApiEndpoint, so it inherits Brightspot's existing API client, credential, and permission model. The same @ToolMethod-annotated tools used by in-process agents (Ask AI, Create with AI) are reused as MCP tools.

How it works

  • The mcp module registers an ApiEndpoint (McpApiEndpoint, display name MCP) that handles MCP protocol traffic at one or more configurable paths.
  • A servlet filter (McpApiEndpointFilter) starts a stateless MCP server on application init. It discovers every concrete ToolGroup on the classpath, resolves each @ToolMethod-annotated method into a tool, and registers it with the server.
  • The server advertises tools only—prompts and resources are disabled. Each tool name is namespaced as <GroupName>_<methodName> (for example, Content_search).
  • Each incoming MCP request is authenticated against an ApiClient record. Once validated, the request is delegated to the MCP transport servlet, which dispatches the tool call.
  • Tool return values become the MCP structuredContent payload. Scalars and collections are wrapped as {"result": ...}. Exceptions are returned as an error result with the stack trace as text content.

Installation

Add the mcp artifact alongside the core AI plugin:

Requirements
Requires Brightspot 4.8 or later.
<dependency>
<groupId>com.brightspot.ai</groupId>
<artifactId>mcp</artifactId>
<version>3.0.0</version>
</dependency>

This pulls in the upstream MCP SDK (io.modelcontextprotocol.sdk:mcp-core plus the Jackson JSON transport at runtime) and registers the MCP endpoint and built-in Content tool group.

Setting up the endpoint

The MCP server is exposed through a Brightspot API endpoint, configured in the CMS like any other endpoint.

To create an MCP endpoint:

  1. Click > Admin > APIs.
  2. Create a new API endpoint and select MCP as the type.
  3. In the Paths field, add one or more URL paths to serve MCP traffic at (for example, /mcp).
  4. Save.

The endpoint is now reachable at the configured paths on your application host. Point MCP clients at the full URL, including scheme and host.

Authentication

McpApiEndpoint accepts credentials from either of two headers, in order of precedence:

HeaderFormat
AuthorizationBearer <token>
X-API-Key<token>

Tokens are validated against ApiClient records:

  • Invalid credentials produce 401 Unauthorized.
  • Valid credentials that lack endpoint or permission access produce 403 Forbidden.

To issue credentials for an MCP client:

  1. Click > Admin > APIs.
  2. Create or open an API Client.
  3. Generate a token for the client and grant it access to the MCP endpoint.
  4. Configure access control under the MCP cluster on the same client (see Access control).
  5. Share the token with the MCP client out of band.

Access control

The McpApiClient modification adds two MCP-specific fields to every ApiClient, surfaced under the MCP cluster in the CMS:

  • Allowed Sites — Sites this client can read from or write to. An empty set means unrestricted.
  • Allowed Types — Content types this client can read or write. An empty set means unrestricted.

The built-in Content tool group enforces these restrictions on every call. Custom tool groups that operate on CMS content should consult McpApiClient and apply the same checks.

tip

Treat MCP credentials like any other API token. A client with unrestricted allowed sites and types can read and modify any content the endpoint user can access.

Built-in tools

The mcp module ships one tool group, Content (ContentToolGroup), providing CRUD and search over Brightspot content. All tools are namespaced Content_*:

ToolHintsPurpose
Content_searchTyperead-only, idempotentFind content type names by partial match.
Content_getTyperead-only, idempotentGet the JSON Schema for a content type.
Content_getFieldValuesread-only, idempotentList allowed values for a field with a value generator.
Content_searchTextuallyread-only, idempotentKeyword search across content.
Content_searchSemanticallyread-only, idempotentEmbedding-based search across content.
Content_getread-only, idempotentFetch a single content item by ID.
Content_generateIdsread-onlyGenerate fresh UUIDs for new content.
Content_createwriteCreate new content of a given type.
Content_updatewriteUpdate existing content by ID.
Content_deletewrite, destructiveDelete content by ID.

The group also publishes a usage guide to the MCP server's instructions payload so that clients can route tool calls correctly without trial and error. See ContentToolGroup#getInstructions for the current text.

Content_searchSemantically requires a configured text embedding generator (see Configuration). The other tools work without one.

Adding custom tools

Any concrete subclass of ToolGroup on the classpath is picked up automatically. Tools defined this way are available both to the in-process agents and to MCP clients.

1
@NullMarked
2
public class WeatherToolGroup extends ToolGroup {
3
4
@Override
5
public String getName() {
6
return "Weather";
7
}
8
9
@Override
10
public @Nullable String getInstructions() {
11
return "Use Weather_* tools for current conditions and forecasts.";
12
}
13
14
@ToolMethod(
15
title = "Get the current temperature for a city",
16
readOnly = true,
17
destructive = false,
18
idempotent = false,
19
description = "Returns the current temperature in Celsius for the given city.")
20
public double currentTemperature(
21
@ToolParam(description = "City name, e.g. `San Francisco`.") String city) {
22
23
return WeatherApi.lookup(city).temperatureCelsius();
24
}
25
}

Notes:

  • The group's getName() becomes the tool name prefix (Weather_currentTemperature here).
  • Per-method behavioral hints (readOnly, destructive, idempotent) on @ToolMethod are forwarded to MCP clients, which may use them to auto-approve calls or prompt for confirmation.
  • Parameter schemas are derived from @ToolParam annotations and the method signature. For non-standard schemas, supply a SchemaSupplier via @ToolParam.
  • Return values are serialized as structured content. Scalars and collections are auto-wrapped as {"result": ...}; return a Map<String, Object> for richer payloads.
  • Throwing from a tool method produces an MCP error result; the stack trace is included as text content.

For deeper internals—Tool, RunnableTool, ToolGroup discovery, and the agentic chat loop that consumes the same tools—see Architecture overview.

Was this page helpful?

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.