# This file was auto-generated by Fern from our API Definition.

import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.call_tool_response import CallToolResponse
from ..types.connection_type import ConnectionType
from ..types.create_self_hosted_server_response import CreateSelfHostedServerResponse
from ..types.create_server_response import CreateServerResponse
from ..types.external_server_request import ExternalServerRequest
from ..types.get_auth_data_response import GetAuthDataResponse
from ..types.get_instance_response import GetInstanceResponse
from ..types.get_mcp_servers_response import GetMcpServersResponse
from ..types.get_o_auth_url_response import GetOAuthUrlResponse
from ..types.http_validation_error import HttpValidationError
from ..types.list_tools_response import ListToolsResponse
from ..types.mcp_server_name import McpServerName
from ..types.status_response import StatusResponse
from ..types.strata_add_servers_response import StrataAddServersResponse
from ..types.strata_create_response import StrataCreateResponse
from ..types.strata_delete_servers_response import StrataDeleteServersResponse
from ..types.strata_get_response import StrataGetResponse
from ..types.tool_format import ToolFormat
from .types.authdata import Authdata
from .types.delete_servers_from_strata_mcp_server_strata_strata_id_servers_delete_request_servers_item import (
    DeleteServersFromStrataMcpServerStrataStrataIdServersDeleteRequestServersItem,
)
from .types.servers import Servers

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class RawMcpServerClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def call_tools(
        self,
        *,
        server_url: str,
        tool_name: str,
        tool_args: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        connection_type: typing.Optional[ConnectionType] = OMIT,
        headers: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CallToolResponse]:
        """
        Calls a tool on a specific remote MCP server, used for function calling. Eliminates the need for manual MCP code implementation.
        Under the hood, Klavis will instantiates an MCP client and establishes a connection with the remote MCP server to call the tool.

        Parameters
        ----------
        server_url : str
            The full URL for connecting to the MCP server

        tool_name : str
            The name of the tool to call

        tool_args : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            The input parameters for the tool

        connection_type : typing.Optional[ConnectionType]
            The connection type to use for the MCP server. Default is STREAMABLE_HTTP.

        headers : typing.Optional[typing.Dict[str, typing.Optional[str]]]
            Optional HTTP headers to include when connecting to the server

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[CallToolResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "mcp-server/call-tool",
            method="POST",
            json={
                "serverUrl": server_url,
                "toolName": tool_name,
                "toolArgs": tool_args,
                "connectionType": connection_type,
                "headers": headers,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CallToolResponse,
                    parse_obj_as(
                        type_=CallToolResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def list_tools(
        self,
        *,
        server_url: str,
        connection_type: typing.Optional[ConnectionType] = OMIT,
        format: typing.Optional[ToolFormat] = OMIT,
        headers: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ListToolsResponse]:
        """
        Lists all tools available for a specific remote MCP server in various AI model formats.

        This eliminates the need for manual MCP code implementation and format conversion.
        Under the hood, Klavis instantiates an MCP client and establishes a connection
        with the remote MCP server to retrieve available tools.

        Parameters
        ----------
        server_url : str
            The full URL for connecting to the MCP server

        connection_type : typing.Optional[ConnectionType]
            The connection type to use for the MCP server. Default is STREAMABLE_HTTP.

        format : typing.Optional[ToolFormat]
            The format to return tools in. Default is MCP Native format for maximum compatibility.

        headers : typing.Optional[typing.Dict[str, typing.Optional[str]]]
            Optional HTTP headers to include when connecting to the server

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ListToolsResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "mcp-server/list-tools",
            method="POST",
            json={
                "serverUrl": server_url,
                "connectionType": connection_type,
                "format": format,
                "headers": headers,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListToolsResponse,
                    parse_obj_as(
                        type_=ListToolsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def create_strata_server(
        self,
        *,
        user_id: str,
        servers: typing.Optional[Servers] = OMIT,
        external_servers: typing.Optional[typing.Sequence[ExternalServerRequest]] = OMIT,
        enable_auth_handling: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[StrataCreateResponse]:
        """
        Create a Strata MCP server.

        Parameters:
        - servers: Can be 'ALL' to add all available Klavis MCP servers, a list of specific server names, or null to add no servers
        - externalServers: Optional list of external MCP servers to validate and add

        Parameters
        ----------
        user_id : str
            The unique identifier for the user. The server instance along with the all the authentication data will belong to that specific user only. It can be a UUID from the database, a unique email address from the user, etc.

        servers : typing.Optional[Servers]
            List of Klavis MCP servers to enable (e.g., 'jira', 'linear'), 'ALL' to add all Klavis MCP servers, or null to add no servers.

        external_servers : typing.Optional[typing.Sequence[ExternalServerRequest]]
            Optional list of external MCP servers to add with their URLs. Each server will be validated before being added.

        enable_auth_handling : typing.Optional[bool]
            Whether to enable authentication handling. Default is True.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[StrataCreateResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "mcp-server/strata/create",
            method="POST",
            json={
                "userId": user_id,
                "servers": convert_and_respect_annotation_metadata(
                    object_=servers, annotation=Servers, direction="write"
                ),
                "externalServers": convert_and_respect_annotation_metadata(
                    object_=external_servers, annotation=typing.Sequence[ExternalServerRequest], direction="write"
                ),
                "enable_auth_handling": enable_auth_handling,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StrataCreateResponse,
                    parse_obj_as(
                        type_=StrataCreateResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def add_servers_to_strata(
        self,
        *,
        strata_id: str,
        servers: typing.Optional[Servers] = OMIT,
        external_servers: typing.Optional[typing.Sequence[ExternalServerRequest]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[StrataAddServersResponse]:
        """
        Add servers to an existing Strata MCP server.

        Note: After adding servers, you need to reconnect the MCP server so that list_tool can be updated with the new servers.

        Parameters:
        - servers: Can be 'ALL' to add all available servers, a list of specific server names, or null to add no servers
        - externalServers: Optional list of external MCP servers to validate and add

        Parameters
        ----------
        strata_id : str
            The strata server ID

        servers : typing.Optional[Servers]
            List of Klavis MCP servers to add (e.g., 'jira', 'linear'), 'ALL' to add all Klavis MCP servers, or null to add no servers.

        external_servers : typing.Optional[typing.Sequence[ExternalServerRequest]]
            Optional list of external MCP servers to add with their URLs. Each server will be validated before being added.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[StrataAddServersResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "mcp-server/strata/add",
            method="POST",
            json={
                "strataId": strata_id,
                "servers": convert_and_respect_annotation_metadata(
                    object_=servers, annotation=Servers, direction="write"
                ),
                "externalServers": convert_and_respect_annotation_metadata(
                    object_=external_servers, annotation=typing.Sequence[ExternalServerRequest], direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StrataAddServersResponse,
                    parse_obj_as(
                        type_=StrataAddServersResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def delete_servers_from_strata(
        self,
        strata_id: str,
        *,
        servers: typing.Optional[
            typing.Union[
                DeleteServersFromStrataMcpServerStrataStrataIdServersDeleteRequestServersItem,
                typing.Sequence[DeleteServersFromStrataMcpServerStrataStrataIdServersDeleteRequestServersItem],
            ]
        ] = None,
        external_servers: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[StrataDeleteServersResponse]:
        """
        Delete servers from an existing Strata MCP server.

        Note: After deleting servers, you need to reconnect the MCP server so that list_tool can be updated to reflect the removed servers.

        Parameters:
        - strataId: The strata server ID (path parameter)
        - servers: Can be 'ALL' to delete all available Klavis MCP servers, a list of specific server names, or null to delete no servers
        - externalServers: Query parameter - comma-separated list of external server names to delete

        Returns separate lists for deleted Klavis servers and deleted external servers.

        Parameters
        ----------
        strata_id : str

        servers : typing.Optional[typing.Union[DeleteServersFromStrataMcpServerStrataStrataIdServersDeleteRequestServersItem, typing.Sequence[DeleteServersFromStrataMcpServerStrataStrataIdServersDeleteRequestServersItem]]]
            List of Klavis MCP servers to delete (e.g., 'jira', 'linear'), 'ALL' to delete all Klavis MCP servers, or null to delete no servers.

        external_servers : typing.Optional[str]
            Comma-separated list of external server names to delete

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[StrataDeleteServersResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"mcp-server/strata/{jsonable_encoder(strata_id)}/servers",
            method="DELETE",
            params={
                "servers": servers,
                "externalServers": external_servers,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StrataDeleteServersResponse,
                    parse_obj_as(
                        type_=StrataDeleteServersResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_strata_instance(
        self, strata_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[StrataGetResponse]:
        """
        Get information about an existing Strata MCP server instance.

        Returns the strata URL, connected klavis servers, connected external servers (with URLs),
        and authentication URLs for klavis servers.

        Parameters
        ----------
        strata_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[StrataGetResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"mcp-server/strata/{jsonable_encoder(strata_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StrataGetResponse,
                    parse_obj_as(
                        type_=StrataGetResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def set_strata_auth(
        self,
        *,
        strata_id: str,
        server_name: McpServerName,
        auth_data: Authdata,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[StatusResponse]:
        """
        Sets authentication data for a specific integration within a Strata MCP server.

        Accepts either API key authentication or general authentication data.

        Parameters
        ----------
        strata_id : str
            The strata server ID

        server_name : McpServerName
            The name of the Klavis MCP server to set authentication for (e.g., 'GitHub', 'Jira')

        auth_data : Authdata
            Authentication data

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[StatusResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "mcp-server/strata/set-auth",
            method="POST",
            json={
                "strataId": strata_id,
                "serverName": server_name,
                "authData": convert_and_respect_annotation_metadata(
                    object_=auth_data, annotation=Authdata, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def create_server_instance(
        self,
        *,
        server_name: McpServerName,
        user_id: str,
        platform_name: typing.Optional[str] = OMIT,
        connection_type: typing.Optional[ConnectionType] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CreateServerResponse]:
        """
        Creates a URL for a specified MCP server,
        validating the request with an API key and user details.
        Returns the existing server URL if it already exists for the user.
        If OAuth is configured for the server, also returns the base OAuth authorization URL.

        Parameters
        ----------
        server_name : McpServerName
            The name of the target MCP server. Case-insensitive (e.g., 'google calendar', 'GOOGLE_CALENDAR', 'Google Calendar' are all valid).

        user_id : str
            The unique identifier for the user. The server instance along with the all the authentication data will belong to that specific user only. It can be a UUID from the database, a unique email address from the user, etc.

        platform_name : typing.Optional[str]
            The name of the platform associated with the user. Optional.

        connection_type : typing.Optional[ConnectionType]
            The connection type to use for the MCP server. Default is STREAMABLE_HTTP.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[CreateServerResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "mcp-server/instance/create",
            method="POST",
            json={
                "serverName": server_name,
                "userId": user_id,
                "platformName": platform_name,
                "connectionType": connection_type,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateServerResponse,
                    parse_obj_as(
                        type_=CreateServerResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def create_self_hosted_server_instance(
        self, *, server_name: McpServerName, user_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[CreateSelfHostedServerResponse]:
        """
        Creates an instance id for a self-hosted MCP server,
        validating the request with an API key and user details.
        The main purpose of this endpoint is to create an instance id for a self-hosted MCP server.
        The instance id is used to identify and store the auth metadata in the database.
        Returns the existing instance id if it already exists for the user.

        Parameters
        ----------
        server_name : McpServerName
            The name of the target MCP server. Case-insensitive (e.g., 'google calendar', 'GOOGLE_CALENDAR', 'Google Calendar' are all valid).

        user_id : str
            The unique identifier for the user. The server instance along with the all the authentication data will belong to that specific user only. It can be a UUID from the database, a unique email address from the user, etc.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[CreateSelfHostedServerResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "mcp-server/self-hosted/instance/create",
            method="POST",
            json={
                "serverName": server_name,
                "userId": user_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateSelfHostedServerResponse,
                    parse_obj_as(
                        type_=CreateSelfHostedServerResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_server_instance(
        self, instance_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[GetInstanceResponse]:
        """
        Checks the details of a specific server connection instance using its unique ID and API key,
        returning server details like authentication status and associated server/platform info.

        Parameters
        ----------
        instance_id : str
            The ID of the connection instance whose status is being checked. This is returned by the Create API.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[GetInstanceResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"mcp-server/instance/get/{jsonable_encoder(instance_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetInstanceResponse,
                    parse_obj_as(
                        type_=GetInstanceResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def delete_instance_auth(
        self, instance_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[StatusResponse]:
        """
        Deletes authentication data for a specific server connection instance.

        Parameters
        ----------
        instance_id : str
            The ID of the connection instance to delete auth for.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[StatusResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"mcp-server/instance/delete-auth/{jsonable_encoder(instance_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def delete_server_instance(
        self, instance_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[StatusResponse]:
        """
        Completely removes a server connection instance using its unique ID,
        deleting all associated data from the system.

        Parameters
        ----------
        instance_id : str
            The ID of the connection instance to delete.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[StatusResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"mcp-server/instance/delete/{jsonable_encoder(instance_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_tools(
        self,
        server_name: McpServerName,
        *,
        format: typing.Optional[ToolFormat] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ListToolsResponse]:
        """
        Get tools information for any MCP server.

        Parameters
        ----------
        server_name : McpServerName
            The name of the target MCP server. Case-insensitive (e.g., 'google calendar', 'GOOGLE_CALENDAR', 'Google Calendar' are all valid).

        format : typing.Optional[ToolFormat]
            The format to return tools in. Default is MCP Native format for maximum compatibility.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ListToolsResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"mcp-server/tools/{jsonable_encoder(server_name)}",
            method="GET",
            params={
                "format": format,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListToolsResponse,
                    parse_obj_as(
                        type_=ListToolsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_all_mcp_servers(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[GetMcpServersResponse]:
        """
        Get all MCP servers with their basic information including id, name, description, and tools.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[GetMcpServersResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "mcp-server/servers",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetMcpServersResponse,
                    parse_obj_as(
                        type_=GetMcpServersResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def set_instance_auth(
        self, *, instance_id: str, auth_data: Authdata, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[StatusResponse]:
        """
        Sets authentication data for a specific instance.
        Accepts either API key authentication or general authentication data.
        This updates the auth_metadata for the specified instance.

        Parameters
        ----------
        instance_id : str
            The unique identifier for the connection instance

        auth_data : Authdata
            Authentication data

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[StatusResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "mcp-server/instance/set-auth",
            method="POST",
            json={
                "instanceId": instance_id,
                "authData": convert_and_respect_annotation_metadata(
                    object_=auth_data, annotation=Authdata, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_instance_auth_data(
        self, instance_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[GetAuthDataResponse]:
        """
        Retrieves the auth data for a specific instance that the API key owner controls.
        Includes access token, refresh token, and other authentication data.

        This endpoint includes proper ownership verification to ensure users can only access
        authentication data for instances they own. It also handles token refresh if needed.

        Parameters
        ----------
        instance_id : str
            The ID of the connection instance to get auth data for.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[GetAuthDataResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"mcp-server/instance/get-auth/{jsonable_encoder(instance_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetAuthDataResponse,
                    parse_obj_as(
                        type_=GetAuthDataResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_o_auth_url(
        self,
        *,
        server_name: McpServerName,
        instance_id: str,
        client_id: typing.Optional[str] = OMIT,
        scope: typing.Optional[str] = OMIT,
        redirect_url: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[GetOAuthUrlResponse]:
        """
        Gets the OAuth authorization URL for a specific MCP server and instance.
        Returns the complete OAuth URL with the instance ID as a query parameter.

        Parameters
        ----------
        server_name : McpServerName
            The name of the target MCP server. Case-insensitive (e.g., 'google calendar', 'GOOGLE_CALENDAR', 'Google Calendar' are all valid).

        instance_id : str
            The unique identifier for the connection instance.

        client_id : typing.Optional[str]
            Optional client ID for white labeling. If not provided, will use default credentials.

        scope : typing.Optional[str]
            Optional OAuth scopes to request (comma-separated string).

        redirect_url : typing.Optional[str]
            Optional URL to redirect to after authorization completes.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[GetOAuthUrlResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "mcp-server/oauth-url",
            method="POST",
            json={
                "serverName": server_name,
                "instanceId": instance_id,
                "clientId": client_id,
                "scope": scope,
                "redirectUrl": redirect_url,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetOAuthUrlResponse,
                    parse_obj_as(
                        type_=GetOAuthUrlResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


class AsyncRawMcpServerClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def call_tools(
        self,
        *,
        server_url: str,
        tool_name: str,
        tool_args: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
        connection_type: typing.Optional[ConnectionType] = OMIT,
        headers: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CallToolResponse]:
        """
        Calls a tool on a specific remote MCP server, used for function calling. Eliminates the need for manual MCP code implementation.
        Under the hood, Klavis will instantiates an MCP client and establishes a connection with the remote MCP server to call the tool.

        Parameters
        ----------
        server_url : str
            The full URL for connecting to the MCP server

        tool_name : str
            The name of the tool to call

        tool_args : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
            The input parameters for the tool

        connection_type : typing.Optional[ConnectionType]
            The connection type to use for the MCP server. Default is STREAMABLE_HTTP.

        headers : typing.Optional[typing.Dict[str, typing.Optional[str]]]
            Optional HTTP headers to include when connecting to the server

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[CallToolResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "mcp-server/call-tool",
            method="POST",
            json={
                "serverUrl": server_url,
                "toolName": tool_name,
                "toolArgs": tool_args,
                "connectionType": connection_type,
                "headers": headers,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CallToolResponse,
                    parse_obj_as(
                        type_=CallToolResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def list_tools(
        self,
        *,
        server_url: str,
        connection_type: typing.Optional[ConnectionType] = OMIT,
        format: typing.Optional[ToolFormat] = OMIT,
        headers: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ListToolsResponse]:
        """
        Lists all tools available for a specific remote MCP server in various AI model formats.

        This eliminates the need for manual MCP code implementation and format conversion.
        Under the hood, Klavis instantiates an MCP client and establishes a connection
        with the remote MCP server to retrieve available tools.

        Parameters
        ----------
        server_url : str
            The full URL for connecting to the MCP server

        connection_type : typing.Optional[ConnectionType]
            The connection type to use for the MCP server. Default is STREAMABLE_HTTP.

        format : typing.Optional[ToolFormat]
            The format to return tools in. Default is MCP Native format for maximum compatibility.

        headers : typing.Optional[typing.Dict[str, typing.Optional[str]]]
            Optional HTTP headers to include when connecting to the server

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ListToolsResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "mcp-server/list-tools",
            method="POST",
            json={
                "serverUrl": server_url,
                "connectionType": connection_type,
                "format": format,
                "headers": headers,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListToolsResponse,
                    parse_obj_as(
                        type_=ListToolsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def create_strata_server(
        self,
        *,
        user_id: str,
        servers: typing.Optional[Servers] = OMIT,
        external_servers: typing.Optional[typing.Sequence[ExternalServerRequest]] = OMIT,
        enable_auth_handling: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[StrataCreateResponse]:
        """
        Create a Strata MCP server.

        Parameters:
        - servers: Can be 'ALL' to add all available Klavis MCP servers, a list of specific server names, or null to add no servers
        - externalServers: Optional list of external MCP servers to validate and add

        Parameters
        ----------
        user_id : str
            The unique identifier for the user. The server instance along with the all the authentication data will belong to that specific user only. It can be a UUID from the database, a unique email address from the user, etc.

        servers : typing.Optional[Servers]
            List of Klavis MCP servers to enable (e.g., 'jira', 'linear'), 'ALL' to add all Klavis MCP servers, or null to add no servers.

        external_servers : typing.Optional[typing.Sequence[ExternalServerRequest]]
            Optional list of external MCP servers to add with their URLs. Each server will be validated before being added.

        enable_auth_handling : typing.Optional[bool]
            Whether to enable authentication handling. Default is True.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[StrataCreateResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "mcp-server/strata/create",
            method="POST",
            json={
                "userId": user_id,
                "servers": convert_and_respect_annotation_metadata(
                    object_=servers, annotation=Servers, direction="write"
                ),
                "externalServers": convert_and_respect_annotation_metadata(
                    object_=external_servers, annotation=typing.Sequence[ExternalServerRequest], direction="write"
                ),
                "enable_auth_handling": enable_auth_handling,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StrataCreateResponse,
                    parse_obj_as(
                        type_=StrataCreateResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def add_servers_to_strata(
        self,
        *,
        strata_id: str,
        servers: typing.Optional[Servers] = OMIT,
        external_servers: typing.Optional[typing.Sequence[ExternalServerRequest]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[StrataAddServersResponse]:
        """
        Add servers to an existing Strata MCP server.

        Note: After adding servers, you need to reconnect the MCP server so that list_tool can be updated with the new servers.

        Parameters:
        - servers: Can be 'ALL' to add all available servers, a list of specific server names, or null to add no servers
        - externalServers: Optional list of external MCP servers to validate and add

        Parameters
        ----------
        strata_id : str
            The strata server ID

        servers : typing.Optional[Servers]
            List of Klavis MCP servers to add (e.g., 'jira', 'linear'), 'ALL' to add all Klavis MCP servers, or null to add no servers.

        external_servers : typing.Optional[typing.Sequence[ExternalServerRequest]]
            Optional list of external MCP servers to add with their URLs. Each server will be validated before being added.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[StrataAddServersResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "mcp-server/strata/add",
            method="POST",
            json={
                "strataId": strata_id,
                "servers": convert_and_respect_annotation_metadata(
                    object_=servers, annotation=Servers, direction="write"
                ),
                "externalServers": convert_and_respect_annotation_metadata(
                    object_=external_servers, annotation=typing.Sequence[ExternalServerRequest], direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StrataAddServersResponse,
                    parse_obj_as(
                        type_=StrataAddServersResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def delete_servers_from_strata(
        self,
        strata_id: str,
        *,
        servers: typing.Optional[
            typing.Union[
                DeleteServersFromStrataMcpServerStrataStrataIdServersDeleteRequestServersItem,
                typing.Sequence[DeleteServersFromStrataMcpServerStrataStrataIdServersDeleteRequestServersItem],
            ]
        ] = None,
        external_servers: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[StrataDeleteServersResponse]:
        """
        Delete servers from an existing Strata MCP server.

        Note: After deleting servers, you need to reconnect the MCP server so that list_tool can be updated to reflect the removed servers.

        Parameters:
        - strataId: The strata server ID (path parameter)
        - servers: Can be 'ALL' to delete all available Klavis MCP servers, a list of specific server names, or null to delete no servers
        - externalServers: Query parameter - comma-separated list of external server names to delete

        Returns separate lists for deleted Klavis servers and deleted external servers.

        Parameters
        ----------
        strata_id : str

        servers : typing.Optional[typing.Union[DeleteServersFromStrataMcpServerStrataStrataIdServersDeleteRequestServersItem, typing.Sequence[DeleteServersFromStrataMcpServerStrataStrataIdServersDeleteRequestServersItem]]]
            List of Klavis MCP servers to delete (e.g., 'jira', 'linear'), 'ALL' to delete all Klavis MCP servers, or null to delete no servers.

        external_servers : typing.Optional[str]
            Comma-separated list of external server names to delete

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[StrataDeleteServersResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"mcp-server/strata/{jsonable_encoder(strata_id)}/servers",
            method="DELETE",
            params={
                "servers": servers,
                "externalServers": external_servers,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StrataDeleteServersResponse,
                    parse_obj_as(
                        type_=StrataDeleteServersResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_strata_instance(
        self, strata_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[StrataGetResponse]:
        """
        Get information about an existing Strata MCP server instance.

        Returns the strata URL, connected klavis servers, connected external servers (with URLs),
        and authentication URLs for klavis servers.

        Parameters
        ----------
        strata_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[StrataGetResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"mcp-server/strata/{jsonable_encoder(strata_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StrataGetResponse,
                    parse_obj_as(
                        type_=StrataGetResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def set_strata_auth(
        self,
        *,
        strata_id: str,
        server_name: McpServerName,
        auth_data: Authdata,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[StatusResponse]:
        """
        Sets authentication data for a specific integration within a Strata MCP server.

        Accepts either API key authentication or general authentication data.

        Parameters
        ----------
        strata_id : str
            The strata server ID

        server_name : McpServerName
            The name of the Klavis MCP server to set authentication for (e.g., 'GitHub', 'Jira')

        auth_data : Authdata
            Authentication data

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[StatusResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "mcp-server/strata/set-auth",
            method="POST",
            json={
                "strataId": strata_id,
                "serverName": server_name,
                "authData": convert_and_respect_annotation_metadata(
                    object_=auth_data, annotation=Authdata, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def create_server_instance(
        self,
        *,
        server_name: McpServerName,
        user_id: str,
        platform_name: typing.Optional[str] = OMIT,
        connection_type: typing.Optional[ConnectionType] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CreateServerResponse]:
        """
        Creates a URL for a specified MCP server,
        validating the request with an API key and user details.
        Returns the existing server URL if it already exists for the user.
        If OAuth is configured for the server, also returns the base OAuth authorization URL.

        Parameters
        ----------
        server_name : McpServerName
            The name of the target MCP server. Case-insensitive (e.g., 'google calendar', 'GOOGLE_CALENDAR', 'Google Calendar' are all valid).

        user_id : str
            The unique identifier for the user. The server instance along with the all the authentication data will belong to that specific user only. It can be a UUID from the database, a unique email address from the user, etc.

        platform_name : typing.Optional[str]
            The name of the platform associated with the user. Optional.

        connection_type : typing.Optional[ConnectionType]
            The connection type to use for the MCP server. Default is STREAMABLE_HTTP.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[CreateServerResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "mcp-server/instance/create",
            method="POST",
            json={
                "serverName": server_name,
                "userId": user_id,
                "platformName": platform_name,
                "connectionType": connection_type,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateServerResponse,
                    parse_obj_as(
                        type_=CreateServerResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def create_self_hosted_server_instance(
        self, *, server_name: McpServerName, user_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[CreateSelfHostedServerResponse]:
        """
        Creates an instance id for a self-hosted MCP server,
        validating the request with an API key and user details.
        The main purpose of this endpoint is to create an instance id for a self-hosted MCP server.
        The instance id is used to identify and store the auth metadata in the database.
        Returns the existing instance id if it already exists for the user.

        Parameters
        ----------
        server_name : McpServerName
            The name of the target MCP server. Case-insensitive (e.g., 'google calendar', 'GOOGLE_CALENDAR', 'Google Calendar' are all valid).

        user_id : str
            The unique identifier for the user. The server instance along with the all the authentication data will belong to that specific user only. It can be a UUID from the database, a unique email address from the user, etc.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[CreateSelfHostedServerResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "mcp-server/self-hosted/instance/create",
            method="POST",
            json={
                "serverName": server_name,
                "userId": user_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateSelfHostedServerResponse,
                    parse_obj_as(
                        type_=CreateSelfHostedServerResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_server_instance(
        self, instance_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[GetInstanceResponse]:
        """
        Checks the details of a specific server connection instance using its unique ID and API key,
        returning server details like authentication status and associated server/platform info.

        Parameters
        ----------
        instance_id : str
            The ID of the connection instance whose status is being checked. This is returned by the Create API.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[GetInstanceResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"mcp-server/instance/get/{jsonable_encoder(instance_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetInstanceResponse,
                    parse_obj_as(
                        type_=GetInstanceResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def delete_instance_auth(
        self, instance_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[StatusResponse]:
        """
        Deletes authentication data for a specific server connection instance.

        Parameters
        ----------
        instance_id : str
            The ID of the connection instance to delete auth for.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[StatusResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"mcp-server/instance/delete-auth/{jsonable_encoder(instance_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def delete_server_instance(
        self, instance_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[StatusResponse]:
        """
        Completely removes a server connection instance using its unique ID,
        deleting all associated data from the system.

        Parameters
        ----------
        instance_id : str
            The ID of the connection instance to delete.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[StatusResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"mcp-server/instance/delete/{jsonable_encoder(instance_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_tools(
        self,
        server_name: McpServerName,
        *,
        format: typing.Optional[ToolFormat] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ListToolsResponse]:
        """
        Get tools information for any MCP server.

        Parameters
        ----------
        server_name : McpServerName
            The name of the target MCP server. Case-insensitive (e.g., 'google calendar', 'GOOGLE_CALENDAR', 'Google Calendar' are all valid).

        format : typing.Optional[ToolFormat]
            The format to return tools in. Default is MCP Native format for maximum compatibility.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ListToolsResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"mcp-server/tools/{jsonable_encoder(server_name)}",
            method="GET",
            params={
                "format": format,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ListToolsResponse,
                    parse_obj_as(
                        type_=ListToolsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_all_mcp_servers(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[GetMcpServersResponse]:
        """
        Get all MCP servers with their basic information including id, name, description, and tools.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[GetMcpServersResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "mcp-server/servers",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetMcpServersResponse,
                    parse_obj_as(
                        type_=GetMcpServersResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def set_instance_auth(
        self, *, instance_id: str, auth_data: Authdata, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[StatusResponse]:
        """
        Sets authentication data for a specific instance.
        Accepts either API key authentication or general authentication data.
        This updates the auth_metadata for the specified instance.

        Parameters
        ----------
        instance_id : str
            The unique identifier for the connection instance

        auth_data : Authdata
            Authentication data

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[StatusResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "mcp-server/instance/set-auth",
            method="POST",
            json={
                "instanceId": instance_id,
                "authData": convert_and_respect_annotation_metadata(
                    object_=auth_data, annotation=Authdata, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_instance_auth_data(
        self, instance_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[GetAuthDataResponse]:
        """
        Retrieves the auth data for a specific instance that the API key owner controls.
        Includes access token, refresh token, and other authentication data.

        This endpoint includes proper ownership verification to ensure users can only access
        authentication data for instances they own. It also handles token refresh if needed.

        Parameters
        ----------
        instance_id : str
            The ID of the connection instance to get auth data for.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[GetAuthDataResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"mcp-server/instance/get-auth/{jsonable_encoder(instance_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetAuthDataResponse,
                    parse_obj_as(
                        type_=GetAuthDataResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_o_auth_url(
        self,
        *,
        server_name: McpServerName,
        instance_id: str,
        client_id: typing.Optional[str] = OMIT,
        scope: typing.Optional[str] = OMIT,
        redirect_url: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[GetOAuthUrlResponse]:
        """
        Gets the OAuth authorization URL for a specific MCP server and instance.
        Returns the complete OAuth URL with the instance ID as a query parameter.

        Parameters
        ----------
        server_name : McpServerName
            The name of the target MCP server. Case-insensitive (e.g., 'google calendar', 'GOOGLE_CALENDAR', 'Google Calendar' are all valid).

        instance_id : str
            The unique identifier for the connection instance.

        client_id : typing.Optional[str]
            Optional client ID for white labeling. If not provided, will use default credentials.

        scope : typing.Optional[str]
            Optional OAuth scopes to request (comma-separated string).

        redirect_url : typing.Optional[str]
            Optional URL to redirect to after authorization completes.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[GetOAuthUrlResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "mcp-server/oauth-url",
            method="POST",
            json={
                "serverName": server_name,
                "instanceId": instance_id,
                "clientId": client_id,
                "scope": scope,
                "redirectUrl": redirect_url,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    GetOAuthUrlResponse,
                    parse_obj_as(
                        type_=GetOAuthUrlResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
