Skip to main content

Client

Struct Client 

Source
pub struct Client<S: State = Disconnected> { /* private fields */ }
Expand description

The Montrose MCP client

The client must first be connected, then the Montrose API functions can be used. Build a client using ClientBuilder. The user will by default automatically be requested to authenticate if there is no valid cached OAuth token.

The high-level API functions provide a Rust-style API, where the type system is used to enforce required and mutually exclusive arguments.

The low-level API functions provide an API functions that are generated directly from the MCP API. They provide less guardrails and are clunkier to use, but can allow access to functionality not yet provided by the high-level API functions.

The raw API functions allow calling MCP tools with raw JSON data.

§Examples

let montrose = ClientBuilder::new("My Montrose Client").build().await?;
let montrose = montrose.connect().await?;

let accounts = montrose.get_user_accounts().await?;
for account in &accounts {
    dbg!(account);
}

montrose.disconnect().await;

Implementations§

Source§

impl Client<Connected>

§Client state

Source

pub async fn disconnect(self) -> Client<Disconnected>

Disconnects from the MCP server.

Source§

impl Client<Connected>

§High-level API

Each method maps directly to a Montrose MCP tool of the same name.

Source

pub async fn get_holdings( &self, selection: AccountFilter, ) -> Result<Vec<AccountHoldings>, ClientCallError>

Returns holdings for either one account (when AccountFilter::AccountId is provided) or all accessible accounts. Each account includes currency_positions: the account’s multi-currency cash balances with the amount available for purchase per currency. An empty currency_positions list means the account holds cash only in its main currency (see summary). Use get_user_accounts first to find valid account IDs.

Source

pub async fn get_user_accounts( &self, ) -> Result<Vec<AccountIdentifiers>, ClientCallError>

Returns all user accounts with stable account IDs and display names. Use this tool to discover valid account IDs before calling get_holdings for a specific account.

Source

pub async fn create_trade_ticket( &self, args: TradeTicketArgs, ) -> Result<Url, ClientCallError>

Creates a pre-filled trade ticket URL for the Montrose app. Specify side (Buy/Sell), quantity or amount, and an instrument identifier. Use orderbookId directly when known, since it is the safest identifier. If you only know a ticker or name and it may be ambiguous, call search_instruments first to find the correct orderbookId, then call create_trade_ticket. Returns a URL that opens the trade ticket in the Montrose app with the order details pre-filled.

Source

pub async fn search_instruments( &self, query: &str, ) -> Result<Vec<InstrumentIdentifiers>, ClientCallError>

Searches instruments by ticker or name and returns matching orderbookIds, tickers, and names. Use this tool before create_trade_ticket when multiple instruments have similar names.

Seems to return at most 9 results.

Source

pub async fn get_watchlists( &self, ) -> Result<Vec<WatchlistInfo>, ClientCallError>

Returns the authenticated user’s watchlists with their ID, name, and the number of instruments on each list. Use get_watchlist with a listId to read the instruments on a specific watchlist.

Source

pub async fn get_watchlist( &self, list_id: u64, ) -> Result<Watchlist, ClientCallError>

Returns the instruments on a single watchlist, identified by list_id. Each instrument is enriched with its orderbookId, ticker and name. Use get_watchlists first to discover valid listIds.

Source

pub async fn create_watchlist( &self, name: &str, ) -> Result<WatchlistInfo, ClientCallError>

Creates a new watchlist with the given name for the authenticated user. If a watchlist with the same name already exists, returns that existing watchlist.

Source

pub async fn add_to_watchlist( &self, list_id: u64, orderbook_ids: &[u64], ) -> Result<ModifyWatchlistResult, ClientCallError>

Adds one or more instruments to an existing watchlist by orderbookId. Use search_instruments to find the correct orderbookId for a ticker or name. Instruments already on the watchlist are silently skipped.

Source

pub async fn remove_from_watchlist( &self, list_id: u64, orderbook_ids: &[u64], ) -> Result<ModifyWatchlistResult, ClientCallError>

Removes one or more instruments from a watchlist by orderbookId. Returns the orderbookIds that were actually removed; orderbookIds that were not on the watchlist are silently ignored and excluded from the response.

Source§

impl Client<Connected>

§Raw API

The following methods provides raw API access to the MCP.

Source

pub async fn raw_tool_call<T: DeserializeOwned>( &self, tool_name: impl Into<Cow<'static, str>>, args: Option<JsonObject>, ) -> Result<T, ClientCallError>

Available on crate feature raw-api only.

Raw API. Calls the specified MCP tool with the given arguments.

This function can be used before a new MCP API tool has been added to southesk.

Set T as a type that implements Deserialize that matches the expected response format. You can use serde_json::Value when the format is unknown.

This is a raw API call. Prefer using the higher-level methods when available.

§Examples
use southesk::raw::json_object;

let result: serde_json::Value = client
    .raw_tool_call::<serde_json::Value>(
        "get_holdings",
        Some(json_object!({"accountId": "771c4286-991c-48aa-965e-c7dd62e31735"})))
    .await?;
let mut args = serde_json::Map::new();
args.insert(
    "accountId".to_string(),
    "771c4286-991c-48aa-965e-c7dd62e31735".into(),
);
let result: serde_json::Value = client
    .raw_tool_call::<serde_json::Value>("get_holdings", Some(args))
    .await?;
Source§

impl Client<Disconnected>

Source

pub async fn connect(self) -> Result<Client<Connected>, ClientConnectError>

Sets up a new MCP connection.

This will automatically handle authentication, including refreshing tokens if needed. If there are no valid credentials, the user will be prompted to authenticate.

Use ClientBuilder::no_auth to disable interactive authentication.

Call disconnect to disconnect cleanly at shutdown.

Source§

impl Client<Connected>

§Low-level API

The following methods provides a direct mapping to the API provided by the MCP. They are less ergonomic than the high-level methods. Each method maps directly to a Montrose MCP tool of the same name.

Source

pub async fn low_get_holdings<'arg>( &self, account_id: Option<&'arg str>, ) -> Result<Vec<GetHoldingsReturnItem>, ClientCallError>

Available on crate feature low-api only.

Low-level API. Returns holdings for either one account (when accountId is provided) or all accessible accounts. Each account includes currencyPositions: the account’s multi-currency cash balances with the amount available for purchase per currency. An empty currencyPositions list means the account holds cash only in its main currency (see the summary). Use GetUserAccounts first to find valid account IDs.

account_id: Optional account ID as a UUID/GUID string (e.g. “3fa85f64-5717-4562-b3fc-2c963f66afa6”). Use GetUserAccounts to find valid account IDs. If omitted, holdings are returned for all accessible accounts.

Source

pub async fn low_add_to_watchlist<'arg>( &self, list_id: i64, orderbook_ids: &'arg [i64], ) -> Result<AddToWatchlistReturn, ClientCallError>

Available on crate feature low-api only.

Low-level API. Adds one or more instruments to an existing watchlist by orderbookId. Use SearchInstruments to find the correct orderbookId for a ticker or name. Instruments already on the watchlist are silently skipped.

list_id: The watchlist ID returned by GetWatchlists.

orderbook_ids: OrderbookIds (int) of the instruments to add. Use SearchInstruments to find the correct orderbookId.

Source

pub async fn low_search_instruments<'arg>( &self, query: &'arg str, ) -> Result<Vec<SearchInstrumentsReturnItem>, ClientCallError>

Available on crate feature low-api only.

Low-level API. Searches instruments by ticker or name and returns matching orderbookIds, tickers, and names. Use this tool before CreateTradeTicket when multiple instruments have similar names.

query: Ticker or instrument name to search for.

Source

pub async fn low_create_trade_ticket( &self, args: CreateTradeTicketArgs<'_>, ) -> Result<String, ClientCallError>

Available on crate feature low-api only.

Low-level API. Creates a pre-filled trade ticket URL for the Montrose app. Specify side (Buy/Sell), quantity or amount, and an instrument identifier. Use orderbookId directly when known, since it is the safest identifier. If you only know a ticker or name and it may be ambiguous, call SearchInstruments first to find the correct orderbookId, then call CreateTradeTicket. Returns a URL that opens the trade ticket in the Montrose app with the order details pre-filled.

Source

pub async fn low_get_watchlists( &self, ) -> Result<Vec<GetWatchlistsReturnItem>, ClientCallError>

Available on crate feature low-api only.

Low-level API. Returns the authenticated user’s watchlists with their ID, name, and the number of instruments on each list. Use GetWatchlist with a listId to read the instruments on a specific watchlist.

Source

pub async fn low_create_watchlist<'arg>( &self, name: &'arg str, ) -> Result<CreateWatchlistReturn, ClientCallError>

Available on crate feature low-api only.

Low-level API. Creates a new watchlist with the given name for the authenticated user. If a watchlist with the same name already exists, returns that existing watchlist.

name: The name of the watchlist to create.

Source

pub async fn low_get_watchlist( &self, list_id: i64, ) -> Result<GetWatchlistReturn, ClientCallError>

Available on crate feature low-api only.

Low-level API. Returns the instruments on a single watchlist, identified by listId. Each instrument is enriched with its orderbookId, ticker and name. Use GetWatchlists first to discover valid listIds.

list_id: The watchlist ID returned by GetWatchlists.

Source

pub async fn low_remove_from_watchlist<'arg>( &self, list_id: i64, orderbook_ids: &'arg [i64], ) -> Result<RemoveFromWatchlistReturn, ClientCallError>

Available on crate feature low-api only.

Low-level API. Removes one or more instruments from a watchlist by orderbookId. Returns the orderbookIds that were actually removed; orderbookIds that were not on the watchlist are silently ignored and excluded from the response.

list_id: The watchlist ID returned by GetWatchlists.

orderbook_ids: OrderbookIds (int) of the instruments to remove.

Source

pub async fn low_get_user_accounts( &self, ) -> Result<Vec<GetUserAccountsReturnItem>, ClientCallError>

Available on crate feature low-api only.

Low-level API. Returns all user accounts with stable account IDs and display names. Use this tool to discover valid account IDs before calling GetHoldings for a specific account.

Trait Implementations§

Source§

impl<S: Debug + State> Debug for Client<S>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<S = Disconnected> !RefUnwindSafe for Client<S>

§

impl<S = Disconnected> !Send for Client<S>

§

impl<S = Disconnected> !Sync for Client<S>

§

impl<S = Disconnected> !UnwindSafe for Client<S>

§

impl<S> Freeze for Client<S>
where S: Freeze,

§

impl<S> Unpin for Client<S>
where S: Unpin,

§

impl<S> UnsafeUnpin for Client<S>
where S: UnsafeUnpin,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more