-
Notifications
You must be signed in to change notification settings - Fork 310
Description
Background
We're integrating a third-party API with our MCP server, which requires credentials (like api key/token) for authentication. We need to support multiple instances in a single MCP server, which would require session management. My MCP server runs in SSE mode.
Current Implementation
We're providing the credentials as parameters to each tool, something like:
#[tool]
pub async fn my_tool(
&self,
Parameters(AuthParams { api_token }): Parameters<AuthParams>,
) -> Result<CallToolResult, ErrorData>
let client = MyClient::new(api_token);
match client.request(Method::GET, "endpoint").await {
// Rest of the implementation ...
}
}
Problem
The current implementation is not a great design as passing credentials to each tool is redundant.
In order to add abstraction and to support other third-party APIs as plugins, we cannot define the API clients in the server itself. But we are lost on how to store the user credentials for each session.
We tried adding the Auth Params in the extension of RequestContext
:
#[tool]
pub async fn save_credentials(
&self,
Parameters(AuthParams { api_token }): Parameters<AuthParams>,
mut ctx: RequestContext<RoleServer>
) -> Result<CallToolResult, ErrorData> {
ctx.extensions.insert(AuthParams {
api_token
});
Ok(CallToolResult::success(vec![Content::text(
"Credentials saved successfuly!",
)]))
}
But the extensions remain empty in other tools.
Question
Is there a standard way we can achieve this? Any help would be appreciated. TIA!