sk-agents
sk_agents
sk_agents.a2a
sk_agents.a2a.redis_task_store
DEPRECATION NOTICE: A2A (Agent-to-Agent) functionality is being deprecated as part of the framework migration evaluation. This module is maintained for backward compatibility only. New development should avoid using A2A functionality.
Redis implementation of the TaskStore interface. This implementation uses Redis as the persistent store for Task objects.
sk_agents.a2a.redis_task_store.RedisTaskStore
Bases: TaskStore
Redis implementation of the TaskStore interface.
This class provides Redis-based persistence for Task objects.
Source code in src/sk_agents/a2a/redis_task_store.py
sk_agents.a2a.redis_task_store.RedisTaskStore.__init__
Initialize the RedisTaskStore with a Redis client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
redis_client
|
Redis
|
An instance of Redis client |
required |
key_prefix
|
str
|
Prefix used for Redis keys (default: "task:") |
'task:'
|
Source code in src/sk_agents/a2a/redis_task_store.py
sk_agents.a2a.redis_task_store.RedisTaskStore.save
async
Saves or updates a task in the Redis store.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task
|
Task
|
The Task object to save |
required |
Source code in src/sk_agents/a2a/redis_task_store.py
sk_agents.a2a.redis_task_store.RedisTaskStore.get
async
Retrieves a task from the Redis store by ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_id
|
str
|
The ID of the task to retrieve |
required |
Returns:
| Type | Description |
|---|---|
Task | None
|
The Task object if found, None otherwise |
Source code in src/sk_agents/a2a/redis_task_store.py
sk_agents.a2a.redis_task_store.RedisTaskStore.delete
async
Deletes a task from the Redis store by ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_id
|
str
|
The ID of the task to delete |
required |
sk_agents.a2a.response_classifier
sk_agents.a2a.response_classifier.A2AResponseClassifier
A class to classify responses from the A2A agent.
Source code in src/sk_agents/a2a/response_classifier.py
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | |
sk_agents.a2a.response_classifier.A2AResponseClassifier.classify_response
async
Classify the response from the A2A agent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
response
|
str
|
The response from the A2A agent. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
A2AResponseClassification
|
The classification of the response. |
Source code in src/sk_agents/a2a/response_classifier.py
sk_agents.appv3
class AppV3
@staticmethod def run(name, version, app_config, config, app): pass
sk_agents.auth
MCP OAuth 2.1 Authentication Components
This module provides OAuth 2.1 compliant authentication for MCP (Model Context Protocol) servers. All components follow the MCP specification (2025-06-18) for authorization: https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization
Key Features: - PKCE (Proof Key for Code Exchange) for authorization code flow - Resource parameter binding for token audience validation - State parameter for CSRF protection - Token refresh with rotation - Server metadata discovery (RFC8414, RFC9728) - Dynamic client registration (RFC7591)
Architecture: - This module is isolated from platform authentication (RequestAuthorizer) - Platform auth: Validates user to platform, returns user_id - Service auth (MCP): Manages OAuth tokens for external services per user
Components: - oauth_client: Main OAuth 2.1 client for authorization flows - oauth_pkce: PKCE generation and validation - oauth_models: Request/response models for OAuth flows - oauth_state_manager: State and PKCE verifier storage for OAuth flows - server_metadata: Authorization server metadata discovery (RFC8414, RFC9728) - client_registration: Dynamic client registration (RFC7591)
sk_agents.auth.client_registration
Dynamic Client Registration
Implements dynamic client registration per RFC7591. Allows automatic OAuth client registration with authorization servers.
References: - RFC 7591: OAuth 2.0 Dynamic Client Registration Protocol
sk_agents.auth.client_registration.ClientRegistrationRequest
Bases: BaseModel
OAuth 2.0 Dynamic Client Registration Request (RFC7591)
Source code in src/sk_agents/auth/client_registration.py
sk_agents.auth.client_registration.ClientRegistrationResponse
Bases: BaseModel
OAuth 2.0 Dynamic Client Registration Response (RFC7591)
Source code in src/sk_agents/auth/client_registration.py
sk_agents.auth.client_registration.DynamicClientRegistration
Dynamic Client Registration Client.
Handles automatic OAuth client registration. Phase 3 implementation (optional).
Source code in src/sk_agents/auth/client_registration.py
sk_agents.auth.client_registration.DynamicClientRegistration.register_client
async
register_client(
registration_endpoint: str,
request: ClientRegistrationRequest,
) -> ClientRegistrationResponse
Register OAuth client with authorization server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
registration_endpoint
|
str
|
Registration endpoint URL from server metadata |
required |
request
|
ClientRegistrationRequest
|
Client registration request |
required |
Returns:
| Name | Type | Description |
|---|---|---|
ClientRegistrationResponse |
ClientRegistrationResponse
|
Registered client credentials |
Raises:
| Type | Description |
|---|---|
HTTPError
|
If registration fails |
Source code in src/sk_agents/auth/client_registration.py
sk_agents.auth.client_registration.DynamicClientRegistration.update_client
async
update_client(
registration_client_uri: str,
registration_access_token: str,
request: ClientRegistrationRequest,
) -> ClientRegistrationResponse
Update registered OAuth client configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
registration_client_uri
|
str
|
Client configuration URI |
required |
registration_access_token
|
str
|
Access token for client management |
required |
request
|
ClientRegistrationRequest
|
Updated client configuration |
required |
Returns:
| Name | Type | Description |
|---|---|---|
ClientRegistrationResponse |
ClientRegistrationResponse
|
Updated client credentials |
Source code in src/sk_agents/auth/client_registration.py
sk_agents.auth.oauth_client
OAuth 2.1 Client Implementation
Main OAuth client for handling authorization code flow with PKCE. Implements MCP specification requirements for OAuth authorization.
Key Features: - Authorization URL generation with PKCE + resource parameter - Authorization code exchange for access token - Token refresh with rotation - Resource-bound token acquisition
References: - MCP Specification 2025-06-18 - OAuth 2.1 Draft - RFC 8707 (Resource Indicators)
sk_agents.auth.oauth_client.OAuthClient
OAuth 2.1 Client for MCP Server Authentication.
Handles complete OAuth authorization code flow with PKCE and resource binding.
Source code in src/sk_agents/auth/oauth_client.py
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 | |
sk_agents.auth.oauth_client.OAuthClient.__init__
Initialize OAuth client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
timeout
|
float
|
HTTP request timeout in seconds |
30.0
|
Source code in src/sk_agents/auth/oauth_client.py
sk_agents.auth.oauth_client.OAuthClient.should_include_resource_param
staticmethod
should_include_resource_param(
protocol_version: str | None = None,
has_prm: bool = False,
) -> bool
Determine if resource parameter should be included in OAuth requests.
Per MCP specification 2025-06-18: - resource parameter MUST be included if protocol version >= 2025-06-18 - resource parameter MUST be included if Protected Resource Metadata discovered - Otherwise, resource parameter SHOULD be omitted for backward compatibility
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
protocol_version
|
str | None
|
MCP protocol version (e.g., "2025-06-18") |
None
|
has_prm
|
bool
|
Whether Protected Resource Metadata has been discovered |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if resource parameter should be included |
Source code in src/sk_agents/auth/oauth_client.py
sk_agents.auth.oauth_client.OAuthClient.validate_token_scopes
staticmethod
validate_token_scopes(
requested_scopes: list[str] | None,
token_response: TokenResponse,
) -> None
Validate that returned scopes don't exceed requested scopes (prevents escalation attacks).
Per OAuth 2.1 Section 3.3: - If scopes were requested, returned scopes MUST be a subset of requested scopes - Servers MUST NOT grant scopes not requested by the client - This prevents scope escalation attacks
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
requested_scopes
|
list[str] | None
|
Scopes requested in authorization request |
required |
token_response
|
TokenResponse
|
Token response from authorization server |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If scope escalation detected (returned > requested) |
Source code in src/sk_agents/auth/oauth_client.py
sk_agents.auth.oauth_client.OAuthClient.build_authorization_url
build_authorization_url(
request: AuthorizationRequest,
) -> str
Build complete OAuth authorization URL.
Constructs URL with all required parameters: - response_type=code - client_id, redirect_uri - resource (canonical MCP server URI) - only if protocol version >= 2025-06-18 - code_challenge, code_challenge_method=S256 - scope, state
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
AuthorizationRequest
|
Authorization request parameters |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
Complete authorization URL for user redirect |
Source code in src/sk_agents/auth/oauth_client.py
sk_agents.auth.oauth_client.OAuthClient.exchange_code_for_tokens
async
exchange_code_for_tokens(
token_request: TokenRequest,
) -> TokenResponse
Exchange authorization code for access token.
Makes POST request to token endpoint with: - grant_type=authorization_code - code, redirect_uri - code_verifier (PKCE) - resource (canonical URI) - only if protocol version >= 2025-06-18 - client_id (+ client_secret if confidential)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token_request
|
TokenRequest
|
Token request parameters |
required |
Returns:
| Name | Type | Description |
|---|---|---|
TokenResponse |
TokenResponse
|
Access token and metadata |
Raises:
| Type | Description |
|---|---|
HTTPError
|
If token request fails |
ValueError
|
If response is invalid |
Source code in src/sk_agents/auth/oauth_client.py
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | |
sk_agents.auth.oauth_client.OAuthClient.refresh_access_token
async
refresh_access_token(
refresh_request: RefreshTokenRequest,
) -> TokenResponse
Refresh expired access token.
Makes POST request to token endpoint with: - grant_type=refresh_token - refresh_token - resource (must match original) - client_id
Implements token rotation per OAuth 2.1.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
refresh_request
|
RefreshTokenRequest
|
Refresh token request parameters |
required |
Returns:
| Name | Type | Description |
|---|---|---|
TokenResponse |
TokenResponse
|
New access token (and possibly new refresh token) |
Raises:
| Type | Description |
|---|---|
HTTPError
|
If refresh fails |
Source code in src/sk_agents/auth/oauth_client.py
sk_agents.auth.oauth_client.OAuthClient.revoke_token
async
revoke_token(
token: str,
revocation_endpoint: str,
client_id: str,
client_secret: str | None = None,
token_type_hint: str = "access_token",
) -> None
Revoke an access or refresh token per RFC 7009.
This allows clients to notify the authorization server that a token is no longer needed, enabling immediate invalidation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
The token to revoke (access or refresh token) |
required |
revocation_endpoint
|
str
|
Token revocation endpoint URL |
required |
client_id
|
str
|
OAuth client ID |
required |
client_secret
|
str | None
|
OAuth client secret (for confidential clients) |
None
|
token_type_hint
|
str
|
Hint about token type ("access_token" or "refresh_token") |
'access_token'
|
Raises:
| Type | Description |
|---|---|
HTTPError
|
If revocation request fails |
Source code in src/sk_agents/auth/oauth_client.py
sk_agents.auth.oauth_client.OAuthClient.initiate_authorization_flow
async
initiate_authorization_flow(
server_config: McpServerConfig, user_id: str
) -> str
Initiate OAuth authorization flow for MCP server.
Generates PKCE pair, state, stores flow state, and returns authorization URL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
server_config
|
McpServerConfig
|
MCP server configuration |
required |
user_id
|
str
|
User ID initiating the flow |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
Authorization URL for user redirect |
Raises:
| Type | Description |
|---|---|
ValueError
|
If server configuration is invalid |
Source code in src/sk_agents/auth/oauth_client.py
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 | |
sk_agents.auth.oauth_client.OAuthClient.handle_callback
async
handle_callback(
code: str,
state: str,
user_id: str,
server_config: McpServerConfig,
) -> OAuth2AuthData
Handle OAuth callback after user authorization.
Validates state, exchanges code for tokens, and stores in AuthStorage.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
code
|
str
|
Authorization code from callback |
required |
state
|
str
|
State parameter from callback |
required |
user_id
|
str
|
User ID to validate against |
required |
server_config
|
McpServerConfig
|
MCP server configuration |
required |
Returns:
| Name | Type | Description |
|---|---|---|
OAuth2AuthData |
OAuth2AuthData
|
Stored token data |
Raises:
| Type | Description |
|---|---|
ValueError
|
If state invalid or user mismatch |
HTTPError
|
If token exchange fails |
Source code in src/sk_agents/auth/oauth_client.py
544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 | |
sk_agents.auth.oauth_error_handler
OAuth Error Handler
Handles OAuth error responses and WWW-Authenticate header parsing per: - RFC 6750: Bearer Token Usage - RFC 9728: Protected Resource Metadata - MCP Specification 2025-06-18
Key functionality: - Parse WWW-Authenticate headers from 401 responses - Extract error codes: invalid_token, insufficient_scope, etc. - Extract scope requirements for re-authorization - Extract resource_metadata URL for RFC 9728 discovery
sk_agents.auth.oauth_error_handler.WWWAuthenticateChallenge
Parsed WWW-Authenticate challenge from 401 response.
Per RFC 6750 Section 3: WWW-Authenticate: Bearer realm="example", error="invalid_token", error_description="The access token expired", scope="read write", resource_metadata="https://api.example.com/.well-known/oauth-protected-resource"
Source code in src/sk_agents/auth/oauth_error_handler.py
sk_agents.auth.oauth_error_handler.WWWAuthenticateChallenge.scopes
property
Get scopes as list.
sk_agents.auth.oauth_error_handler.WWWAuthenticateChallenge.requires_reauth
sk_agents.auth.oauth_error_handler.WWWAuthenticateChallenge.is_token_expired
sk_agents.auth.oauth_error_handler.WWWAuthenticateChallenge.is_insufficient_scope
sk_agents.auth.oauth_error_handler.OAuthErrorHandler
Handler for OAuth error responses.
Provides structured error handling for: - 401 Unauthorized (invalid_token, insufficient_scope) - 403 Forbidden (insufficient permissions) - 400 Bad Request (malformed request)
Source code in src/sk_agents/auth/oauth_error_handler.py
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | |
sk_agents.auth.oauth_error_handler.OAuthErrorHandler.handle_401_response
staticmethod
handle_401_response(
response_headers: dict[str, str],
) -> WWWAuthenticateChallenge | None
Handle 401 Unauthorized response.
Extracts WWW-Authenticate challenge for further processing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
response_headers
|
dict[str, str]
|
HTTP response headers |
required |
Returns:
| Type | Description |
|---|---|
WWWAuthenticateChallenge | None
|
Parsed WWW-Authenticate challenge, or None if header missing |
Source code in src/sk_agents/auth/oauth_error_handler.py
sk_agents.auth.oauth_error_handler.OAuthErrorHandler.should_refresh_token
staticmethod
should_refresh_token(
challenge: WWWAuthenticateChallenge | None,
) -> bool
Determine if token should be refreshed based on error.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
challenge
|
WWWAuthenticateChallenge | None
|
Parsed WWW-Authenticate challenge |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if token refresh should be attempted |
Source code in src/sk_agents/auth/oauth_error_handler.py
sk_agents.auth.oauth_error_handler.OAuthErrorHandler.should_reauthorize
staticmethod
should_reauthorize(
challenge: WWWAuthenticateChallenge | None,
) -> bool
Determine if re-authorization is required.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
challenge
|
WWWAuthenticateChallenge | None
|
Parsed WWW-Authenticate challenge |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if re-authorization flow should be initiated |
Source code in src/sk_agents/auth/oauth_error_handler.py
sk_agents.auth.oauth_error_handler.OAuthErrorHandler.get_required_scopes
staticmethod
get_required_scopes(
challenge: WWWAuthenticateChallenge | None,
) -> list[str]
Extract required scopes from challenge.
For insufficient_scope errors, this returns the scopes needed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
challenge
|
WWWAuthenticateChallenge | None
|
Parsed WWW-Authenticate challenge |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
List of required scopes, empty if none specified |
Source code in src/sk_agents/auth/oauth_error_handler.py
sk_agents.auth.oauth_error_handler.parse_www_authenticate_header
parse_www_authenticate_header(
header_value: str,
) -> WWWAuthenticateChallenge | None
Parse WWW-Authenticate header per RFC 6750 + RFC 9728.
Format
WWW-Authenticate: Bearer realm="example", error="invalid_token", error_description="The access token expired", scope="read write", resource_metadata="https://..."
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
header_value
|
str
|
Value of WWW-Authenticate header |
required |
Returns:
| Name | Type | Description |
|---|---|---|
WWWAuthenticateChallenge |
WWWAuthenticateChallenge | None
|
Parsed challenge, or None if not a Bearer challenge |
Raises:
| Type | Description |
|---|---|
ValueError
|
If header is malformed |
Source code in src/sk_agents/auth/oauth_error_handler.py
sk_agents.auth.oauth_error_handler.extract_field_from_www_authenticate
Extract a specific field from WWW-Authenticate header.
Convenience function for extracting single fields.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
header_value
|
str
|
Value of WWW-Authenticate header |
required |
field_name
|
str
|
Field to extract (e.g., "error", "scope", "resource_metadata") |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Field value, or None if not present |
Source code in src/sk_agents/auth/oauth_error_handler.py
sk_agents.auth.oauth_error_handler.build_www_authenticate_header
build_www_authenticate_header(
error: str,
error_description: str | None = None,
scope: str | None = None,
realm: str | None = None,
resource_metadata: str | None = None,
) -> str
Build WWW-Authenticate header per RFC 6750 + RFC 9728.
For use when implementing MCP servers that need to challenge clients.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
error
|
str
|
OAuth error code (e.g., "invalid_token", "insufficient_scope") |
required |
error_description
|
str | None
|
Human-readable error description |
None
|
scope
|
str | None
|
Required scope(s) (space-separated) |
None
|
realm
|
str | None
|
Protection realm |
None
|
resource_metadata
|
str | None
|
URL for Protected Resource Metadata (RFC 9728) |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
Formatted WWW-Authenticate header value |
Example
build_www_authenticate_header( ... error="insufficient_scope", ... error_description="Token lacks required scopes", ... scope="read write", ... resource_metadata="https://api.example.com/.well-known/oauth-protected-resource" ... ) # doctest: +SKIP 'Bearer error="insufficient_scope", ...'
Source code in src/sk_agents/auth/oauth_error_handler.py
sk_agents.auth.oauth_models
OAuth 2.1 Request and Response Models
Models for OAuth authorization flows following MCP specification.
sk_agents.auth.oauth_models.AuthorizationRequest
Bases: BaseModel
OAuth 2.1 Authorization Request
Used to construct authorization URL with all required parameters. Follows MCP spec requirement for PKCE and resource parameter.
Note: resource parameter is optional and should only be included if: - MCP protocol version >= 2025-06-18, OR - Protected Resource Metadata has been discovered
Source code in src/sk_agents/auth/oauth_models.py
sk_agents.auth.oauth_models.TokenRequest
Bases: BaseModel
OAuth 2.1 Token Request
Used to exchange authorization code for access token. Includes PKCE verifier and resource parameter.
Note: resource parameter is optional and should only be included if: - MCP protocol version >= 2025-06-18, OR - Protected Resource Metadata has been discovered
Source code in src/sk_agents/auth/oauth_models.py
sk_agents.auth.oauth_models.TokenResponse
Bases: BaseModel
OAuth 2.1 Token Response
Token endpoint response with access token and metadata.
Source code in src/sk_agents/auth/oauth_models.py
sk_agents.auth.oauth_models.RefreshTokenRequest
Bases: BaseModel
OAuth 2.1 Refresh Token Request
Request to refresh an expired access token.
Note: resource parameter is optional and should only be included if: - MCP protocol version >= 2025-06-18, OR - Protected Resource Metadata has been discovered - Must match the original authorization request resource if included
Source code in src/sk_agents/auth/oauth_models.py
sk_agents.auth.oauth_models.OAuthError
Bases: BaseModel
OAuth Error Response
Parsed from WWW-Authenticate header or token endpoint error response.
Source code in src/sk_agents/auth/oauth_models.py
sk_agents.auth.oauth_models.MCP401Response
Bases: BaseModel
MCP-compliant 401 Unauthorized response.
Per MCP spec, servers should return WWW-Authenticate header with: - error: Error code - error_description: Human-readable description - scope: Required scopes (for insufficient_scope) - resource_metadata: URL for RFC 9728 discovery (optional)
Source code in src/sk_agents/auth/oauth_models.py
sk_agents.auth.oauth_models.MCP403Response
Bases: BaseModel
MCP-compliant 403 Forbidden response.
Source code in src/sk_agents/auth/oauth_models.py
sk_agents.auth.oauth_pkce
PKCE (Proof Key for Code Exchange) Implementation
Implements PKCE as required by OAuth 2.1 and MCP specification. PKCE prevents authorization code interception attacks.
References: - OAuth 2.1 Section 7.5.2 - RFC 7636: Proof Key for Code Exchange
sk_agents.auth.oauth_pkce.PKCEManager
Manager for PKCE generation and validation.
Provides high-level interface for PKCE operations in OAuth flows.
Source code in src/sk_agents/auth/oauth_pkce.py
sk_agents.auth.oauth_pkce.PKCEManager.generate_pkce_pair
staticmethod
Generate PKCE verifier and challenge pair.
Returns:
| Name | Type | Description |
|---|---|---|
tuple |
tuple[str, str]
|
(verifier, challenge) |
Source code in src/sk_agents/auth/oauth_pkce.py
sk_agents.auth.oauth_pkce.PKCEManager.validate_verifier
staticmethod
Validate code verifier meets requirements.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
verifier
|
str
|
Code verifier to validate |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if valid |
Source code in src/sk_agents/auth/oauth_pkce.py
sk_agents.auth.oauth_pkce.PKCEManager.verify_challenge
staticmethod
Verify that challenge matches verifier.
Used by authorization server (not typically by client).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
verifier
|
str
|
Code verifier |
required |
challenge
|
str
|
Code challenge to verify |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if challenge matches verifier |
Source code in src/sk_agents/auth/oauth_pkce.py
sk_agents.auth.oauth_pkce.generate_code_verifier
Generate cryptographically random code verifier.
Per OAuth 2.1 spec, code verifier must be: - 43-128 characters long - Use characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~"
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
Base64url-encoded random verifier (43-128 chars) |
Source code in src/sk_agents/auth/oauth_pkce.py
sk_agents.auth.oauth_pkce.generate_code_challenge
Generate PKCE code challenge from verifier using S256 method.
Per OAuth 2.1 spec: - challenge = BASE64URL(SHA256(verifier))
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
verifier
|
str
|
Code verifier from generate_code_verifier() |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
Base64url-encoded SHA256 hash of verifier |
Source code in src/sk_agents/auth/oauth_pkce.py
sk_agents.auth.oauth_pkce.validate_code_verifier
Validate code verifier meets OAuth 2.1 requirements.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
verifier
|
str
|
Code verifier to validate |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if valid, False otherwise |
Source code in src/sk_agents/auth/oauth_pkce.py
sk_agents.auth.oauth_state_manager
OAuth State Manager
Manages OAuth flow state for CSRF protection. Stores state parameter + PKCE verifier temporarily during OAuth flow.
Implementation uses AuthStorage with temporary keys and TTL.
sk_agents.auth.oauth_state_manager.OAuthFlowState
Represents temporary OAuth flow state.
Stored during authorization request, retrieved during callback.
Source code in src/sk_agents/auth/oauth_state_manager.py
sk_agents.auth.oauth_state_manager.OAuthFlowState.to_dict
Serialize to dict for storage
Source code in src/sk_agents/auth/oauth_state_manager.py
sk_agents.auth.oauth_state_manager.OAuthFlowState.from_dict
classmethod
from_dict(data: dict[str, Any]) -> OAuthFlowState
Deserialize from storage dict
Source code in src/sk_agents/auth/oauth_state_manager.py
sk_agents.auth.oauth_state_manager.OAuthFlowState.is_expired
Check if flow state has expired (default 5 minutes)
sk_agents.auth.oauth_state_manager.OAuthStateManager
Manager for OAuth flow state and CSRF protection.
Uses AuthStorage with temporary keys to store state during OAuth flow.
Source code in src/sk_agents/auth/oauth_state_manager.py
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | |
sk_agents.auth.oauth_state_manager.OAuthStateManager.__init__
Initialize state manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ttl_seconds
|
int
|
Time-to-live for state (default 5 minutes) |
300
|
Source code in src/sk_agents/auth/oauth_state_manager.py
sk_agents.auth.oauth_state_manager.OAuthStateManager.generate_state
staticmethod
Generate cryptographically random state parameter.
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
Random state string (URL-safe, 32 bytes) |
sk_agents.auth.oauth_state_manager.OAuthStateManager.store_flow_state
store_flow_state(
state: str,
verifier: str,
user_id: str,
server_name: str,
resource: str,
scopes: list[str],
) -> None
Store OAuth flow state temporarily.
Stores in two locations: 1. User-specific key for validation: oauth_flow_temp:{user_id} 2. State-only key for callback retrieval: oauth_flow_temp:by_state
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
str
|
CSRF state parameter |
required |
verifier
|
str
|
PKCE code verifier |
required |
user_id
|
str
|
User ID for this flow |
required |
server_name
|
str
|
MCP server name |
required |
resource
|
str
|
Canonical server URI |
required |
scopes
|
list[str]
|
Requested scopes |
required |
Source code in src/sk_agents/auth/oauth_state_manager.py
sk_agents.auth.oauth_state_manager.OAuthStateManager.retrieve_flow_state
retrieve_flow_state(
state: str, user_id: str
) -> OAuthFlowState
Retrieve and validate OAuth flow state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
str
|
CSRF state parameter from callback |
required |
user_id
|
str
|
User ID to validate against |
required |
Returns:
| Name | Type | Description |
|---|---|---|
OAuthFlowState |
OAuthFlowState
|
Retrieved flow state |
Raises:
| Type | Description |
|---|---|
ValueError
|
If state not found, expired, or user_id mismatch |
Source code in src/sk_agents/auth/oauth_state_manager.py
sk_agents.auth.oauth_state_manager.OAuthStateManager.retrieve_flow_state_by_state_only
retrieve_flow_state_by_state_only(
state: str,
) -> OAuthFlowState
Retrieve OAuth flow state using only the state parameter.
This is used in OAuth callbacks where we don't have user_id upfront. The flow state contains user_id which we extract after retrieval.
Note: This method attempts retrieval by trying common patterns. For production, consider using a state→user_id mapping or encoding user_id in the state parameter itself.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
str
|
CSRF state parameter from callback |
required |
Returns:
| Name | Type | Description |
|---|---|---|
OAuthFlowState |
OAuthFlowState
|
Retrieved flow state with embedded user_id |
Raises:
| Type | Description |
|---|---|
ValueError
|
If state not found or expired |
Source code in src/sk_agents/auth/oauth_state_manager.py
sk_agents.auth.oauth_state_manager.OAuthStateManager.delete_flow_state
Delete OAuth flow state after use or expiry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
str
|
CSRF state parameter |
required |
user_id
|
str
|
User ID |
required |
Source code in src/sk_agents/auth/oauth_state_manager.py
sk_agents.auth.server_metadata
Authorization Server Metadata Discovery
Implements server metadata discovery per RFC8414 and RFC9728. Used for dynamic discovery of OAuth endpoints and capabilities.
References: - RFC 8414: OAuth 2.0 Authorization Server Metadata - RFC 9728: OAuth 2.0 Protected Resource Metadata
sk_agents.auth.server_metadata.AuthServerMetadata
Bases: BaseModel
OAuth 2.0 Authorization Server Metadata (RFC8414)
Discovered from {auth_server}/.well-known/oauth-authorization-server
Source code in src/sk_agents/auth/server_metadata.py
sk_agents.auth.server_metadata.ProtectedResourceMetadata
Bases: BaseModel
OAuth 2.0 Protected Resource Metadata (RFC9728)
Discovered from {mcp_server}/.well-known/oauth-protected-resource
Source code in src/sk_agents/auth/server_metadata.py
sk_agents.auth.server_metadata.ServerMetadataCache
Cache for server metadata to avoid repeated discovery requests.
Implements RFC 8414 and RFC 9728 discovery with TTL-based caching.
Source code in src/sk_agents/auth/server_metadata.py
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | |
sk_agents.auth.server_metadata.ServerMetadataCache.__init__
Initialize metadata cache.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
timeout
|
float
|
HTTP request timeout in seconds (default: 30) |
30.0
|
ttl
|
int
|
Cache TTL in seconds (default: 3600 = 1 hour) |
3600
|
Source code in src/sk_agents/auth/server_metadata.py
sk_agents.auth.server_metadata.ServerMetadataCache.fetch_auth_server_metadata
async
fetch_auth_server_metadata(
auth_server: str,
) -> AuthServerMetadata
Fetch authorization server metadata from well-known endpoint.
Per RFC 8414, discovers OAuth endpoints from: {auth_server}/.well-known/oauth-authorization-server
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
auth_server
|
str
|
Authorization server base URL |
required |
Returns:
| Name | Type | Description |
|---|---|---|
AuthServerMetadata |
AuthServerMetadata
|
Parsed metadata |
Raises:
| Type | Description |
|---|---|
HTTPError
|
If discovery fails |
ValueError
|
If metadata is invalid |
Source code in src/sk_agents/auth/server_metadata.py
sk_agents.auth.server_metadata.ServerMetadataCache.fetch_protected_resource_metadata
async
fetch_protected_resource_metadata(
mcp_server: str,
) -> ProtectedResourceMetadata | None
Fetch protected resource metadata from MCP server.
Per RFC 9728, discovers resource metadata from: {mcp_server}/.well-known/oauth-protected-resource
Note: This metadata is OPTIONAL per RFC 9728. Returns None if not available.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mcp_server
|
str
|
MCP server base URL |
required |
Returns:
| Name | Type | Description |
|---|---|---|
ProtectedResourceMetadata |
ProtectedResourceMetadata | None
|
Parsed metadata, or None if not available |
Raises:
| Type | Description |
|---|---|
ValueError
|
If metadata exists but is invalid |
Source code in src/sk_agents/auth/server_metadata.py
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | |
sk_agents.auth_storage
sk_agents.auth_storage.auth_storage_factory
sk_agents.auth_storage.auth_storage_factory.AuthStorageFactory
Source code in src/sk_agents/auth_storage/auth_storage_factory.py
sk_agents.auth_storage.custom
sk_agents.auth_storage.custom.example_redis_auth_storage
Complete Redis Authentication Storage Implementation
This example demonstrates a full-featured, production-ready Redis-based authentication storage implementation. It serves as a complete alternative to the default in-memory storage.
To use this implementation, set the following environment variables:
TA_AUTH_STORAGE_MANAGER_MODULE=src/sk_agents/auth_storage/custom/example_redis_auth_storage.py TA_AUTH_STORAGE_MANAGER_CLASS=RedisSecureAuthStorageManager
Required Redis configuration environment variables: - TA_REDIS_HOST (default: localhost) - TA_REDIS_PORT (default: 6379) - TA_REDIS_DB (default: 0) - TA_REDIS_TTL (default: 3600 seconds) - TA_REDIS_PWD (optional) - TA_REDIS_SSL (default: false)
sk_agents.auth_storage.custom.example_redis_auth_storage.RedisSecureAuthStorageManager
Bases: SecureAuthStorageManager
Source code in src/sk_agents/auth_storage/custom/example_redis_auth_storage.py
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | |
sk_agents.auth_storage.custom.example_redis_auth_storage.RedisSecureAuthStorageManager.__init__
Initialize the Redis-based auth storage manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app_config
|
AppConfig
|
Application configuration object. If None, creates a new one. |
None
|
Source code in src/sk_agents/auth_storage/custom/example_redis_auth_storage.py
sk_agents.auth_storage.custom.example_redis_auth_storage.RedisSecureAuthStorageManager.store
Store authorization data for a given user and key with TTL.
Source code in src/sk_agents/auth_storage/custom/example_redis_auth_storage.py
sk_agents.auth_storage.custom.example_redis_auth_storage.RedisSecureAuthStorageManager.retrieve
Retrieve authorization data for a given user and key.
Source code in src/sk_agents/auth_storage/custom/example_redis_auth_storage.py
sk_agents.auth_storage.custom.example_redis_auth_storage.RedisSecureAuthStorageManager.delete
Delete authorization data for a given user and key.
Source code in src/sk_agents/auth_storage/custom/example_redis_auth_storage.py
sk_agents.auth_storage.custom.example_redis_auth_storage.RedisSecureAuthStorageManager.clear_user_data
Clear all authorization data for a given user.
Returns:
| Type | Description |
|---|---|
int
|
Number of keys deleted. |
Source code in src/sk_agents/auth_storage/custom/example_redis_auth_storage.py
sk_agents.auth_storage.custom.example_redis_auth_storage.RedisSecureAuthStorageManager.health_check
sk_agents.auth_storage.in_memory_secure_auth_storage_manager
sk_agents.auth_storage.in_memory_secure_auth_storage_manager.InMemorySecureAuthStorageManager
Bases: SecureAuthStorageManager
A thread-safe, in-memory implementation of the SecureAuthStorageManager.
Source code in src/sk_agents/auth_storage/in_memory_secure_auth_storage_manager.py
sk_agents.auth_storage.models
sk_agents.auth_storage.models.OAuth2AuthData
Bases: BaseAuthData
Source code in src/sk_agents/auth_storage/models.py
sk_agents.auth_storage.models.OAuth2AuthData.is_valid_for_resource
Validate token is valid for specific resource.
Checks: 1. Token not expired 2. Resource matches (if resource binding present) 3. Audience matches (if audience present)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
resource_uri
|
str
|
Canonical MCP server URI to validate against |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if token is valid for this resource |
Source code in src/sk_agents/auth_storage/models.py
sk_agents.auth_storage.secure_auth_storage_manager
sk_agents.auth_storage.secure_auth_storage_manager.SecureAuthStorageManager
Bases: ABC
Source code in src/sk_agents/auth_storage/secure_auth_storage_manager.py
sk_agents.auth_storage.secure_auth_storage_manager.SecureAuthStorageManager.store
abstractmethod
sk_agents.auth_storage.secure_auth_storage_manager.SecureAuthStorageManager.retrieve
abstractmethod
sk_agents.auth_storage.secure_auth_storage_manager.SecureAuthStorageManager.delete
abstractmethod
sk_agents.authorization
sk_agents.authorization.request_authorizer
sk_agents.authorization.request_authorizer.RequestAuthorizer
Bases: ABC
Source code in src/sk_agents/authorization/request_authorizer.py
sk_agents.authorization.request_authorizer.RequestAuthorizer.authorize_request
abstractmethod
async
Validates the given authorization header and returns a unique identifier for the authenticated user.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
auth_header
|
str
|
The value of the 'Authorization' HTTP header.
Typically, this is in the format 'Bearer |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
A unique string that identifies the authenticated user. This could be a user ID, username, email, or any other unique identifier suitable for tracking and authorization. |
Examples |
str
|
"user_12345" "alice@example.com" |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the authorization header is missing, malformed, or invalid. |
AuthenticationError(optional)
|
If used in your implementation, it may be raised to signal an authentication failure. |
Source code in src/sk_agents/authorization/request_authorizer.py
sk_agents.exceptions
sk_agents.exceptions.AgentsException
sk_agents.exceptions.InvalidConfigException
Bases: AgentsException
Exception raised when the provided configuration is invalid
Source code in src/sk_agents/exceptions.py
sk_agents.exceptions.InvalidInputException
Bases: AgentsException
Exception raised when the provided input type is invalid
Source code in src/sk_agents/exceptions.py
sk_agents.exceptions.AgentInvokeException
Bases: AgentsException
Exception raised when invoking an Agent failed
Source code in src/sk_agents/exceptions.py
sk_agents.exceptions.PersistenceCreateError
Bases: AgentsException
Exception raised for errors during task creation.
Source code in src/sk_agents/exceptions.py
sk_agents.exceptions.PersistenceLoadError
Bases: AgentsException
Exception raised for errors during task loading.
Source code in src/sk_agents/exceptions.py
sk_agents.exceptions.PersistenceUpdateError
Bases: AgentsException
Exception raised for errors during task update.
Source code in src/sk_agents/exceptions.py
sk_agents.exceptions.PersistenceDeleteError
Bases: AgentsException
Exception raised for errors during task deletion.
Source code in src/sk_agents/exceptions.py
sk_agents.exceptions.AuthenticationException
Bases: AgentsException
Exception raised errors when authenticating users
Source code in src/sk_agents/exceptions.py
sk_agents.exceptions.PluginCatalogDefinitionException
Bases: AgentsException
Exception raised when the parsed json does not match the PluginCatalogDefinition Model
Source code in src/sk_agents/exceptions.py
sk_agents.exceptions.PluginFileReadException
Bases: AgentsException
Raise this exception when the plugin file fails to be read
Source code in src/sk_agents/exceptions.py
sk_agents.hitl
sk_agents.hitl.hitl_manager
sk_agents.hitl.hitl_manager.HitlInterventionRequired
Bases: Exception
Exception raised when a tool call requires human-in-the-loop intervention.
Source code in src/sk_agents/hitl/hitl_manager.py
sk_agents.hitl.hitl_manager.check_for_intervention
Checks the plugin catalog to determine if a tool call requires Human-in-the-Loop intervention.
Source code in src/sk_agents/hitl/hitl_manager.py
sk_agents.mcp_client
MCP Client for Teal Agents Platform - Clean Implementation
This module provides an MCP (Model Context Protocol) client that supports only the transports that are actually available in the MCP Python SDK.
ONLY SUPPORTED TRANSPORTS: - stdio: Local subprocess communication - http: HTTP with Server-Sent Events for remote servers
WebSocket support will be added when it becomes available in the MCP SDK.
sk_agents.mcp_client.AuthRequiredError
Bases: Exception
Exception raised when MCP server authentication is required but missing.
This exception is raised during discovery when a server requires authentication (has auth_server + scopes configured) but the user has no valid token in AuthStorage.
Source code in src/sk_agents/mcp_client.py
sk_agents.mcp_client.McpConnectionManager
Request-scoped connection manager for MCP servers.
Manages MCP connections within a single agent invoke() request scope: - Lazy connection establishment (connect on first tool call per server) - Connection reuse within the request (all tools on same server share connection) - Automatic cleanup at request end - Session ID persistence via state manager for cross-request continuity
Lifecycle
- Created at start of invoke() request
- Connections created lazily when first tool from server is called
- Connections reused for all subsequent tool calls in same request
- Cleanup at end of invoke() - close connections, persist session IDs
Usage
async with McpConnectionManager(servers, user_id, ...) as conn_mgr: session = await conn_mgr.get_or_create_session(server_name) result = await session.call_tool(tool_name, args)
Source code in src/sk_agents/mcp_client.py
1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 | |
sk_agents.mcp_client.McpConnectionManager.__aenter__
async
__aenter__() -> McpConnectionManager
Enter context - initialize and load stored session IDs.
Source code in src/sk_agents/mcp_client.py
sk_agents.mcp_client.McpConnectionManager.__aexit__
async
Exit context - persist session IDs and cleanup connections.
Source code in src/sk_agents/mcp_client.py
sk_agents.mcp_client.McpConnectionManager.get_or_create_session
async
Get existing session or create new one for server (lazy connection).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
server_name
|
str
|
Name of the MCP server |
required |
Returns:
| Type | Description |
|---|---|
ClientSession
|
Active MCP ClientSession for the server |
Source code in src/sk_agents/mcp_client.py
sk_agents.mcp_client.McpConnectionManager.has_active_session
sk_agents.mcp_client.McpConnectionManager.get_active_servers
sk_agents.mcp_client.McpTool
Stateless wrapper for MCP tools to make them compatible with Semantic Kernel.
This class stores the server configuration and tool metadata, but does NOT store active connections. Each invocation creates a temporary connection.
Source code in src/sk_agents/mcp_client.py
1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 | |
sk_agents.mcp_client.McpTool.__init__
__init__(
tool_name: str,
description: str,
input_schema: dict[str, Any],
output_schema: dict[str, Any] | None,
server_config: McpServerConfig,
server_name: str,
)
Initialize stateless MCP tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tool_name
|
str
|
Name of the MCP tool |
required |
description
|
str
|
Tool description |
required |
input_schema
|
dict[str, Any]
|
JSON schema for tool inputs |
required |
output_schema
|
dict[str, Any] | None
|
JSON schema for tool outputs (optional) |
required |
server_config
|
McpServerConfig
|
MCP server configuration (for reconnection) |
required |
server_name
|
str
|
Name of the MCP server |
required |
Source code in src/sk_agents/mcp_client.py
sk_agents.mcp_client.McpTool.invoke
async
invoke(
connection_manager: McpConnectionManager, **kwargs
) -> str
Invoke the MCP tool using a request-scoped connection manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
connection_manager
|
McpConnectionManager
|
Request-scoped connection manager for connection reuse |
required |
**kwargs
|
Tool arguments |
{}
|
Returns:
| Type | Description |
|---|---|
str
|
Tool execution result as string |
Raises:
| Type | Description |
|---|---|
ValueError
|
If connection_manager is not provided |
RuntimeError
|
If tool execution fails |
Source code in src/sk_agents/mcp_client.py
sk_agents.mcp_client.McpPlugin
Bases: BasePlugin
Plugin wrapper that holds MCP tools for Semantic Kernel integration.
This plugin creates kernel functions with proper type annotations from MCP JSON schemas, allowing Semantic Kernel to expose full parameter information to the LLM.
MCP-Specific Design Note:
MCP plugins require both user_id and connection_manager:
-
Per-User Authentication: MCP tools connect to external services that require OAuth2 authentication. Tokens are stored per-user in AuthStorage.
-
Connection Reuse: All tool calls within a request share connections via the connection_manager, reducing overhead from per-tool-call to per-request per-server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tools
|
list[McpTool]
|
List of MCP tools discovered from the server |
required |
server_name
|
str
|
Name of the MCP server (used for logging and namespacing) |
required |
user_id
|
str
|
User ID for OAuth2 token resolution (REQUIRED) |
required |
connection_manager
|
McpConnectionManager
|
Request-scoped connection manager (REQUIRED) |
required |
authorization
|
str | None
|
Optional standard authorization header (rarely used with MCP) |
None
|
extra_data_collector
|
Optional collector for extra response data |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If user_id or connection_manager is not provided |
Example
async with McpConnectionManager(configs, user_id, session_id) as conn_mgr: ... plugin_instance = plugin_class( ... user_id="user123", ... connection_manager=conn_mgr, ... extra_data_collector=collector ... ) ... kernel.add_plugin(plugin_instance, "mcp_github")
Source code in src/sk_agents/mcp_client.py
1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 | |
sk_agents.mcp_client.build_auth_storage_key
Create deterministic key for storing OAuth tokens in AuthStorage.
Source code in src/sk_agents/mcp_client.py
sk_agents.mcp_client.normalize_canonical_uri
Normalize URI to canonical format for MCP resource parameter.
Per MCP specification, canonical URI must be: - Absolute URI with scheme - Lowercase scheme and host - Optional port (only if non-standard) - Optional path
Examples:
"HTTPS://API.Example.COM/mcp" -> "https://api.example.com/mcp" "https://example.com:443/mcp" -> "https://example.com/mcp" "https://example.com:8443/mcp" -> "https://example.com:8443/mcp"
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
uri
|
str
|
URI to normalize |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
Normalized canonical URI |
Raises:
| Type | Description |
|---|---|
ValueError
|
If URI is invalid or not absolute |
Source code in src/sk_agents/mcp_client.py
sk_agents.mcp_client.validate_https_url
Validate that URL uses HTTPS (or localhost for development).
Per MCP spec and OAuth 2.1, all endpoints must use HTTPS except localhost.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
URL to validate |
required |
allow_localhost
|
bool
|
Allow http://localhost or http://127.0.0.1 |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if valid, False otherwise |
Source code in src/sk_agents/mcp_client.py
sk_agents.mcp_client.get_package_version
Get package version for MCP client identification.
sk_agents.mcp_client.validate_mcp_sdk_version
Validate MCP SDK version compatibility.
Logs warnings if the installed MCP SDK version is too old to support all features.
Source code in src/sk_agents/mcp_client.py
sk_agents.mcp_client.initialize_mcp_session
async
initialize_mcp_session(
session: ClientSession,
server_name: str,
server_info_obj: Any = None,
protocol_version: str = "2025-11-25",
) -> Any
Initialize MCP session with proper protocol handshake.
This function handles the complete MCP initialization sequence: 1. Send initialize request with protocol version and capabilities 2. Receive initialization result from server 3. Send initialized notification (required by MCP spec)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
ClientSession
|
The MCP ClientSession to initialize |
required |
server_name
|
str
|
Name of the server for logging purposes |
required |
server_info_obj
|
Any
|
Optional server info object for logging |
None
|
Returns:
| Type | Description |
|---|---|
Any
|
The initialization result from the server |
Raises:
| Type | Description |
|---|---|
ConnectionError
|
If initialization fails |
Source code in src/sk_agents/mcp_client.py
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | |
sk_agents.mcp_client.graceful_shutdown_session
async
Attempt graceful MCP session shutdown.
Per MCP spec, clients should attempt to notify servers before disconnecting. This is a best-effort operation and failures are logged but not raised.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
ClientSession
|
The MCP ClientSession to shutdown |
required |
server_name
|
str
|
Name of the server for logging purposes |
required |
Source code in src/sk_agents/mcp_client.py
sk_agents.mcp_client.map_mcp_annotations_to_governance
map_mcp_annotations_to_governance(
annotations: dict[str, Any], tool_description: str = ""
) -> Governance
Map MCP tool annotations to Teal Agents governance policies using secure-by-default approach.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
annotations
|
dict[str, Any]
|
MCP tool annotations |
required |
tool_description
|
str
|
Tool description for risk analysis |
''
|
Returns:
| Name | Type | Description |
|---|---|---|
Governance |
Governance
|
Governance settings for the tool |
Source code in src/sk_agents/mcp_client.py
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 | |
sk_agents.mcp_client.apply_trust_level_governance
apply_trust_level_governance(
base_governance: Governance,
trust_level: str,
tool_description: str = "",
) -> Governance
Apply server trust level controls to governance settings.
Trust levels provide defense-in-depth by applying additional security controls based on the server's trust relationship with the platform: - untrusted: Maximum restrictions, force HITL for all operations - sandboxed: Enhanced restrictions, HITL required unless explicitly safe - trusted: Base governance applies, but still enforce safety on detected risks
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_governance
|
Governance
|
Base governance settings from MCP annotations |
required |
trust_level
|
str
|
Server trust level ("trusted", "sandboxed", "untrusted") |
required |
tool_description
|
str
|
Tool description for additional risk analysis |
''
|
Returns:
| Name | Type | Description |
|---|---|---|
Governance |
Governance
|
Governance with trust level controls applied |
Source code in src/sk_agents/mcp_client.py
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 | |
sk_agents.mcp_client.apply_governance_overrides
apply_governance_overrides(
base_governance: Governance,
tool_name: str,
overrides: dict[str, GovernanceOverride] | None,
) -> Governance
Apply tool-specific governance overrides to base governance settings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_governance
|
Governance
|
Auto-inferred governance from MCP annotations |
required |
tool_name
|
str
|
Name of the MCP tool |
required |
overrides
|
dict[str, GovernanceOverride] | None
|
Optional governance overrides from server config |
required |
Returns:
| Name | Type | Description |
|---|---|---|
Governance |
Governance
|
Final governance with overrides applied |
Source code in src/sk_agents/mcp_client.py
sk_agents.mcp_client.resolve_server_auth_headers
async
resolve_server_auth_headers(
server_config: McpServerConfig,
user_id: str = "default",
app_config: AppConfig | None = None,
) -> dict[str, str]
Resolve authentication headers for MCP server connection.
Now supports automatic token refresh with OAuth 2.1 compliance: - Validates token audience matches resource - Automatically refreshes expired tokens - Implements token rotation per OAuth 2.1
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
server_config
|
McpServerConfig
|
MCP server configuration |
required |
user_id
|
str
|
User ID for auth lookup |
'default'
|
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
Dict[str, str]: Headers to use for server connection |
Raises:
| Type | Description |
|---|---|
AuthRequiredError
|
If no valid token and refresh fails |
Source code in src/sk_agents/mcp_client.py
534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 | |
sk_agents.mcp_client.revoke_mcp_server_tokens
async
revoke_mcp_server_tokens(
server_config: McpServerConfig, user_id: str = "default"
) -> None
Revoke all tokens for an MCP server.
Useful when: - User logs out - Security incident detected - Server access no longer needed
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
server_config
|
McpServerConfig
|
MCP server configuration |
required |
user_id
|
str
|
User ID for token lookup |
'default'
|
Raises:
| Type | Description |
|---|---|
Exception
|
If revocation fails |
Source code in src/sk_agents/mcp_client.py
851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 | |
sk_agents.mcp_client.create_mcp_session_with_retry
async
create_mcp_session_with_retry(
server_config: McpServerConfig,
connection_stack: AsyncExitStack,
user_id: str = "default",
max_retries: int = 3,
mcp_session_id: str | None = None,
on_stale_session: Callable[[str], Awaitable[None]]
| None = None,
app_config: AppConfig | None = None,
) -> tuple[ClientSession, Callable[[], str | None]]
Create MCP session with retry logic for transient failures.
This function wraps create_mcp_session with exponential backoff retry logic to handle transient network issues and temporary server unavailability.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
server_config
|
McpServerConfig
|
MCP server configuration |
required |
connection_stack
|
AsyncExitStack
|
AsyncExitStack for resource management |
required |
user_id
|
str
|
User ID for authentication |
'default'
|
max_retries
|
int
|
Maximum number of retry attempts (default: 3) |
3
|
Returns:
| Name | Type | Description |
|---|---|---|
ClientSession |
tuple[ClientSession, Callable[[], str | None]]
|
Initialized MCP session |
Raises:
| Type | Description |
|---|---|
ConnectionError
|
If all retry attempts fail |
ValueError
|
If server configuration is invalid |
Source code in src/sk_agents/mcp_client.py
932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 | |
sk_agents.mcp_client.create_mcp_session
async
create_mcp_session(
server_config: McpServerConfig,
connection_stack: AsyncExitStack,
user_id: str = "default",
mcp_session_id: str | None = None,
app_config: AppConfig | None = None,
) -> tuple[ClientSession, Callable[[], str | None]]
Create MCP session using SDK transport factories.
Source code in src/sk_agents/mcp_client.py
1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 | |
sk_agents.mcp_client.get_transport_info
get_transport_info(server_config: McpServerConfig) -> str
Get transport info for logging.
Source code in src/sk_agents/mcp_client.py
sk_agents.mcp_discovery
MCP State Management Module.
sk_agents.mcp_discovery.DiscoveryManagerFactory
Factory for MCP state manager with dependency injection.
Uses singleton pattern to ensure only one factory instance exists. Dynamically loads state manager implementation based on environment variables.
Configuration
TA_MCP_DISCOVERY_MODULE: Python module containing manager class TA_MCP_DISCOVERY_CLASS: Manager class name
Defaults to InMemoryStateManager for development.
Source code in src/sk_agents/mcp_discovery/discovery_manager_factory.py
sk_agents.mcp_discovery.DiscoveryManagerFactory.__init__
Initialize factory with app configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app_config
|
AppConfig
|
Application configuration for env vars |
required |
Source code in src/sk_agents/mcp_discovery/discovery_manager_factory.py
sk_agents.mcp_discovery.DiscoveryManagerFactory.get_discovery_manager
get_discovery_manager() -> McpStateManager
Get state manager instance (cached singleton).
Loads manager implementation on first call based on configuration, then caches for subsequent calls.
Returns:
| Type | Description |
|---|---|
McpStateManager
|
McpStateManager instance |
Raises:
| Type | Description |
|---|---|
Exception
|
If manager class cannot be loaded (falls back to in-memory) |
Source code in src/sk_agents/mcp_discovery/discovery_manager_factory.py
sk_agents.mcp_discovery.InMemoryStateManager
Bases: McpStateManager
In-memory implementation of MCP state manager.
Stores MCP state in memory with thread-safe access. Suitable for: - Development and testing - Single-instance deployments - Scenarios where persistence is not required
Note: State is lost on server restart.
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 | |
sk_agents.mcp_discovery.InMemoryStateManager.__init__
Initialize in-memory state manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app_config
|
Application configuration (for consistency with other managers) |
required |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.InMemoryStateManager.create_discovery
async
create_discovery(state: McpState) -> None
Create initial MCP state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
McpState
|
MCP state to create |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryCreateError
|
If state already exists |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.InMemoryStateManager.load_discovery
async
load_discovery(
user_id: str, session_id: str
) -> McpState | None
Load MCP state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Returns:
| Type | Description |
|---|---|
McpState | None
|
Deep copy of MCP state if exists, None otherwise. |
McpState | None
|
Returns a copy to prevent external mutations. |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.InMemoryStateManager.update_discovery
async
update_discovery(state: McpState) -> None
Update existing MCP state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
McpState
|
Updated MCP state |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryUpdateError
|
If state does not exist |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.InMemoryStateManager.delete_discovery
async
Delete MCP state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.InMemoryStateManager.mark_completed
async
Mark discovery as completed.
If state doesn't exist, auto-creates it with discovery_completed=True and empty discovered_servers dict. A warning is logged when auto-creating.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.InMemoryStateManager.is_completed
async
Check if discovery is completed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if discovery completed, False otherwise |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.InMemoryStateManager.store_mcp_session
async
Store MCP session ID for a server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
mcp_session_id
|
str
|
MCP session ID from server |
required |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.InMemoryStateManager.get_mcp_session
async
Get MCP session ID for a server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
MCP session ID if exists, None otherwise |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.InMemoryStateManager.update_session_last_used
async
Update last_used timestamp for an MCP session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryUpdateError
|
If state or server doesn't exist |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.InMemoryStateManager.clear_mcp_session
async
clear_mcp_session(
user_id: str,
session_id: str,
server_name: str,
expected_session_id: str | None = None,
) -> None
Remove stored MCP session info for a server if present.
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.McpState
MCP state for a specific user session.
Stores the results of MCP server discovery and session management including: - Which servers have been discovered - Serialized plugin data for each server - MCP session IDs for stateful servers - Completion status
Scoped to (user_id, session_id) for session-level isolation.
Structure of discovered_servers: { "server_name": { "tools": [...], # Plugin metadata "mcp_session_id": "session-abc123", # Optional, for stateful servers "last_used_at": "2025-01-15T10:30:00Z", # Optional, session activity timestamp "created_at": "2025-01-15T10:00:00Z" # Optional, session creation timestamp } }
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.McpState.__init__
__init__(
user_id: str,
session_id: str,
discovered_servers: dict[str, dict],
discovery_completed: bool,
created_at: datetime | None = None,
failed_servers: dict[str, str] | None = None,
)
Initialize MCP state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID for authentication and scoping |
required |
session_id
|
str
|
Session ID for conversation grouping |
required |
discovered_servers
|
dict[str, dict]
|
Mapping of server_name to plugin data and session info |
required |
discovery_completed
|
bool
|
Whether discovery has finished successfully |
required |
created_at
|
datetime | None
|
Timestamp of state creation (defaults to now) |
None
|
failed_servers
|
dict[str, str] | None
|
Dictionary of failed servers and their error messages |
None
|
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.McpStateManager
Bases: ABC
Abstract interface for MCP state management (discovery + sessions).
Implementations must provide storage for MCP state scoped to (user_id, session_id) combinations. This enables: - Session-level tool isolation - Shared discovery across tasks in the same session - MCP session persistence for stateful servers - External state storage (Redis, in-memory, etc.)
Pattern matches: - TaskPersistenceManager (for task state) - SecureAuthStorageManager (for OAuth tokens)
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | |
sk_agents.mcp_discovery.McpStateManager.create_discovery
abstractmethod
async
create_discovery(state: McpState) -> None
Create initial state for (user_id, session_id).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
McpState
|
MCP state to create |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryCreateError
|
If state already exists for this (user_id, session_id) |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.McpStateManager.load_discovery
abstractmethod
async
load_discovery(
user_id: str, session_id: str
) -> McpState | None
Load MCP state for (user_id, session_id).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Returns:
| Type | Description |
|---|---|
McpState | None
|
MCP state if exists, None otherwise |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.McpStateManager.update_discovery
abstractmethod
async
update_discovery(state: McpState) -> None
Update existing MCP state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
McpState
|
Updated MCP state |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryUpdateError
|
If state does not exist |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.McpStateManager.delete_discovery
abstractmethod
async
Delete MCP state for (user_id, session_id).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
sk_agents.mcp_discovery.McpStateManager.mark_completed
abstractmethod
async
Mark discovery as completed for (user_id, session_id).
If the state does not exist, it will be created automatically with an empty discovered_servers dict and discovery_completed=True. A warning will be logged when auto-creating.
This operation is idempotent - calling it multiple times has the same effect as calling it once.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.McpStateManager.is_completed
abstractmethod
async
Check if discovery is completed for (user_id, session_id).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if discovery completed, False otherwise |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.McpStateManager.store_mcp_session
abstractmethod
async
Store MCP session ID for a server.
If state doesn't exist, it will be created. If server doesn't exist in discovered_servers, it will be added.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
mcp_session_id
|
str
|
MCP session ID from server |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryUpdateError
|
If state update fails |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.McpStateManager.get_mcp_session
abstractmethod
async
Get MCP session ID for a server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
MCP session ID if exists, None otherwise |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.McpStateManager.update_session_last_used
abstractmethod
async
Update last_used timestamp for an MCP session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryUpdateError
|
If state or server doesn't exist |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.McpStateManager.clear_mcp_session
abstractmethod
async
clear_mcp_session(
user_id: str,
session_id: str,
server_name: str,
expected_session_id: str | None = None,
) -> None
Clear the stored MCP session for a given server (if present).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
expected_session_id
|
str | None
|
Optional session id to match before clearing |
None
|
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.RedisStateManager
Bases: McpStateManager
Redis-backed implementation of MCP state manager.
Stores MCP state in Redis for: - Production deployments - Multi-instance horizontal scaling - Persistence across server restarts - Shared state across distributed systems
Uses the same Redis configuration as other components (TA_REDIS_*).
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 | |
sk_agents.mcp_discovery.RedisStateManager.__init__
Initialize Redis state manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app_config
|
AppConfig
|
Application configuration for Redis connection |
required |
redis_client
|
Redis | None
|
Optional pre-configured Redis client (for testing) |
None
|
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.RedisStateManager.close
async
Close Redis connection and cleanup resources.
sk_agents.mcp_discovery.RedisStateManager.__aenter__
async
sk_agents.mcp_discovery.RedisStateManager.__aexit__
async
sk_agents.mcp_discovery.RedisStateManager.create_discovery
async
create_discovery(state: McpState) -> None
Create initial MCP state in Redis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
McpState
|
MCP state to create |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryCreateError
|
If state already exists |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.RedisStateManager.load_discovery
async
load_discovery(
user_id: str, session_id: str
) -> McpState | None
Load MCP state from Redis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Returns:
| Type | Description |
|---|---|
McpState | None
|
MCP state if exists, None otherwise |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.RedisStateManager.update_discovery
async
update_discovery(state: McpState) -> None
Update existing MCP state in Redis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
McpState
|
Updated MCP state |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryUpdateError
|
If state does not exist |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.RedisStateManager.delete_discovery
async
Delete discovery state from Redis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.RedisStateManager.mark_completed
async
Mark discovery as completed in Redis using atomic operation.
If state doesn't exist, auto-creates it with discovery_completed=True and empty discovered_servers dict. A warning is logged when auto-creating.
Uses Lua script for atomic read-modify-write to prevent race conditions in multi-worker deployments.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.RedisStateManager.is_completed
async
Check if discovery is completed in Redis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if discovery completed, False otherwise |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.RedisStateManager.store_mcp_session
async
Store MCP session ID for a server using atomic Lua script.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
mcp_session_id
|
str
|
MCP session ID from server |
required |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | |
sk_agents.mcp_discovery.RedisStateManager.get_mcp_session
async
Get MCP session ID for a server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
MCP session ID if exists, None otherwise |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.RedisStateManager.update_session_last_used
async
Update last_used timestamp using atomic Lua script.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryUpdateError
|
If state or server doesn't exist |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.RedisStateManager.clear_mcp_session
async
clear_mcp_session(
user_id: str,
session_id: str,
server_name: str,
expected_session_id: str | None = None,
) -> None
Remove stored MCP session info for a server if present.
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.discovery_manager_factory
MCP State Manager Factory
Provides singleton factory for creating MCP state manager instances with dynamic module loading and dependency injection.
Follows the same pattern as PersistenceFactory and AuthStorageFactory.
sk_agents.mcp_discovery.discovery_manager_factory.DiscoveryManagerFactory
Factory for MCP state manager with dependency injection.
Uses singleton pattern to ensure only one factory instance exists. Dynamically loads state manager implementation based on environment variables.
Configuration
TA_MCP_DISCOVERY_MODULE: Python module containing manager class TA_MCP_DISCOVERY_CLASS: Manager class name
Defaults to InMemoryStateManager for development.
Source code in src/sk_agents/mcp_discovery/discovery_manager_factory.py
sk_agents.mcp_discovery.discovery_manager_factory.DiscoveryManagerFactory.__init__
Initialize factory with app configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app_config
|
AppConfig
|
Application configuration for env vars |
required |
Source code in src/sk_agents/mcp_discovery/discovery_manager_factory.py
sk_agents.mcp_discovery.discovery_manager_factory.DiscoveryManagerFactory.get_discovery_manager
get_discovery_manager() -> McpStateManager
Get state manager instance (cached singleton).
Loads manager implementation on first call based on configuration, then caches for subsequent calls.
Returns:
| Type | Description |
|---|---|
McpStateManager
|
McpStateManager instance |
Raises:
| Type | Description |
|---|---|
Exception
|
If manager class cannot be loaded (falls back to in-memory) |
Source code in src/sk_agents/mcp_discovery/discovery_manager_factory.py
sk_agents.mcp_discovery.in_memory_discovery_manager
In-Memory MCP State Manager
Provides in-memory implementation for development and testing. Follows the same pattern as InMemoryPersistenceManager.
sk_agents.mcp_discovery.in_memory_discovery_manager.InMemoryStateManager
Bases: McpStateManager
In-memory implementation of MCP state manager.
Stores MCP state in memory with thread-safe access. Suitable for: - Development and testing - Single-instance deployments - Scenarios where persistence is not required
Note: State is lost on server restart.
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 | |
sk_agents.mcp_discovery.in_memory_discovery_manager.InMemoryStateManager.__init__
Initialize in-memory state manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app_config
|
Application configuration (for consistency with other managers) |
required |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.in_memory_discovery_manager.InMemoryStateManager.create_discovery
async
create_discovery(state: McpState) -> None
Create initial MCP state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
McpState
|
MCP state to create |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryCreateError
|
If state already exists |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.in_memory_discovery_manager.InMemoryStateManager.load_discovery
async
load_discovery(
user_id: str, session_id: str
) -> McpState | None
Load MCP state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Returns:
| Type | Description |
|---|---|
McpState | None
|
Deep copy of MCP state if exists, None otherwise. |
McpState | None
|
Returns a copy to prevent external mutations. |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.in_memory_discovery_manager.InMemoryStateManager.update_discovery
async
update_discovery(state: McpState) -> None
Update existing MCP state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
McpState
|
Updated MCP state |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryUpdateError
|
If state does not exist |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.in_memory_discovery_manager.InMemoryStateManager.delete_discovery
async
Delete MCP state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.in_memory_discovery_manager.InMemoryStateManager.mark_completed
async
Mark discovery as completed.
If state doesn't exist, auto-creates it with discovery_completed=True and empty discovered_servers dict. A warning is logged when auto-creating.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.in_memory_discovery_manager.InMemoryStateManager.is_completed
async
Check if discovery is completed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if discovery completed, False otherwise |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.in_memory_discovery_manager.InMemoryStateManager.store_mcp_session
async
Store MCP session ID for a server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
mcp_session_id
|
str
|
MCP session ID from server |
required |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.in_memory_discovery_manager.InMemoryStateManager.get_mcp_session
async
Get MCP session ID for a server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
MCP session ID if exists, None otherwise |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.in_memory_discovery_manager.InMemoryStateManager.update_session_last_used
async
Update last_used timestamp for an MCP session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryUpdateError
|
If state or server doesn't exist |
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.in_memory_discovery_manager.InMemoryStateManager.clear_mcp_session
async
clear_mcp_session(
user_id: str,
session_id: str,
server_name: str,
expected_session_id: str | None = None,
) -> None
Remove stored MCP session info for a server if present.
Source code in src/sk_agents/mcp_discovery/in_memory_discovery_manager.py
sk_agents.mcp_discovery.mcp_discovery_manager
MCP State Manager - Abstract Interface
Provides abstract base class for managing MCP tool discovery and session state. Follows the same pattern as TaskPersistenceManager and SecureAuthStorageManager.
sk_agents.mcp_discovery.mcp_discovery_manager.DiscoveryError
sk_agents.mcp_discovery.mcp_discovery_manager.DiscoveryCreateError
Bases: DiscoveryError
Raised when state creation fails.
sk_agents.mcp_discovery.mcp_discovery_manager.DiscoveryUpdateError
Bases: DiscoveryError
Raised when state update fails.
sk_agents.mcp_discovery.mcp_discovery_manager.McpState
MCP state for a specific user session.
Stores the results of MCP server discovery and session management including: - Which servers have been discovered - Serialized plugin data for each server - MCP session IDs for stateful servers - Completion status
Scoped to (user_id, session_id) for session-level isolation.
Structure of discovered_servers: { "server_name": { "tools": [...], # Plugin metadata "mcp_session_id": "session-abc123", # Optional, for stateful servers "last_used_at": "2025-01-15T10:30:00Z", # Optional, session activity timestamp "created_at": "2025-01-15T10:00:00Z" # Optional, session creation timestamp } }
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.mcp_discovery_manager.McpState.__init__
__init__(
user_id: str,
session_id: str,
discovered_servers: dict[str, dict],
discovery_completed: bool,
created_at: datetime | None = None,
failed_servers: dict[str, str] | None = None,
)
Initialize MCP state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID for authentication and scoping |
required |
session_id
|
str
|
Session ID for conversation grouping |
required |
discovered_servers
|
dict[str, dict]
|
Mapping of server_name to plugin data and session info |
required |
discovery_completed
|
bool
|
Whether discovery has finished successfully |
required |
created_at
|
datetime | None
|
Timestamp of state creation (defaults to now) |
None
|
failed_servers
|
dict[str, str] | None
|
Dictionary of failed servers and their error messages |
None
|
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.mcp_discovery_manager.McpStateManager
Bases: ABC
Abstract interface for MCP state management (discovery + sessions).
Implementations must provide storage for MCP state scoped to (user_id, session_id) combinations. This enables: - Session-level tool isolation - Shared discovery across tasks in the same session - MCP session persistence for stateful servers - External state storage (Redis, in-memory, etc.)
Pattern matches: - TaskPersistenceManager (for task state) - SecureAuthStorageManager (for OAuth tokens)
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | |
sk_agents.mcp_discovery.mcp_discovery_manager.McpStateManager.create_discovery
abstractmethod
async
create_discovery(state: McpState) -> None
Create initial state for (user_id, session_id).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
McpState
|
MCP state to create |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryCreateError
|
If state already exists for this (user_id, session_id) |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.mcp_discovery_manager.McpStateManager.load_discovery
abstractmethod
async
load_discovery(
user_id: str, session_id: str
) -> McpState | None
Load MCP state for (user_id, session_id).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Returns:
| Type | Description |
|---|---|
McpState | None
|
MCP state if exists, None otherwise |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.mcp_discovery_manager.McpStateManager.update_discovery
abstractmethod
async
update_discovery(state: McpState) -> None
Update existing MCP state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
McpState
|
Updated MCP state |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryUpdateError
|
If state does not exist |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.mcp_discovery_manager.McpStateManager.delete_discovery
abstractmethod
async
Delete MCP state for (user_id, session_id).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
sk_agents.mcp_discovery.mcp_discovery_manager.McpStateManager.mark_completed
abstractmethod
async
Mark discovery as completed for (user_id, session_id).
If the state does not exist, it will be created automatically with an empty discovered_servers dict and discovery_completed=True. A warning will be logged when auto-creating.
This operation is idempotent - calling it multiple times has the same effect as calling it once.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.mcp_discovery_manager.McpStateManager.is_completed
abstractmethod
async
Check if discovery is completed for (user_id, session_id).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if discovery completed, False otherwise |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.mcp_discovery_manager.McpStateManager.store_mcp_session
abstractmethod
async
Store MCP session ID for a server.
If state doesn't exist, it will be created. If server doesn't exist in discovered_servers, it will be added.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
mcp_session_id
|
str
|
MCP session ID from server |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryUpdateError
|
If state update fails |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.mcp_discovery_manager.McpStateManager.get_mcp_session
abstractmethod
async
Get MCP session ID for a server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
MCP session ID if exists, None otherwise |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.mcp_discovery_manager.McpStateManager.update_session_last_used
abstractmethod
async
Update last_used timestamp for an MCP session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryUpdateError
|
If state or server doesn't exist |
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.mcp_discovery_manager.McpStateManager.clear_mcp_session
abstractmethod
async
clear_mcp_session(
user_id: str,
session_id: str,
server_name: str,
expected_session_id: str | None = None,
) -> None
Clear the stored MCP session for a given server (if present).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
expected_session_id
|
str | None
|
Optional session id to match before clearing |
None
|
Source code in src/sk_agents/mcp_discovery/mcp_discovery_manager.py
sk_agents.mcp_discovery.redis_discovery_manager
Redis MCP State Manager
Provides Redis-backed implementation for production deployments. Follows the same pattern as Redis persistence and auth storage.
sk_agents.mcp_discovery.redis_discovery_manager.RedisStateManager
Bases: McpStateManager
Redis-backed implementation of MCP state manager.
Stores MCP state in Redis for: - Production deployments - Multi-instance horizontal scaling - Persistence across server restarts - Shared state across distributed systems
Uses the same Redis configuration as other components (TA_REDIS_*).
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 | |
sk_agents.mcp_discovery.redis_discovery_manager.RedisStateManager.__init__
Initialize Redis state manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app_config
|
AppConfig
|
Application configuration for Redis connection |
required |
redis_client
|
Redis | None
|
Optional pre-configured Redis client (for testing) |
None
|
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.redis_discovery_manager.RedisStateManager.close
async
Close Redis connection and cleanup resources.
sk_agents.mcp_discovery.redis_discovery_manager.RedisStateManager.__aenter__
async
sk_agents.mcp_discovery.redis_discovery_manager.RedisStateManager.__aexit__
async
sk_agents.mcp_discovery.redis_discovery_manager.RedisStateManager.create_discovery
async
create_discovery(state: McpState) -> None
Create initial MCP state in Redis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
McpState
|
MCP state to create |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryCreateError
|
If state already exists |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.redis_discovery_manager.RedisStateManager.load_discovery
async
load_discovery(
user_id: str, session_id: str
) -> McpState | None
Load MCP state from Redis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Returns:
| Type | Description |
|---|---|
McpState | None
|
MCP state if exists, None otherwise |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.redis_discovery_manager.RedisStateManager.update_discovery
async
update_discovery(state: McpState) -> None
Update existing MCP state in Redis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
McpState
|
Updated MCP state |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryUpdateError
|
If state does not exist |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.redis_discovery_manager.RedisStateManager.delete_discovery
async
Delete discovery state from Redis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.redis_discovery_manager.RedisStateManager.mark_completed
async
Mark discovery as completed in Redis using atomic operation.
If state doesn't exist, auto-creates it with discovery_completed=True and empty discovered_servers dict. A warning is logged when auto-creating.
Uses Lua script for atomic read-modify-write to prevent race conditions in multi-worker deployments.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.redis_discovery_manager.RedisStateManager.is_completed
async
Check if discovery is completed in Redis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if discovery completed, False otherwise |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.redis_discovery_manager.RedisStateManager.store_mcp_session
async
Store MCP session ID for a server using atomic Lua script.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
mcp_session_id
|
str
|
MCP session ID from server |
required |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | |
sk_agents.mcp_discovery.redis_discovery_manager.RedisStateManager.get_mcp_session
async
Get MCP session ID for a server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
MCP session ID if exists, None otherwise |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.redis_discovery_manager.RedisStateManager.update_session_last_used
async
Update last_used timestamp using atomic Lua script.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Teal agent session ID |
required |
server_name
|
str
|
Name of the MCP server |
required |
Raises:
| Type | Description |
|---|---|
DiscoveryUpdateError
|
If state or server doesn't exist |
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_discovery.redis_discovery_manager.RedisStateManager.clear_mcp_session
async
clear_mcp_session(
user_id: str,
session_id: str,
server_name: str,
expected_session_id: str | None = None,
) -> None
Remove stored MCP session info for a server if present.
Source code in src/sk_agents/mcp_discovery/redis_discovery_manager.py
sk_agents.mcp_plugin_registry
MCP Plugin Registry - Discovers and stores MCP tools at session start.
This registry discovers MCP tools and stores them in external state. At request time, tools are loaded from state and used to instantiate McpPlugin directly in kernel_builder.
sk_agents.mcp_plugin_registry.McpPluginRegistry
Registry for MCP tools with per-session isolation.
At session start, this registry: 1. Connects to MCP servers temporarily 2. Discovers available tools 3. Registers tools in catalog for governance/HITL 4. Serializes tool data to external storage (via McpStateManager)
At request time: - Tools are loaded from storage via get_tools_for_session() - kernel_builder instantiates McpPlugin directly with these tools
This ensures proper multi-tenant isolation and horizontal scalability. Tool state is stored externally (Redis/InMemory) instead of class variables.
Source code in src/sk_agents/mcp_plugin_registry.py
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 | |
sk_agents.mcp_plugin_registry.McpPluginRegistry.discover_and_materialize
async
classmethod
discover_and_materialize(
mcp_servers: list[McpServerConfig],
user_id: str,
session_id: str,
discovery_manager,
app_config,
) -> None
Discover MCP tools and store in external state.
This is called once per session when first invoked. Creates temporary connections to discover tools, then closes them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mcp_servers
|
list[McpServerConfig]
|
List of MCP server configurations |
required |
user_id
|
str
|
User ID for authentication |
required |
session_id
|
str
|
Session ID for scoping |
required |
discovery_manager
|
Manager for storing discovery state |
required |
Raises:
| Type | Description |
|---|---|
AuthRequiredError
|
If any server requires authentication that is missing |
Source code in src/sk_agents/mcp_plugin_registry.py
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | |
sk_agents.mcp_plugin_registry.McpPluginRegistry.get_tools_for_session
async
classmethod
get_tools_for_session(
user_id: str, session_id: str, discovery_manager
) -> dict[str, list[McpTool]]
Load MCP tools from external storage for this session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_id
|
str
|
User ID |
required |
session_id
|
str
|
Session ID |
required |
discovery_manager
|
Manager for loading discovery state |
required |
Returns:
| Type | Description |
|---|---|
dict[str, list[McpTool]]
|
Dictionary mapping server_name to list of McpTool objects |
Source code in src/sk_agents/mcp_plugin_registry.py
sk_agents.persistence
sk_agents.persistence.custom
sk_agents.persistence.custom.example_redis_persistence
Complete Redis Task Persistence Implementation
This example demonstrates a full-featured, production-ready Redis-based task persistence implementation. It serves as a complete alternative to the default in-memory storage.
To use this implementation, set the following environment variables:
TA_PERSISTENCE_MODULE=src/sk_agents/persistence/custom/example_redis_persistence.py TA_PERSISTENCE_CLASS=RedisTaskPersistenceManager
Required Redis configuration environment variables: - TA_REDIS_HOST (default: localhost) - TA_REDIS_PORT (default: 6379) - TA_REDIS_DB (default: 0) - TA_REDIS_TTL (default: 3600 seconds) - TA_REDIS_PWD (optional) - TA_REDIS_SSL (default: false)
sk_agents.persistence.custom.example_redis_persistence.RedisTaskPersistenceManager
Bases: TaskPersistenceManager
Source code in src/sk_agents/persistence/custom/example_redis_persistence.py
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | |
sk_agents.persistence.custom.example_redis_persistence.RedisTaskPersistenceManager.__init__
Initialize the Redis-based task persistence manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app_config
|
AppConfig
|
Application configuration object. If None, creates a new one. |
None
|
Source code in src/sk_agents/persistence/custom/example_redis_persistence.py
sk_agents.persistence.custom.example_redis_persistence.RedisTaskPersistenceManager.create
async
Create a new task in Redis.
Source code in src/sk_agents/persistence/custom/example_redis_persistence.py
sk_agents.persistence.custom.example_redis_persistence.RedisTaskPersistenceManager.load
async
Load a task from Redis by task_id.
Source code in src/sk_agents/persistence/custom/example_redis_persistence.py
sk_agents.persistence.custom.example_redis_persistence.RedisTaskPersistenceManager.update
async
Update an existing task in Redis.
Source code in src/sk_agents/persistence/custom/example_redis_persistence.py
sk_agents.persistence.custom.example_redis_persistence.RedisTaskPersistenceManager.delete
async
Delete a task from Redis.
Source code in src/sk_agents/persistence/custom/example_redis_persistence.py
sk_agents.persistence.custom.example_redis_persistence.RedisTaskPersistenceManager.load_by_request_id
async
Load a task by request_id.
Source code in src/sk_agents/persistence/custom/example_redis_persistence.py
sk_agents.persistence.custom.example_redis_persistence.RedisTaskPersistenceManager.health_check
sk_agents.persistence.custom.example_redis_persistence.RedisTaskPersistenceManager.clear_all_tasks
Clear all task data (useful for testing).
Returns:
| Type | Description |
|---|---|
int
|
Number of keys deleted. |
Source code in src/sk_agents/persistence/custom/example_redis_persistence.py
sk_agents.persistence.persistence_factory
sk_agents.persistence.persistence_factory.PersistenceFactory
Source code in src/sk_agents/persistence/persistence_factory.py
sk_agents.plugin_catalog
sk_agents.plugin_catalog.local_plugin_catalog
sk_agents.plugin_catalog.local_plugin_catalog.FileBasedPluginCatalog
Bases: PluginCatalog
File-based implementation that loads plugins from JSON files.
Source code in src/sk_agents/plugin_catalog/local_plugin_catalog.py
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | |
sk_agents.plugin_catalog.local_plugin_catalog.FileBasedPluginCatalog.get_plugin
sk_agents.plugin_catalog.local_plugin_catalog.FileBasedPluginCatalog.get_tool
sk_agents.plugin_catalog.local_plugin_catalog.FileBasedPluginCatalog.register_dynamic_plugin
Register a plugin discovered at runtime (e.g., from MCP servers).
Source code in src/sk_agents/plugin_catalog/local_plugin_catalog.py
sk_agents.plugin_catalog.local_plugin_catalog.FileBasedPluginCatalog.register_dynamic_tool
Register a tool discovered at runtime.
Source code in src/sk_agents/plugin_catalog/local_plugin_catalog.py
sk_agents.plugin_catalog.local_plugin_catalog.FileBasedPluginCatalog.unregister_dynamic_plugin
Unregister a dynamically registered plugin.
Source code in src/sk_agents/plugin_catalog/local_plugin_catalog.py
sk_agents.plugin_catalog.models
sk_agents.plugin_catalog.models.GovernanceOverride
Bases: BaseModel
Optional governance overrides for MCP tools.
Only specified fields will override auto-inferred values.
Source code in src/sk_agents/plugin_catalog/models.py
sk_agents.plugin_catalog.plugin_catalog
sk_agents.plugin_catalog.plugin_catalog.PluginCatalog
Bases: ABC
Source code in src/sk_agents/plugin_catalog/plugin_catalog.py
sk_agents.plugin_catalog.plugin_catalog.PluginCatalog.register_dynamic_plugin
Register a plugin discovered at runtime (e.g., from MCP servers).
sk_agents.plugin_catalog.plugin_catalog.PluginCatalog.register_dynamic_tool
Register a tool discovered at runtime.
sk_agents.plugin_catalog.plugin_catalog.PluginCatalog.unregister_dynamic_plugin
sk_agents.plugin_catalog.plugin_catalog_factory
sk_agents.plugin_catalog.plugin_catalog_factory.PluginCatalogFactory
Singleton factory for creating PluginCatalog instances based on environment variables.
Source code in src/sk_agents/plugin_catalog/plugin_catalog_factory.py
sk_agents.plugin_catalog.plugin_catalog_factory.PluginCatalogFactory.get_catalog
get_catalog() -> PluginCatalog
Get the plugin catalog instance, creating it if it doesn't exist.
Source code in src/sk_agents/plugin_catalog/plugin_catalog_factory.py
sk_agents.routes
sk_agents.routes.Routes
Source code in src/sk_agents/routes.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | |
sk_agents.routes.Routes.get_a2a_routes
staticmethod
get_a2a_routes(
name: str,
version: str,
description: str,
config: BaseConfig,
app_config: AppConfig,
chat_completion_builder: ChatCompletionBuilder,
task_store: TaskStore,
state_manager: StateManager,
) -> APIRouter
DEPRECATION NOTICE: A2A (Agent-to-Agent) routes are being deprecated as part of the framework migration evaluation. This method is maintained for backward compatibility only. New development should avoid using A2A functionality.
Source code in src/sk_agents/routes.py
sk_agents.routes.Routes.get_stateful_routes
staticmethod
get_stateful_routes(
name: str,
version: str,
description: str,
config: BaseConfig,
app_config: AppConfig,
state_manager: TaskPersistenceManager,
authorizer: RequestAuthorizer,
auth_storage_manager: SecureAuthStorageManager,
mcp_discovery_manager=None,
input_class: type[UserMessage] = UserMessage,
) -> APIRouter
Get the stateful API routes for the given configuration.
Source code in src/sk_agents/routes.py
sk_agents.routes.Routes.get_oauth_callback_routes
staticmethod
Get OAuth 2.1 callback routes for MCP server authentication.
This route handles the OAuth redirect callback after user authorization.
Source code in src/sk_agents/routes.py
427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | |
sk_agents.ska_types
sk_agents.ska_types.BaseMultiModalInputWithUserContext
Bases: KernelBaseModel
The history of a chat interaction between an automated assistant and a human with multimodal input (text and images), along with context about the user.
Source code in src/sk_agents/ska_types.py
sk_agents.ska_types.HistoryMessage
Bases: BaseModel
A single interaction in a chat history.
'role' - Either 'user' (requestor) or 'assistant' (responder) indicating
who sent the message.
'content' - The content of the message
Source code in src/sk_agents/ska_types.py
sk_agents.ska_types.BaseInput
Bases: KernelBaseModel
The history of a chat interaction between an automated assistant and a human.
Source code in src/sk_agents/ska_types.py
sk_agents.ska_types.BaseInputWithUserContext
Bases: KernelBaseModel
The history of a chat interaction between an automated assistant and a human, along with context about the user.
Source code in src/sk_agents/ska_types.py
sk_agents.state
sk_agents.state.redis_state_manager
Redis implementation of the StateManager interface. This implementation uses Redis as the persistent store for task state management.
sk_agents.state.redis_state_manager.RedisStateManager
Bases: StateManager
Redis implementation of the StateManager interface.
This class provides Redis-based persistence for task state management.
Source code in src/sk_agents/state/redis_state_manager.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | |
sk_agents.state.redis_state_manager.RedisStateManager.__init__
Initialize the RedisStateManager with a Redis client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
redis_client
|
Redis
|
An instance of Redis client |
required |
key_prefix
|
str
|
Prefix used for Redis keys (default: "task_state:") |
'task_state:'
|
Source code in src/sk_agents/state/redis_state_manager.py
sk_agents.state.redis_state_manager.RedisStateManager.update_task_messages
async
update_task_messages(
task_id: str, new_message: HistoryMultiModalMessage
) -> list[HistoryMultiModalMessage]
Updates the messages for a specific task.
Appends a new message to the task's message history and returns the complete list of messages.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_id
|
str
|
The ID of the task |
required |
new_message
|
HistoryMultiModalMessage
|
The new message to add to the task's history |
required |
Returns:
| Type | Description |
|---|---|
list[HistoryMultiModalMessage]
|
The complete list of messages for the task |
Source code in src/sk_agents/state/redis_state_manager.py
sk_agents.state.redis_state_manager.RedisStateManager.set_canceled
async
Marks a task as canceled.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_id
|
str
|
The ID of the task to mark as canceled |
required |
Source code in src/sk_agents/state/redis_state_manager.py
sk_agents.state.redis_state_manager.RedisStateManager.is_canceled
async
Checks if a task is marked as canceled.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_id
|
str
|
The ID of the task to check |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the task is canceled, False otherwise |
Source code in src/sk_agents/state/redis_state_manager.py
sk_agents.stateful
sk_agents.stateful.UserMessage
Bases: BaseModel
New input model for the tealagents/v1alpha1 API version. Unlike BaseMultiModalInput, chat history is maintained server-side.
Source code in src/sk_agents/stateful.py
sk_agents.stateful.TaskState
Bases: BaseModel
Model for the state associated with a Task ID
Source code in src/sk_agents/stateful.py
sk_agents.stateful.RequestState
Bases: BaseModel
Model for the state associated with a Request ID
Source code in src/sk_agents/stateful.py
sk_agents.stateful.StateResponse
Bases: BaseModel
Response model including state identifiers
Source code in src/sk_agents/stateful.py
sk_agents.stateful.StateManager
Bases: ABC
Abstract base class for state management
Source code in src/sk_agents/stateful.py
sk_agents.stateful.StateManager.create_task
abstractmethod
async
sk_agents.stateful.StateManager.get_task
abstractmethod
async
get_task(task_id: UUID4) -> TaskState
sk_agents.stateful.StateManager.update_task
abstractmethod
async
update_task(task_state: TaskState) -> None
sk_agents.stateful.StateManager.create_request
abstractmethod
async
sk_agents.stateful.StateManager.get_request
abstractmethod
async
get_request(request_id: UUID4) -> RequestState
sk_agents.stateful.StateManager.update_request
abstractmethod
async
update_request(request_state: RequestState) -> None
sk_agents.stateful.InMemoryStateManager
Bases: StateManager
In-memory implementation of state manager
Source code in src/sk_agents/stateful.py
sk_agents.stateful.RedisStateManager
Bases: StateManager
Redis implementation of state manager
Source code in src/sk_agents/stateful.py
sk_agents.stateful.AuthenticationManager
Bases: ABC
Abstract base class for authentication management
Source code in src/sk_agents/stateful.py
sk_agents.stateful.AuthenticationManager.authorize_request
abstractmethod
async
sk_agents.stateful.AuthenticationManager.validate_task_access
abstractmethod
async
sk_agents.stateful.MockAuthenticationManager
Bases: AuthenticationManager
Mock implementation of authentication manager for development
Source code in src/sk_agents/stateful.py
sk_agents.tealagents
sk_agents.tealagents.kernel_builder
sk_agents.tealagents.kernel_builder.KernelBuilder
Source code in src/sk_agents/tealagents/kernel_builder.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | |
sk_agents.tealagents.kernel_builder.KernelBuilder.load_mcp_plugins
async
load_mcp_plugins(
kernel: Kernel,
user_id: str,
session_id: str,
mcp_discovery_manager,
connection_manager,
) -> Kernel
Load MCP plugins by instantiating McpPlugin directly with tools from storage.
This loads tools discovered at session start and creates McpPlugin instances for each MCP server. Only tools that the user has authenticated to access will be loaded, ensuring proper multi-tenant isolation at the session level.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kernel
|
Kernel
|
The kernel to add plugins to |
required |
user_id
|
str
|
User ID to get plugins for (required) |
required |
session_id
|
str
|
Session ID for plugin isolation (required) |
required |
mcp_discovery_manager
|
Discovery manager for loading tool state (required) |
required | |
connection_manager
|
Request-scoped connection manager for connection reuse (required) |
required |
Returns:
| Type | Description |
|---|---|
Kernel
|
The kernel with session's MCP plugins loaded |
Note: MCP tools must be discovered first via McpPluginRegistry.discover_and_materialize() before calling this method.
Source code in src/sk_agents/tealagents/kernel_builder.py
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | |
sk_agents.tealagents.models
sk_agents.tealagents.models.AuthChallengeResponse
Bases: BaseModel
Response when MCP server authentication is required before agent construction.
Source code in src/sk_agents/tealagents/models.py
sk_agents.tealagents.models.TaskStatus
sk_agents.tealagents.v1alpha1
sk_agents.tealagents.v1alpha1.agent
sk_agents.tealagents.v1alpha1.agent.handler
sk_agents.tealagents.v1alpha1.agent.handler.TealAgentsV1Alpha1Handler
Bases: BaseHandler
Source code in src/sk_agents/tealagents/v1alpha1/agent/handler.py
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 | |
sk_agents.tealagents.v1alpha1.agent.handler.TealAgentsV1Alpha1Handler.authenticate_mcp_servers
async
authenticate_mcp_servers(
user_id: str,
session_id: str,
task_id: str,
request_id: str,
) -> AuthChallengeResponse | None
Authenticate MCP servers before agent construction.
Returns AuthChallengeResponse if authentication is needed, None if all servers are authenticated.
Source code in src/sk_agents/tealagents/v1alpha1/agent/handler.py
sk_agents.tealagents.v1alpha1.config
sk_agents.tealagents.v1alpha1.config.McpServerConfig
Bases: BaseModel
Configuration for an MCP server connection supporting multiple transports.
Source code in src/sk_agents/tealagents/v1alpha1/config.py
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | |
sk_agents.tealagents.v1alpha1.config.McpServerConfig.effective_canonical_uri
property
Get canonical MCP server URI for resource parameter binding.
Per MCP spec, canonical URI must be: - Absolute HTTPS URI - Lowercase scheme and host - Optional port and path
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
Canonical URI (either explicit or computed from url) |
Raises:
| Type | Description |
|---|---|
ValueError
|
If cannot determine canonical URI |
sk_agents.tealagents.v1alpha1.config.McpServerConfig.oauth_redirect_uri
property
Get platform OAuth redirect URI from config.
sk_agents.tealagents.v1alpha1.config.McpServerConfig.validate_transport_fields
Validate that required fields are provided for the selected transport.
Source code in src/sk_agents/tealagents/v1alpha1/config.py
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | |
sk_agents.utility_routes
sk_agents.utility_routes.HealthStatus
Bases: BaseModel
Health check response model.
Source code in src/sk_agents/utility_routes.py
sk_agents.utility_routes.ReadinessStatus
sk_agents.utility_routes.LivenessStatus
sk_agents.utility_routes.UtilityRoutes
Utility routes for health checks and system monitoring.
Source code in src/sk_agents/utility_routes.py
sk_agents.utility_routes.UtilityRoutes.get_health_routes
Get health check routes for the application.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
BaseConfig
|
Base configuration |
required |
app_config
|
AppConfig
|
Application configuration |
required |
Returns:
| Name | Type | Description |
|---|---|---|
APIRouter |
APIRouter
|
Router with health check endpoints |