@@ -16,6 +16,7 @@ class AppServerInfo(BaseModel):
1616 "APP_SERVER_STATUS_ONLINE" ,
1717 "APP_SERVER_STATUS_OFFLINE" ,
1818 ] # Enums: 0=UNSPECIFIED, 1=ONLINE, 2=OFFLINE
19+ unauthenticatedAccess : Optional [bool ] = None
1920
2021
2122# A developer-deployed MCP App which others can configure and use.
@@ -26,6 +27,7 @@ class MCPApp(BaseModel):
2627 description : Optional [str ] = None
2728 createdAt : datetime
2829 updatedAt : datetime
30+ unauthenticatedAccess : Optional [bool ] = None
2931 appServerInfo : Optional [AppServerInfo ] = None
3032 deploymentMetadata : Optional [Dict [str , Any ]] = None
3133
@@ -131,12 +133,18 @@ def log_entries_list(self) -> List[LogEntry]:
131133class MCPAppClient (APIClient ):
132134 """Client for interacting with the MCP App API service over HTTP."""
133135
134- async def create_app (self , name : str , description : Optional [str ] = None ) -> MCPApp :
136+ async def create_app (
137+ self ,
138+ name : str ,
139+ description : Optional [str ] = None ,
140+ unauthenticated_access : Optional [bool ] = None ,
141+ ) -> MCPApp :
135142 """Create a new MCP App via the API.
136143
137144 Args:
138145 name: The name of the MCP App
139146 description: Optional description for the app
147+ unauthenticated_access: Whether the app should allow unauthenticated access
140148
141149 Returns:
142150 MCPApp: The created MCP App
@@ -155,6 +163,9 @@ async def create_app(self, name: str, description: Optional[str] = None) -> MCPA
155163 if description :
156164 payload ["description" ] = description
157165
166+ if unauthenticated_access is not None :
167+ payload ["unauthenticatedAccess" ] = unauthenticated_access
168+
158169 response = await self .post ("/mcp_app/create_app" , payload )
159170
160171 res = response .json ()
@@ -245,6 +256,60 @@ async def get_app_configuration(
245256
246257 return MCPAppConfiguration (** res ["appConfiguration" ])
247258
259+ async def update_app (
260+ self ,
261+ app_id : str ,
262+ name : Optional [str ] = None ,
263+ description : Optional [str ] = None ,
264+ unauthenticated_access : Optional [bool ] = None ,
265+ ) -> MCPApp :
266+ """Update an existing MCP App via the API.
267+
268+ Args:
269+ app_id: The UUID of the app to update
270+ name: Optional new name for the app
271+ description: Optional new description for the app
272+ unauthenticated_access: Optional flag to toggle unauthenticated access
273+
274+ Returns:
275+ MCPApp: The updated MCP App
276+
277+ Raises:
278+ ValueError: If the app_id is invalid or no fields are provided
279+ httpx.HTTPStatusError: If the API returns an error
280+ httpx.HTTPError: If the request fails
281+ """
282+ if not app_id or not is_valid_app_id_format (app_id ):
283+ raise ValueError (f"Invalid app ID format: { app_id } " )
284+
285+ if name is None and description is None and unauthenticated_access is None :
286+ raise ValueError (
287+ "At least one of name, description, or unauthenticated_access must be provided."
288+ )
289+
290+ payload : Dict [str , Any ] = {"appId" : app_id }
291+
292+ if name is not None :
293+ if not isinstance (name , str ) or not name .strip ():
294+ raise ValueError ("App name must be a non-empty string when provided" )
295+ payload ["name" ] = name
296+
297+ if description is not None :
298+ if not isinstance (description , str ):
299+ raise ValueError ("App description must be a string when provided" )
300+ payload ["description" ] = description
301+
302+ if unauthenticated_access is not None :
303+ payload ["unauthenticatedAccess" ] = unauthenticated_access
304+
305+ response = await self .put ("/mcp_app/update_app" , payload )
306+
307+ res = response .json ()
308+ if not res or "app" not in res :
309+ raise ValueError ("API response did not contain the updated app data" )
310+
311+ return MCPApp (** res ["app" ])
312+
248313 async def get_app_or_config (
249314 self , app_id_or_url : str
250315 ) -> Union [MCPApp , MCPAppConfiguration ]:
0 commit comments