Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| import argparse | |
| import os | |
| from pathlib import Path | |
| from huggingface_hub import HfApi, whoami, create_repo, upload_folder | |
| def repo_url(space_id: str) -> str: | |
| return f"https://huggingface.co/spaces/{space_id}" | |
| def app_url(space_id: str) -> str: | |
| owner, name = space_id.split("/", 1) | |
| return f"https://{owner}-{name}.hf.space" | |
| def main() -> None: | |
| parser = argparse.ArgumentParser(description="Create/sync the mcp-bridge Hugging Face Docker Space.") | |
| parser.add_argument("--space-id", default="patdev/mcp-bridge", help="HF Space ID, e.g. patdev/mcp-bridge") | |
| parser.add_argument("--api-key", default=os.getenv("MCP_API_KEY", ""), help="Value for Space secret MCP_API_KEY") | |
| parser.add_argument("--oauth-signing-key", default=os.getenv("MCP_OAUTH_SIGNING_KEY", ""), help="Optional Space secret MCP_OAUTH_SIGNING_KEY") | |
| parser.add_argument("--public-base-url", default="", help="Public base URL, defaults to https://owner-name.hf.space") | |
| parser.add_argument("--chatgpt-callback-url", default="", help="Optional exact ChatGPT OAuth callback URL allowlist. Not required by default; ChatGPT callback prefix is accepted.") | |
| parser.add_argument("--oauth-client-id", default=os.getenv("OAUTH_STATIC_CLIENT_ID", "chatgpt"), help="Manual OAuth client ID for ChatGPT when DCR is unavailable") | |
| parser.add_argument("--oauth-client-secret", default=os.getenv("OAUTH_STATIC_CLIENT_SECRET", ""), help="Optional manual OAuth client secret") | |
| parser.add_argument("--restart", action="store_true", help="Restart the Space after upload") | |
| args = parser.parse_args() | |
| if "/" not in args.space_id: | |
| raise SystemExit("--space-id must look like owner/name") | |
| if not args.api_key: | |
| raise SystemExit("Missing --api-key or MCP_API_KEY env var") | |
| root = Path(__file__).resolve().parents[1] | |
| api = HfApi() | |
| me = whoami() | |
| print(f"Authenticated as: {me.get('name') or me}") | |
| print(f"Space ID: {args.space_id}") | |
| print("Creating Space if needed...") | |
| create_repo(args.space_id, repo_type="space", space_sdk="docker", exist_ok=True) | |
| public_base = (args.public_base_url or app_url(args.space_id)).rstrip("/") | |
| print("Setting Space Secret MCP_API_KEY...") | |
| api.add_space_secret(repo_id=args.space_id, key="MCP_API_KEY", value=args.api_key) | |
| if args.oauth_signing_key: | |
| print("Setting Space Secret MCP_OAUTH_SIGNING_KEY...") | |
| api.add_space_secret(repo_id=args.space_id, key="MCP_OAUTH_SIGNING_KEY", value=args.oauth_signing_key) | |
| def set_space_var(key: str, value: str) -> None: | |
| try: | |
| api.add_space_variable(repo_id=args.space_id, key=key, value=value) | |
| except AttributeError: | |
| # Older huggingface_hub fallback: harmless, but secret instead of variable. | |
| api.add_space_secret(repo_id=args.space_id, key=key, value=value) | |
| print(f"Setting Space Variable PUBLIC_BASE_URL={public_base}") | |
| set_space_var("PUBLIC_BASE_URL", public_base) | |
| if args.oauth_client_id: | |
| print(f"Setting Space Variable OAUTH_STATIC_CLIENT_ID={args.oauth_client_id}") | |
| set_space_var("OAUTH_STATIC_CLIENT_ID", args.oauth_client_id) | |
| if args.chatgpt_callback_url: | |
| print("Setting Space Variable OAUTH_ALLOWED_REDIRECT_URIS=<exact ChatGPT callback URL>") | |
| set_space_var("OAUTH_ALLOWED_REDIRECT_URIS", args.chatgpt_callback_url.strip()) | |
| else: | |
| print("Using default ChatGPT redirect prefix allow: https://chatgpt.com/connector/oauth/*") | |
| set_space_var("OAUTH_ALLOW_CHATGPT_REDIRECT_PREFIX", "true") | |
| if args.oauth_client_secret: | |
| print("Setting Space Secret OAUTH_STATIC_CLIENT_SECRET") | |
| api.add_space_secret(repo_id=args.space_id, key="OAUTH_STATIC_CLIENT_SECRET", value=args.oauth_client_secret) | |
| print("Uploading project files...") | |
| info = upload_folder( | |
| repo_id=args.space_id, | |
| repo_type="space", | |
| folder_path=str(root), | |
| path_in_repo=".", | |
| ignore_patterns=[".git", ".hf", "__pycache__", "*.pyc", ".env", "*.zip"], | |
| commit_message="Update mcp-bridge OAuth server", | |
| ) | |
| print(f"Uploaded: {getattr(info, 'commit_url', info)}") | |
| if args.restart: | |
| print("Restarting Space...") | |
| api.restart_space(repo_id=args.space_id) | |
| print("\nDone.") | |
| print(f"Space: {repo_url(args.space_id)}") | |
| print(f"MCP SSE: {public_base}/sse") | |
| if __name__ == "__main__": | |
| main() | |