@@ -208,8 +208,11 @@ def _initialize_config() -> None:
208208 if "account_id" in scope :
209209 account_id = cast (AccountScope , scope )["account_id" ]
210210 print (f"✓ Connected with account-scoped API key (account: { account_id } )" , file = sys .stderr )
211- # If a project_id is explicitly provided via env, prepare a client for it
211+ # If a project_id is explicitly provided via env, add it to scope
212212 if project_id_config :
213+ # Store project_id in scope so tools/resources can use it as fallback
214+ scope ["project_id" ] = project_id_config # type: ignore
215+ _api_key_scope = scope
213216 client = Project (api_key = _api_key , project_id = project_id_config , host = _host )
214217 _project_clients [project_id_config ] = client
215218 print (
@@ -234,37 +237,31 @@ def get_project_client(project_id: Optional[str] = None) -> Project:
234237 """
235238 Get or create a Project client for the given project.
236239
237- For project-scoped API keys, project_id is optional (uses the key's project).
238- For account-scoped API keys, project_id is required.
240+ Project ID resolution (in order of priority):
241+ 1. Explicit project_id parameter
242+ 2. project_id from _api_key_scope (for project-scoped keys or account-scoped keys with COCALC_PROJECT_ID)
243+ 3. Project client extracts it from the API key (for project-scoped keys)
239244
240245 Args:
241- project_id: The project UUID. If None, uses the project-scoped key's project .
246+ project_id: The project UUID. If None, uses the value from _api_key_scope or the API key itself .
242247
243248 Returns:
244249 Project client for the specified project
245250
246251 Raises:
247- RuntimeError: If project_id cannot be determined or account-scoped key without project_id
252+ RuntimeError: If project_id cannot be determined
248253 """
249254 global _project_clients
250255
251256 _initialize_config ()
252257
253258 # Determine which project_id to use
254259 if project_id is None :
255- # If no project_id provided, try to use the one from project-scoped key
260+ # Try to use project_id from scope (works for both project-scoped keys
261+ # and account-scoped keys with explicit COCALC_PROJECT_ID)
256262 scope = _api_key_scope
257263 if scope and "project_id" in scope :
258264 project_id = cast (ProjectScope , scope )["project_id" ]
259- else :
260- # Account-scoped key requires explicit project_id
261- raise RuntimeError ("Account-scoped API key requires an explicit project_id argument. "
262- "No project_id provided to get_project_client()." )
263-
264- # For project-scoped keys with None/empty project_id, the Project client will extract it from the API key
265- # For account-scoped keys, project_id must be non-empty
266- if not project_id and _api_key_scope and "account_id" in _api_key_scope :
267- raise RuntimeError ("Account-scoped API key requires a non-empty project_id" )
268265
269266 # Use a cache key that handles None/empty project_id for project-scoped keys
270267 cache_key = project_id if project_id else "_default_project"
@@ -288,18 +285,24 @@ def _register_tools_and_resources() -> None:
288285
289286 _initialize_config ()
290287
291- # Determine which tools/resources to register based on API key scope
292- if _api_key_scope and "account_id" in _api_key_scope :
293- # Account-scoped key: register account-scoped tools/resources
288+ # Determine what needs to be registered
289+ register_account_tools = _api_key_scope and "account_id" in _api_key_scope
290+ register_project_tools = _api_key_scope and "project_id" in _api_key_scope
291+ # Also register project tools if account-scoped key has explicit project
292+ if register_account_tools and _project_clients :
293+ register_project_tools = True
294+
295+ # Register account-scoped tools/resources
296+ if register_account_tools :
294297 print ("Registering account-scoped tools and resources..." , file = sys .stderr )
295298 from .tools .projects_search import register_projects_search_tool
296299 from .resources .account_profile import register_account_profile_resource
297300
298301 register_projects_search_tool (mcp )
299302 register_account_profile_resource (mcp )
300303
301- elif _api_key_scope and "project_id" in _api_key_scope :
302- # Project-scoped key: register project-scoped tools/resources
304+ # Register project-scoped tools/resources
305+ if register_project_tools :
303306 print ("Registering project-scoped tools and resources..." , file = sys .stderr )
304307 from .tools .exec import register_exec_tool
305308 from .tools .jupyter import register_jupyter_tool
0 commit comments