@@ -432,6 +432,23 @@ struct GetTeamIterationsArgs {
432432 team_id : String ,
433433}
434434
435+ #[ derive( Deserialize , JsonSchema ) ]
436+ struct ListTeamMembersArgs {
437+ /// AzDO org name
438+ #[ serde( deserialize_with = "deserialize_non_empty_string" ) ]
439+ organization : String ,
440+ /// AzDO project name
441+ #[ serde( deserialize_with = "deserialize_non_empty_string" ) ]
442+ project : String ,
443+ /// Team ID or name
444+ team_id : String ,
445+ }
446+
447+ #[ derive( Deserialize , JsonSchema ) ]
448+ struct GetCurrentUserArgs {
449+ // No parameters needed
450+ }
451+
435452#[ derive( Deserialize , JsonSchema ) ]
436453struct GetWorkItemArgs {
437454 /// AzDO org name
@@ -821,6 +838,102 @@ impl AzureMcpServer {
821838 ) ] ) )
822839 }
823840
841+ #[ tool( description = "List team members" ) ]
842+ async fn azdo_list_team_members (
843+ & self ,
844+ args : Parameters < ListTeamMembersArgs > ,
845+ ) -> Result < CallToolResult , McpError > {
846+ log:: info!( "Tool invoked: azdo_list_team_members" ) ;
847+ let members = self
848+ . client
849+ . list_team_members ( & args. 0 . organization , & args. 0 . project , & args. 0 . team_id )
850+ . await
851+ . map_err ( |e| McpError {
852+ code : ErrorCode ( -32000 ) ,
853+ message : e. to_string ( ) . into ( ) ,
854+ data : None ,
855+ } ) ?;
856+
857+ let mut wtr = csv:: WriterBuilder :: new ( )
858+ . has_headers ( false )
859+ . from_writer ( vec ! [ ] ) ;
860+
861+ for member in members {
862+ wtr. write_record ( & [ member. identity . display_name , member. identity . unique_name ] )
863+ . map_err ( |e| McpError {
864+ code : ErrorCode ( -32000 ) ,
865+ message : format ! ( "Failed to write CSV: {}" , e) . into ( ) ,
866+ data : None ,
867+ } ) ?;
868+ }
869+
870+ wtr. flush ( ) . map_err ( |e| McpError {
871+ code : ErrorCode ( -32000 ) ,
872+ message : format ! ( "Failed to flush CSV: {}" , e) . into ( ) ,
873+ data : None ,
874+ } ) ?;
875+
876+ let csv_bytes = wtr. into_inner ( ) . map_err ( |e| McpError {
877+ code : ErrorCode ( -32000 ) ,
878+ message : format ! ( "Failed to get CSV bytes: {}" , e) . into ( ) ,
879+ data : None ,
880+ } ) ?;
881+
882+ let data = String :: from_utf8 ( csv_bytes) . map_err ( |e| McpError {
883+ code : ErrorCode ( -32000 ) ,
884+ message : format ! ( "Failed to convert CSV to string: {}" , e) . into ( ) ,
885+ data : None ,
886+ } ) ?;
887+
888+ Ok ( CallToolResult :: success ( vec ! [ Content :: text( data) ] ) )
889+ }
890+
891+ #[ tool( description = "Get current user profile" ) ]
892+ async fn azdo_get_current_user (
893+ & self ,
894+ _args : Parameters < GetCurrentUserArgs > ,
895+ ) -> Result < CallToolResult , McpError > {
896+ log:: info!( "Tool invoked: azdo_get_current_user" ) ;
897+ let profile = organizations:: get_profile ( & self . client )
898+ . await
899+ . map_err ( |e| McpError {
900+ code : ErrorCode ( -32000 ) ,
901+ message : e. to_string ( ) . into ( ) ,
902+ data : None ,
903+ } ) ?;
904+
905+ let mut wtr = csv:: WriterBuilder :: new ( )
906+ . has_headers ( false )
907+ . from_writer ( vec ! [ ] ) ;
908+
909+ wtr. write_record ( & [ profile. display_name , profile. email_address ] )
910+ . map_err ( |e| McpError {
911+ code : ErrorCode ( -32000 ) ,
912+ message : format ! ( "Failed to write CSV: {}" , e) . into ( ) ,
913+ data : None ,
914+ } ) ?;
915+
916+ wtr. flush ( ) . map_err ( |e| McpError {
917+ code : ErrorCode ( -32000 ) ,
918+ message : format ! ( "Failed to flush CSV: {}" , e) . into ( ) ,
919+ data : None ,
920+ } ) ?;
921+
922+ let csv_bytes = wtr. into_inner ( ) . map_err ( |e| McpError {
923+ code : ErrorCode ( -32000 ) ,
924+ message : format ! ( "Failed to get CSV bytes: {}" , e) . into ( ) ,
925+ data : None ,
926+ } ) ?;
927+
928+ let data = String :: from_utf8 ( csv_bytes) . map_err ( |e| McpError {
929+ code : ErrorCode ( -32000 ) ,
930+ message : format ! ( "Failed to convert CSV to string: {}" , e) . into ( ) ,
931+ data : None ,
932+ } ) ?;
933+
934+ Ok ( CallToolResult :: success ( vec ! [ Content :: text( data) ] ) )
935+ }
936+
824937 #[ tool( description = "List AzDO organizations" ) ]
825938 async fn azdo_list_organizations (
826939 & self ,
0 commit comments