Skip to content

MCP connectors

octomate.config.mcp.base

The shapes every MCP tentacle's config shares: the server and the name its tools are listed under, with either one operator credential or a person's own linked account behind it.

McpConfig pydantic-model

Bases: BaseModel

What every MCP tentacle is configured with: the server, and the name its tools are listed under.

Fields:

Source code in octomate/config/mcp/base.py
class McpConfig(BaseModel):
    """What every MCP tentacle is configured with: the server, and the name its
    tools are listed under."""

    type: str
    enabled: bool = True

type pydantic-field

type: str

enabled pydantic-field

enabled: bool = True

BareMcpConfig pydantic-model

Bases: McpConfig

A vendor's MCP server spoken to with one operator credential for every caller: the deployment's identity, not the person's.

Fields:

Source code in octomate/config/mcp/base.py
class BareMcpConfig(McpConfig):
    """A vendor's MCP server spoken to with one operator credential for every
    caller: the deployment's identity, not the person's."""

    type: Literal["bare"] = "bare"
    url: str
    token: SecretStr | None = None

type pydantic-field

type: Literal['bare'] = 'bare'

url pydantic-field

url: str

token pydantic-field

token: SecretStr | None = None

DiscoveredOAuthMcpConfig pydantic-model

Bases: McpConfig

OAuth settings discovered from the resource server, using DCR or CIMD.

Config:

  • extra: forbid

Fields:

Source code in octomate/config/mcp/base.py
class DiscoveredOAuthMcpConfig(McpConfig):
    """OAuth settings discovered from the resource server, using DCR or CIMD."""

    model_config = ConfigDict(extra="forbid")

    type: Literal["oauth_discovery"] = "oauth_discovery"
    url: HttpsUrl

model_config class-attribute instance-attribute

model_config = ConfigDict(extra='forbid')

type pydantic-field

type: Literal['oauth_discovery'] = 'oauth_discovery'

url pydantic-field

url: HttpsUrl

DeviceFlowConfig pydantic-model

Bases: BaseModel

A provider's device authorization flow: its endpoints and client auth.

Fields:

Source code in octomate/config/mcp/base.py
class DeviceFlowConfig(BaseModel):
    """A provider's device authorization flow: its endpoints and client auth."""

    type: Literal["device"] = "device"
    device_authorization_endpoint: HttpsUrl
    token_endpoint: HttpsUrl
    token_endpoint_auth_method: Literal[
        "none", "client_secret_basic", "client_secret_post"
    ] = "none"

type pydantic-field

type: Literal['device'] = 'device'

device_authorization_endpoint pydantic-field

device_authorization_endpoint: HttpsUrl

token_endpoint pydantic-field

token_endpoint: HttpsUrl

token_endpoint_auth_method pydantic-field

token_endpoint_auth_method: Literal[
    "none", "client_secret_basic", "client_secret_post"
] = "none"

AuthorizationCodeFlowConfig pydantic-model

Bases: BaseModel

A provider's authorization-code flow: its endpoints and client auth.

Fields:

Source code in octomate/config/mcp/base.py
class AuthorizationCodeFlowConfig(BaseModel):
    """A provider's authorization-code flow: its endpoints and client auth."""

    type: Literal["authorization_code"] = "authorization_code"
    authorization_endpoint: HttpsUrl
    token_endpoint: HttpsUrl
    token_endpoint_auth_method: Literal[
        "none", "client_secret_basic", "client_secret_post"
    ] = "none"

type pydantic-field

type: Literal['authorization_code'] = 'authorization_code'

authorization_endpoint pydantic-field

authorization_endpoint: HttpsUrl

token_endpoint pydantic-field

token_endpoint: HttpsUrl

token_endpoint_auth_method pydantic-field

token_endpoint_auth_method: Literal[
    "none", "client_secret_basic", "client_secret_post"
] = "none"

OAuthMcpConfig pydantic-model

Bases: McpConfig

A configured OAuth application whose grants belong to individual users.

Fields:

Validators:

Source code in octomate/config/mcp/base.py
class OAuthMcpConfig(McpConfig):
    """A configured OAuth application whose grants belong to individual users."""

    type: Literal["oauth"] = "oauth"
    url: HttpsUrl
    client_id: str = Field(min_length=1)
    client_secret: SecretStr | None = None
    scopes: list[str] = Field(
        default_factory=list,
        description="Access requested when connecting. Widening it requires reauthorization.",
    )
    scope_separator: Literal[" ", ","] = Field(
        default=" ",
        description="Delimiter used in the provider's token response scopes.",
    )
    invalid_credentials_errors: list[str] = Field(
        default_factory=lambda: ["invalid_grant", "invalid_client"],
        description="OAuth error codes that require reconnecting instead of retrying a refresh.",
    )
    flows: list[
        Annotated[
            DeviceFlowConfig | AuthorizationCodeFlowConfig, Field(discriminator="type")
        ]
    ] = Field(
        min_length=1,
        description="Available authorization flows; the first is the default.",
    )

    @model_validator(mode="after")
    def validate_client_authentication(self) -> Self:
        if len({flow.type for flow in self.flows}) != len(self.flows):
            raise ValueError("OAuth flow types must be unique")
        if all(flow.token_endpoint_auth_method == "none" for flow in self.flows):
            if self.client_secret is not None:
                raise ValueError(
                    "client_secret requires a token endpoint authentication method"
                )
        elif self.client_secret is None or not self.client_secret.get_secret_value():
            raise ValueError(
                "the token endpoint authentication method requires client_secret"
            )
        return self

type pydantic-field

type: Literal['oauth'] = 'oauth'

url pydantic-field

url: HttpsUrl

client_id pydantic-field

client_id: str

client_secret pydantic-field

client_secret: SecretStr | None = None

scopes pydantic-field

scopes: list[str]

Access requested when connecting. Widening it requires reauthorization.

scope_separator pydantic-field

scope_separator: Literal[' ', ','] = ' '

Delimiter used in the provider's token response scopes.

invalid_credentials_errors pydantic-field

invalid_credentials_errors: list[str]

OAuth error codes that require reconnecting instead of retrying a refresh.

flows pydantic-field

flows: list[
    Annotated[
        DeviceFlowConfig | AuthorizationCodeFlowConfig,
        Field(discriminator="type"),
    ]
]

Available authorization flows; the first is the default.

validate_client_authentication pydantic-validator

validate_client_authentication() -> Self
Source code in octomate/config/mcp/base.py
@model_validator(mode="after")
def validate_client_authentication(self) -> Self:
    if len({flow.type for flow in self.flows}) != len(self.flows):
        raise ValueError("OAuth flow types must be unique")
    if all(flow.token_endpoint_auth_method == "none" for flow in self.flows):
        if self.client_secret is not None:
            raise ValueError(
                "client_secret requires a token endpoint authentication method"
            )
    elif self.client_secret is None or not self.client_secret.get_secret_value():
        raise ValueError(
            "the token endpoint authentication method requires client_secret"
        )
    return self

octomate.config.mcp.pool

Idle eviction for pooled MCP clients.

McpPoolConfig pydantic-model

Bases: BaseModel

Idle eviction for pooled MCP clients.

Fields:

Source code in octomate/config/mcp/pool.py
class McpPoolConfig(BaseModel):
    """Idle eviction for pooled MCP clients."""

    idle_timeout: float = Field(
        default=60 * 60.0,
        gt=0,
        allow_inf_nan=False,
        description=(
            "Seconds since the latest acquisition before a cached MCP client is "
            "closed. Each acquisition renews the cleanup timer."
        ),
    )

idle_timeout pydantic-field

idle_timeout: float = 60 * 60.0

Seconds since the latest acquisition before a cached MCP client is closed. Each acquisition renews the cleanup timer.