Acting User

The acting user of a request from this platform to its own staff-only endpoint.

An LLMClient that has an MCPClient of the MCPServer’s staff-only endpoint, e.g. the built-in smarter_sysadmin, calls that server for the person who is chatting with it. The server must know who that is: its tools read the platform’s logs and its users’ accounts, so it serves only the platform’s staff, and records each call under the person who made it.

An MCPClient can only send a credential from a Secret, the same for everyone who chats, and a prompt runs as its LLMClient’s owner. So the platform says who is chatting itself, with a signed header, ACTING_USER_HEADER:

  1. The prompt api sets the acting user, the user who sent the prompt, with acting_user(), for the length of the prompt. The MCPClient api’s tool call does the same.

  2. MCPServerConnection keeps the acting user when it is created, in the prompt’s own thread, and adds acting_user_headers() to every request, which is the header only for a request to this platform’s own staff-only endpoint (is_staff_endpoint_url()), and nothing for any other server, so that no other server learns who is chatting.

  3. StaffEndpointView verifies the header with verify_acting_user(). A request without an acting user, e.g. the catalog refresh that runs in the background, may list the tools, but not call one. A tool call requires an acting user who is one of the platform’s staff, is_platform_staff().

The header is signed with the platform’s SECRET_KEY, by django.core.signing.TimestampSigner with its own salt, and expires after MAX_AGE_SECONDS, so only this platform can make one, and one that is copied from a log is soon useless. It carries the user’s id, not their name or email address.

smarter.apps.mcpserver.services.acting_user.ACTING_USER_HEADER = 'X-Smarter-Acting-User'

The http header that carries the signed acting user.

An MCPClient’s manifest may not set it.

class smarter.apps.mcpserver.services.acting_user.ActingUser(**data)[source]

Bases: BaseModel

The signed content of ACTING_USER_HEADER.

Parameters:

user_id – The id of the user who is chatting, or None for a request that the platform makes for nobody in particular, e.g. the background refresh of an MCPClient’s catalog.

model_config = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

user_id: int | None
smarter.apps.mcpserver.services.acting_user.acting_user(user)[source]

Make a user the acting user of the MCP server requests that the block makes.

The value is a context variable, so it follows the code into asgiref.sync.async_to_sync() and asgiref.sync.sync_to_async(), and is restored when the block ends.

Example usage:

with acting_user(request.user):
    response = handler(user_profile, prompt, data)
Parameters:

user (object | None) – The user. Anything that is not a User, e.g. AnonymousUser or None, means nobody in particular.

Yields:

Nothing.

smarter.apps.mcpserver.services.acting_user.acting_user_headers(url, user)[source]

Return the acting user header to send to an MCP server, if it is this platform’s staff-only endpoint.

Parameters:
  • url (str | None) – The MCP server’s url.

  • user (User | None) – The acting user, usually the current_acting_user() when the connection was created, or None for nobody in particular.

Return type:

dict[str, str]

Returns:

{ACTING_USER_HEADER: <signed value>} for this platform’s own staff-only endpoint, or an empty dict for any other MCP server, which never learns who is chatting.

smarter.apps.mcpserver.services.acting_user.current_acting_user()[source]

Return the acting user that acting_user() set, if any.

Return type:

User | None

Returns:

The user, or None outside an acting_user() block, or for an anonymous user.

smarter.apps.mcpserver.services.acting_user.is_staff_endpoint_url(url)[source]

Return whether a url is that of this platform’s own staff-only endpoint.

The scheme, host, port and path must all match staff_endpoint_url(), with or without a trailing slash, so that a server elsewhere whose path looks the same never gets the header.

Parameters:

url (str | None) – An MCPClient’s endpoint url.

Return type:

bool

Returns:

True if the url is this platform’s staff-only endpoint.

smarter.apps.mcpserver.services.acting_user.sign_acting_user(user)[source]

Return the signed value of ACTING_USER_HEADER for a user.

Parameters:

user (User | None) – The user, or None for nobody in particular.

Return type:

str

Returns:

The signed, timestamped value.

smarter.apps.mcpserver.services.acting_user.staff_endpoint_url()[source]

Return the url of this platform’s staff-only endpoint.

It is reversed against the platform’s urlconf, because a prompt may run on a deployed LLMClient’s host, whose urlconf has no MCPServer endpoints.

Return type:

str

Returns:

The url, e.g. https://alpha.platform.example.com/api/v1/mcp/smarter-operations/.

smarter.apps.mcpserver.services.acting_user.verify_acting_user(value)[source]

Verify a signed value of ACTING_USER_HEADER.

Parameters:

value (str) – The header’s value.

Return type:

ActingUser | None

Returns:

The acting user, or None if the value was not signed by this platform with SALT, has expired, or is not an ActingUser.