Pydantic Models

Smarter API MCPClient Manifest Constants.

smarter.apps.mcpclient.manifest.models.mcpclient.const.DEFAULT_API_KEY_HEADER = 'X-API-Key'

Default HTTP header that carries the credential of an MCPClient whose authType is api_key.

smarter.apps.mcpclient.manifest.models.mcpclient.const.DEFAULT_CACHE_TTL = 3600

its tools, instructions and capabilities.

One hour.

Type:

Default seconds to cache an MCP server’s catalog

smarter.apps.mcpclient.manifest.models.mcpclient.const.DEFAULT_PRIORITY = 100

Default resolution order of an MCPClient.

Lower runs first.

smarter.apps.mcpclient.manifest.models.mcpclient.const.DEFAULT_TIMEOUT = 30

Default seconds to wait for an MCP server to connect and respond.

smarter.apps.mcpclient.manifest.models.mcpclient.const.MAX_CACHE_TTL = 86400

Maximum seconds to cache an MCP server’s catalog.

smarter.apps.mcpclient.manifest.models.mcpclient.const.MAX_HEADERS = 20

Maximum number of custom HTTP headers.

smarter.apps.mcpclient.manifest.models.mcpclient.const.MAX_HEADER_VALUE_LENGTH = 1024

Maximum length of a custom HTTP header value.

smarter.apps.mcpclient.manifest.models.mcpclient.const.MAX_TIMEOUT = 120

Maximum seconds to wait for an MCP server to connect and respond.

smarter.apps.mcpclient.manifest.models.mcpclient.const.RESERVED_HEADERS = frozenset({'authorization', 'connection', 'content-length', 'content-type', 'cookie', 'host', 'keep-alive', 'proxy-authorization', 'te', 'trailer', 'transfer-encoding', 'upgrade'})

Headers that a manifest may not set.

Credentials belong in a Smarter Secret, via credentials, and the rest are managed by the HTTP client and the MCP transport, as are all headers that begin with mcp-.

Smarter API Manifest - MCPClient.metadata.

class smarter.apps.mcpclient.manifest.models.mcpclient.metadata.SAMMCPClientMetadata(*, name: str, description: str | None, version: str | None, tags: List[str] | None = <factory>, annotations: List[dict[str, str | int | float | bool | ~datetime.date | ~datetime.datetime | ~decimal.Decimal | ~uuid.UUID | bytes | list | dict]] | None=<factory>)[source]

Bases: AbstractSAMMetadataBase

Smarter API MCPClient Manifest - Metadata class.

class_identifier: ClassVar[str] = 'MCPClient.metadata'
model_config = {'arbitrary_types_allowed': True, 'from_attributes': True, 'frozen': True}

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

model_post_init(context, /)

This function is meant to behave like a BaseModel method to initialize private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Parameters:
  • self (BaseModel) – The BaseModel instance.

  • context (Any) – The context.

Return type:

None

Smarter API Manifest - MCPClient.spec.

An MCPClient connects Smarter to a remote Model Context Protocol (MCP) server. When an LLMClient lists the MCPClient in its spec.mcpClients, the server’s tools are offered to the LLM on each prompt, alongside the LLMClient’s Plugins and Functions, and the server’s instructions are added to the system prompt.

spec:
  config:
    transport: http              # http (Streamable HTTP) or sse (legacy HTTP+SSE)
    endpointUrl: https://mcp.example.com/mcp
    headers: {}                  # optional, non-secret HTTP headers
    timeout: 30                  # seconds
    authType: bearer_token       # none, api_key, bearer_token or oauth2
    credentials: example_token   # the name of a Smarter Secret containing the credential
    apiKeyHeader: X-API-Key      # the header that carries an api_key credential
    allowedTools: []             # glob patterns. Empty means all of the server's tools
    allowedResources: []         # glob patterns of resource URIs the LLM may read
    includeInstructions: true    # add the server's instructions to the system prompt
    cacheTtl: 3600               # seconds to cache the server's tools and instructions
    isActive: true
    priority: 100                # lower runs first

Note

Experimental. The MCPClient was designed and coded by Claude Code (Anthropic’s Claude Opus 5.5), with Lawrence McDaniel as co-author. It is experimental, and will be documented.

smarter.apps.mcpclient.manifest.models.mcpclient.spec.HEADER_NAME_PATTERN = re.compile("^[A-Za-z0-9!#$%&'*+.^_`|~-]{1,64}$")

an RFC 9110 token, of at most 64 characters.

Type:

An HTTP header name

class smarter.apps.mcpclient.manifest.models.mcpclient.spec.SAMMCPClientSpec(*, config: SAMMCPClientSpecConfig)[source]

Bases: AbstractSAMSpecBase

Smarter API MCPClient Manifest MCPClient.spec.

class_identifier: ClassVar[str] = 'MCPClient.spec'
config: SAMMCPClientSpecConfig
model_config = {'arbitrary_types_allowed': True, 'from_attributes': True, 'frozen': True}

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

model_post_init(context, /)

This function is meant to behave like a BaseModel method to initialize private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Parameters:
  • self (BaseModel) – The BaseModel instance.

  • context (Any) – The context.

Return type:

None

class smarter.apps.mcpclient.manifest.models.mcpclient.spec.SAMMCPClientSpecConfig(*, transport: Literal['http', 'sse']='http', endpointUrl: str, headers: dict[str, str] | None=<factory>, timeout: Annotated[int, ~annotated_types.Ge(ge=1), ~annotated_types.Le(le=120)] = 30, authType: Literal['none', 'api_key', 'bearer_token', 'oauth2']='none', credentials: str | None = None, apiKeyHeader: str | None = 'X-API-Key', allowedTools: list[str] | None = <factory>, allowedResources: list[str] | None = <factory>, includeInstructions: bool = True, cacheTtl: Annotated[int, ~annotated_types.Ge(ge=0), ~annotated_types.Le(le=86400)] = 3600, isActive: bool = True, priority: Annotated[int, ~annotated_types.Ge(ge=0)] = 100)[source]

Bases: AbstractSAMSpecBase

Smarter API MCPClient Manifest MCPClient.spec.config.

allowedResources: list[str] | None
allowedTools: list[str] | None
apiKeyHeader: str | None
authType: Literal['none', 'api_key', 'bearer_token', 'oauth2']
cacheTtl: int
class_identifier: ClassVar[str] = 'MCPClient.spec.config'
credentials: str | None
endpointUrl: str
headers: dict[str, str] | None
includeInstructions: bool
isActive: bool
model_config = {'arbitrary_types_allowed': True, 'from_attributes': True, 'frozen': True}

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

model_post_init(context, /)

This function is meant to behave like a BaseModel method to initialize private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Parameters:
  • self (BaseModel) – The BaseModel instance.

  • context (Any) – The context.

Return type:

None

priority: int
timeout: int
transport: Literal['http', 'sse']
classmethod validate_api_key_header(v)[source]

Validate the api key header name.

Return type:

str

classmethod validate_auth_type(v)[source]

Validate the authentication type.

Return type:

str

validate_credentials()[source]

Require credentials unless authType is none, and forbid them if it is.

Return type:

SAMMCPClientSpecConfig

classmethod validate_endpoint_url(v)[source]

Validate the endpoint URL.

Return type:

str

classmethod validate_headers(v)[source]

Validate the custom HTTP headers.

Return type:

dict[str, str]

classmethod validate_patterns(v)[source]

Validate the glob patterns: non-empty strings, without duplicates.

Return type:

list[str]

classmethod validate_transport(v)[source]

Validate the transport.

stdio is reserved, and not supported.

Return type:

str

smarter.apps.mcpclient.manifest.models.mcpclient.spec.validate_endpoint_url(url)[source]

Validate an MCP server’s endpoint URL.

The URL must be https, without credentials or a fragment, and may name a port. A loopback host, e.g. http://localhost:9357/, may also be http, because no TLS certificate is issued for it. Whether Smarter may connect to the URL is verified each time it connects: see smarter.apps.mcpclient.connection.validate_endpoint_url().

Parameters:

url (str) – The URL.

Return type:

str

Returns:

The URL.

Raises:

SAMValidationError – If the URL is not permitted.

smarter.apps.mcpclient.manifest.models.mcpclient.spec.validate_header_name(name, field)[source]

Validate an HTTP header name that a manifest may set.

Parameters:
  • name (str) – The header name.

  • field (str) – The manifest field, for the error message.

Return type:

str

Returns:

The header name.

Raises:

SAMValidationError – If the name is not a valid header name, or is reserved.

Smarter API Manifest - MCPClient.status.

class smarter.apps.mcpclient.manifest.models.mcpclient.status.SAMMCPClientStatus(*, recordLocator: str, created: datetime, modified: datetime, dependencies: List[SAMDependency] | None = None, accountNumber: str, username: str, connectionStatus: str | None = None, protocolVersion: str | None = None, serverName: str | None = None, serverVersion: str | None = None, lastConnected: datetime | None = None, lastError: str | None = None, tools: list[str] | None = None)[source]

Bases: AbstractSAMStatusBase

Smarter API MCPClient Manifest - Status class.

Read only. Besides ownership, it reports the result of the last connection to the MCP server.

accountNumber: str
class_identifier: ClassVar[str] = 'MCPClient.status'
connectionStatus: str | None
lastConnected: datetime | None
lastError: str | None
model_config = {'arbitrary_types_allowed': True, 'from_attributes': True, 'frozen': True}

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

model_post_init(context, /)

This function is meant to behave like a BaseModel method to initialize private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Parameters:
  • self (BaseModel) – The BaseModel instance.

  • context (Any) – The context.

Return type:

None

protocolVersion: str | None
serverName: str | None
serverVersion: str | None
tools: list[str] | None
username: str

Smarter API MCPClient Manifest.

class smarter.apps.mcpclient.manifest.models.mcpclient.model.SAMMCPClient(*, apiVersion: str, kind: str, metadata: SAMMCPClientMetadata, spec: SAMMCPClientSpec, status: SAMMCPClientStatus | None = None)[source]

Bases: AbstractSAMBase

Smarter API Manifest - MCPClient.

class_identifier: ClassVar[str] = 'MCPClient'
metadata: SAMMCPClientMetadata
model_config = {'arbitrary_types_allowed': True, 'from_attributes': True, 'frozen': True}

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

model_post_init(context, /)

This function is meant to behave like a BaseModel method to initialize private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Parameters:
  • self (BaseModel) – The BaseModel instance.

  • context (Any) – The context.

Return type:

None

spec: SAMMCPClientSpec
status: SAMMCPClientStatus | None