MCP Integration

MCP Integration

Rustici Generator can serve as an MCP (Model Context Protocol) server. MCP is a standard that lets a Large Language Model client discover tools and resources on a remote server and call them during a conversation. Connecting a client to Generator’s MCP server allows an agent to search your content library and read course text without wrapping Generator’s REST API.

The REST API remains the integration path for applications that import content, generate metadata, or manage tenants and credentials. MCP is intended for agent workflows that need to search and read content that is already in Generator.

Support: MCP tools and resources are read-only. Import, generation, credential management, and other write operations are not available over MCP.

MCP Capability

Tools are the default path for an agent loop. Resources are URI-addressable documents for attaching or re-reading known text.

ToolUse
search_for_contentBroad tenant search (lexical or semantic), up to 100 hits
search_within_contentLocations inside one content_id + version
search_generated_fieldsFind content by generated TITLE, SUMMARY, or KEYWORDS
list_contentCatalog browse when you are not searching by topic
list_content_versionsAll enabled versions of a content id, plus tag and target IDs
get_content_versionMetadata for one version (not course text)
get_content_textPreferred way to fetch course text (format, include_interactions, optional location)

 

ResourceUse
content_version_textFull structured text for a known content version (JSON locations map).
content_location_textText for one slide, chapter, or timestamp.

 

Availability

As of Generator 2.0, the MCP server is enabled for all deployments. Generator’s MCP server can be accessed at:

https://[DOMAIN]/mcp

Connecting a Client

Generator’s MCP server uses Streamable HTTP and is stateless. Configure your MCP client with:

  • URL: https://[DOMAIN]/mcp (a trailing slash is also accepted)
  • Transport: Streamable HTTP. Clients must POST. GET is not supported.
  • Headers on every request:
    • Authorization: Bearer [ACCESS_TOKEN]
    • tenant-id: [TENANT_ID]

Use a stable URL. Do not rely on HTTP redirects between /mcp and /mcp/; many clients drop the Authorization header on redirect.

The tenant-id header is required on every MCP request, including when the token itself is already scoped to a tenant. The header value must match the token’s tenant when the token is tenant-scoped.

Authentication

MCP uses the same login endpoint as the REST API. Tokens are audience-bound: an MCP token is rejected by /api/v1, and an API token is rejected by /mcp. You must request a token for the MCP resource.

Here is an example request for an MCP token:

curl -X 'POST' \
'https://[DOMAIN]/api/v1/login/access_token' \
-H 'accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-raw 'grant_type=client_credentials&client_id=[CREDENTIAL_ID]&client_secret=[CREDENTIAL_PASSWORD]&resource=MCP&timestamp_nonce=1735689600'

More information about authentication with Generator can be found here

Credentials and Scopes

We recommend creating a dedicated credential for MCP access instead of using a single credential for all operations. Current MCP tools and resources only need permission to read content, so a credential requesting MCP tokens only needs READ access on the CONTENT subject. Additionally, credentials can be scoped to access only the tenants that should be accessible to the MCP agent. See Credentials Management and Authorization Scopes for more information.

Access Control Policies

Credential scopes are a broad permission system, controlling if a token is allowed to perform a particular action on a particular kind of resource. When an unscoped MCP token is provided to an agent, the agent will have access to any resources made available by the original credential’s permission scopes.

When you need a finer limit inside the tenant, you can attach an Access Control Policy to the token — for example, granting access to only sales courses, or a partner agent that should not see the full catalog. Policies are built from targets. Targets serve as a way to group content together. See Access Control Targets and Policies for more details.

Access control policies can only be attached to tokens minted for the MCP resource. Provide both access_control_policy_id and tenant_id on the login request. tenant_id is required when a policy is specified; it also scopes the token such that it can only access resources within that tenant, even if the requesting credential has broader access.

Below is an example request for an MCP token that is limited by a defined access control policy id:

curl -X 'POST' \
'https://[DOMAIN]/api/v1/login/access_token' \
-H 'accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-raw 'grant_type=client_credentials&client_id=[CREDENTIAL_ID]&client_secret=[CREDENTIAL_PASSWORD]&resource=MCP&tenant_id=[TENANT_ID]&access_control_policy_id=[POLICY_ID]&timestamp_nonce=1735689600'

Configuration

The following environment variables are relevant to MCP:

VariableDescription
HOSTING__MCP_STRMCP path. Default /mcp. This path is also part of the token audience; changing it invalidates existing MCP tokens
SECURITY__MCP_ACCESS_TOKEN_EXPIRE_MINUTESLifetime of MCP tokens in minutes. Default 60
LLM__USAGE_ENABLEDRequired for semantic search. Default true

See Hosting Variables for the full list.

Troubleshooting

  • 401 / Unauthorized: Missing or invalid Authorization header.
  • 401 / Could not validate credentials: Token expired, inactive credential, or an API_V1 token used against /mcp. Mint a new token with resource=MCP.
  • 400 / Missing tenant-id: The tenant-id header was omitted.
  • 403 / Token is not authorized for the requested tenant: The tenant-id header does not match the tenant scoped on the token.
  • 403 / Not authorized: The credential does not have READ access to CONTENT for that tenant.
  • MCP URL not found / connection refused: The client is using the wrong path.
  • Client cannot connect / 405 on GET: The client is using GET or SSE instead of Streamable HTTP POST.
  • Semantic search fails: LLM__USAGE_ENABLED is disabled, or the instance cannot reach the embedding service.