create_project
Set up a new GitLab project by specifying a name, optional description, and visibility level such as private, internal, or public.
Instructions
Create a new GitLab project.
Args:
name: Project name
description: Project description (optional)
visibility: Project visibility (private, internal, public)
token: GitLab Personal Access Token (optional)
ctx: MCP context (automatically injected)Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| description | No | ||
| visibility | No | private | |
| token | No | ||
| ctx | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- gitlab_clone_mcp_server/server.py:54-77 (handler)The 'create_project' tool handler function. It creates a new GitLab project by calling the GitLab API POST /projects endpoint. Parameters: name (required), description (optional), visibility (optional, defaults to 'private'), token (optional), ctx (auto-injected MCP context). It sends a POST request with project data to GitLab and returns the created project's name, ID, and URL.
@mcp.tool() async def create_project(name: str, description: str = "", visibility: str = "private", token: str = None, ctx=None) -> str: """Create a new GitLab project. Args: name: Project name description: Project description (optional) visibility: Project visibility (private, internal, public) token: GitLab Personal Access Token (optional) ctx: MCP context (automatically injected) """ data = { "name": name, "description": description, "visibility": visibility, "initialize_with_readme": True } result = await make_gitlab_request("/projects", "POST", data, ctx, token=token) if isinstance(result, dict) and "error" in result: return f"Error creating project: {result['error']}" return f"Project created: {result['name']} (ID: {result['id']})\nURL: {result['web_url']}" - gitlab_clone_mcp_server/server.py:54-55 (registration)The tool is registered using the @mcp.tool() decorator on the FastMCP instance 'mcp' (line 9: mcp = FastMCP('GitLab MCP Server', ...)). The decorator registers 'create_project' as an MCP tool within the FastMCP framework.
@mcp.tool() async def create_project(name: str, description: str = "", visibility: str = "private", token: str = None, ctx=None) -> str: - Helper function called by create_project to execute the actual HTTP request to the GitLab API. It handles token resolution (from parameter, context headers, or environment variable), builds the GitLab API URL, and executes GET/POST/PUT/DELETE requests using httpx.
async def make_gitlab_request(endpoint: str, method: str = "GET", data: dict = None, ctx=None, token: str = None) -> dict[str, Any] | None: """Make a request to GitLab API with proper error handling.""" # Priority: 1. Explicit token parameter, 2. Context headers, 3. Environment variable # If no explicit token provided, try to get from context if not token and ctx and hasattr(ctx, 'request_context') and ctx.request_context: # Try to get from request headers if hasattr(ctx.request_context, 'headers'): token = ctx.request_context.headers.get('GITLAB_TOKEN') # Fallback to environment variable if not token: token = os.getenv("GITLAB_TOKEN") if not token: return {"error": "GitLab token not provided. Please provide a token parameter, GITLAB_TOKEN in the request headers, or set the environment variable."} # Get GitLab URL (from context or environment) gitlab_url = os.getenv("GITLAB_URL", "https://gitlab.com") headers = { "PRIVATE-TOKEN": token, "Content-Type": "application/json" } url = f"{gitlab_url}/api/v4{endpoint}" async with httpx.AsyncClient() as client: try: if method == "GET": response = await client.get(url, headers=headers, timeout=30.0) elif method == "POST": response = await client.post(url, headers=headers, json=data, timeout=30.0) elif method == "PUT": response = await client.put(url, headers=headers, json=data, timeout=30.0) elif method == "DELETE": response = await client.delete(url, headers=headers, timeout=30.0) response.raise_for_status() return response.json() if response.content else {"success": True} except Exception as e: return {"error": str(e)}