Bläddra i källkod

feat: add Admin API support for user, org, and repo administration #15

Implemented comprehensive Admin API tools for Gogs administration tasks:

User Administration:
- admin_create_user: Create new users with full configuration
- admin_edit_user: Edit user properties (active, admin, permissions, etc.)
- admin_delete_user: Delete user accounts
- admin_create_user_public_key: Add SSH keys for users
- admin_delete_user_public_key: Remove SSH keys from users

Organization Administration:
- admin_create_org: Create organizations
- admin_list_org_teams: List teams in an organization
- admin_create_user_org: Create organization for specific user

Repository Administration:
- admin_create_user_repo: Create repositories for users

Technical Implementation:
- Added TypeScript types for Admin API requests (GogsAdminCreateUserRequest, GogsAdminEditUserRequest, GogsAdminCreateOrgRequest)
- Implemented admin API methods in gogs-client.ts with proper typing
- Added Zod schemas for request validation
- Implemented MCP tool definitions with security warnings
- Added request handlers with error handling
- Updated README.md with comprehensive documentation and security considerations
- Updated CLAUDE.md with new tool categories

Security Features:
- All admin tools clearly marked with ⚠️ warning
- Proper documentation of admin-only requirements
- Returns appropriate error messages for unauthorized access
- Comprehensive parameter validation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
claude 9 månader sedan
förälder
incheckning
0ebc049952
5 ändrade filer med 813 tillägg och 9 borttagningar
  1. 1 0
      CLAUDE.md
  2. 177 9
      README.md
  3. 111 0
      src/gogs-client.ts
  4. 488 0
      src/server.ts
  5. 36 0
      src/types.ts

+ 1 - 0
CLAUDE.md

@@ -43,6 +43,7 @@ The server exposes tools in these categories:
 - **Webhook Management**: list_hooks, create_hook, update_hook, delete_hook
 - **User Followers**: list_followers, list_following, check_following, follow_user, unfollow_user
 - **Markdown Rendering**: render_markdown, render_markdown_raw
+- **Admin APIs** (⚠️ requires admin privileges): admin_create_user, admin_edit_user, admin_delete_user, admin_create_user_public_key, admin_delete_user_public_key, admin_create_org, admin_list_org_teams, admin_create_user_org, admin_create_user_repo
 
 ## Development Commands
 

+ 177 - 9
README.md

@@ -923,6 +923,183 @@ Unfollow a user. The authenticated user will unfollow the target user.
 }
 ```
 
+### Admin API Tools
+
+⚠️ **WARNING: These tools require administrator privileges on the Gogs instance.**
+
+These tools provide administrative capabilities for managing users, organizations, and repositories. They can only be used with an access token that has admin permissions. Unauthorized access attempts will result in 403 Forbidden errors.
+
+**Security Considerations:**
+- Only use these tools with admin access tokens
+- Admin operations are typically logged for audit purposes
+- These tools can perform destructive operations (e.g., delete users)
+- Ensure proper authorization and validation before use
+- Consider implementing additional access controls in production environments
+
+#### `admin_create_user`
+Create a new user account (admin only).
+- `source_id` (number, required): Authentication source ID (use 0 for local authentication)
+- `login_name` (string, required): Login name for authentication
+- `username` (string, required): Username for the account
+- `email` (string, required): Email address
+- `password` (string, required): Password for the user
+- `full_name` (string, optional): Full name of the user
+- `send_notify` (boolean, optional): Send notification email to user (default: false)
+
+**Example:**
+```json
+{
+  "source_id": 0,
+  "login_name": "newuser",
+  "username": "newuser",
+  "email": "newuser@example.com",
+  "password": "securePassword123",
+  "full_name": "New User",
+  "send_notify": false
+}
+```
+
+#### `admin_edit_user`
+Edit an existing user's properties (admin only).
+- `username` (string, required): Username of the user to edit
+- `source_id` (number, optional): Authentication source ID
+- `login_name` (string, optional): Login name for authentication
+- `full_name` (string, optional): Full name of the user
+- `email` (string, optional): Email address
+- `password` (string, optional): New password
+- `website` (string, optional): Website URL
+- `location` (string, optional): Location
+- `active` (boolean, optional): Whether the account is active
+- `admin` (boolean, optional): Whether the user is an admin
+- `allow_git_hook` (boolean, optional): Allow git hooks
+- `allow_import_local` (boolean, optional): Allow importing local repositories
+- `max_repo_creation` (number, optional): Maximum number of repositories
+- `prohibit_login` (boolean, optional): Prohibit user login
+- `allow_create_organization` (boolean, optional): Allow creating organizations
+
+**Example:**
+```json
+{
+  "username": "existinguser",
+  "email": "newemail@example.com",
+  "active": true,
+  "admin": false
+}
+```
+
+#### `admin_delete_user`
+Delete a user account (admin only). This is a destructive operation.
+- `username` (string, required): Username of the user to delete
+
+**Example:**
+```json
+{
+  "username": "userToDelete"
+}
+```
+
+#### `admin_create_user_public_key`
+Create a public SSH key for a user (admin only).
+- `username` (string, required): Username to add the key to
+- `title` (string, required): Title/name for the key
+- `key` (string, required): Public key content (SSH public key)
+
+**Example:**
+```json
+{
+  "username": "john",
+  "title": "Work Laptop",
+  "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC..."
+}
+```
+
+#### `admin_delete_user_public_key`
+Delete a public SSH key for a user (admin only).
+- `username` (string, required): Username to remove the key from
+- `key_id` (number, required): ID of the public key to delete
+
+**Example:**
+```json
+{
+  "username": "john",
+  "key_id": 5
+}
+```
+
+#### `admin_create_org`
+Create an organization (admin only).
+- `username` (string, required): Organization username
+- `full_name` (string, optional): Full name of the organization
+- `description` (string, optional): Organization description
+- `website` (string, optional): Organization website
+- `location` (string, optional): Organization location
+
+**Example:**
+```json
+{
+  "username": "engineering-team",
+  "full_name": "Engineering Team",
+  "description": "Core engineering organization",
+  "website": "https://engineering.example.com",
+  "location": "San Francisco, CA"
+}
+```
+
+#### `admin_list_org_teams`
+List all teams in an organization (admin only).
+- `orgname` (string, required): Organization name
+
+**Example:**
+```json
+{
+  "orgname": "engineering-team"
+}
+```
+
+#### `admin_create_user_org`
+Create an organization owned by a specific user (admin only).
+- `username` (string, required): Username who will own the organization
+- `org_username` (string, required): Organization username
+- `full_name` (string, optional): Full name of the organization
+- `description` (string, optional): Organization description
+- `website` (string, optional): Organization website
+- `location` (string, optional): Organization location
+
+**Example:**
+```json
+{
+  "username": "john",
+  "org_username": "johns-org",
+  "full_name": "John's Organization",
+  "description": "Personal organization for projects"
+}
+```
+
+#### `admin_create_user_repo`
+Create a repository for a specific user (admin only).
+- `username` (string, required): Username who will own the repository
+- `name` (string, required): Repository name
+- `description` (string, optional): Repository description
+- `private` (boolean, optional): Create as private repository (default: false)
+- `auto_init` (boolean, optional): Initialize with README (default: false)
+- `gitignores` (string, optional): Gitignore templates (e.g., "Go,VisualStudioCode")
+- `license` (string, optional): License template (e.g., "MIT License")
+- `readme` (string, optional): README template (default: "Default")
+
+**Example:**
+```json
+{
+  "username": "john",
+  "name": "new-project",
+  "description": "A new project repository",
+  "private": false,
+  "auto_init": true,
+  "gitignores": "Go,VisualStudioCode",
+  "license": "MIT License",
+  "readme": "Default"
+}
+```
+
 ### Markdown Rendering Tools
 
 These tools allow rendering markdown text to HTML without committing files, useful for previewing documentation, issue/comment content, and building custom markdown editors.
@@ -974,18 +1151,9 @@ The following Gogs API v1 endpoints are officially documented but not yet implem
 
 | Category | Endpoint | Method | Description | Documentation |
 |----------|----------|--------|-------------|---------------|
-| **User Administration** | `/admin/users` | POST | Create a new user | [Link](https://github.com/gogs/docs-api/blob/master/Administration/Users.md#create-a-new-user) |
-| **User Administration** | `/admin/users/:username` | PATCH | Edit an existing user | [Link](https://github.com/gogs/docs-api/blob/master/Administration/Users.md#edit-an-existing-user) |
-| **User Administration** | `/admin/users/:username` | DELETE | Delete a user | [Link](https://github.com/gogs/docs-api/blob/master/Administration/Users.md#delete-a-user) |
-| **User Administration** | `/admin/users/:username/keys` | POST | Create public key for user | [Link](https://github.com/gogs/docs-api/blob/master/Administration/Users.md#create-a-public-key-for-user) |
-| **Repository Administration** | `/admin/users/:username/repos` | POST | Create repository for user/org | [Link](https://github.com/gogs/docs-api/blob/master/Administration/Repositories.md) |
 | **Team Administration** | `/admin/teams/:teamid/members` | GET | List all members of a team | [Link](https://github.com/gogs/docs-api/blob/master/Administration/Teams.md#list-all-members-of-a-team) |
 | **Team Administration** | `/admin/teams/:teamid/repos/:reponame` | PUT | Add or update team repository | [Link](https://github.com/gogs/docs-api/blob/master/Administration/Teams.md#add-or-update-team-repository) |
 | **Team Administration** | `/admin/teams/:teamid/repos/:reponame` | DELETE | Remove team repository | [Link](https://github.com/gogs/docs-api/blob/master/Administration/Teams.md#remove-team-repository) |
-| **Deploy Keys** | `/repos/:username/:reponame/keys` | GET | List deploy keys | [Link](https://github.com/gogs/docs-api/blob/master/Repositories/Deploy%20Keys.md) |
-| **Deploy Keys** | `/repos/:username/:reponame/keys/:id` | GET | Get a deploy key | [Link](https://github.com/gogs/docs-api/blob/master/Repositories/Deploy%20Keys.md) |
-| **Deploy Keys** | `/repos/:username/:reponame/keys` | POST | Add a new deploy key | [Link](https://github.com/gogs/docs-api/blob/master/Repositories/Deploy%20Keys.md) |
-| **Deploy Keys** | `/repos/:username/:reponame/keys/:id` | DELETE | Remove a deploy key | [Link](https://github.com/gogs/docs-api/blob/master/Repositories/Deploy%20Keys.md) |
 
 ### Contributing New Endpoints
 

+ 111 - 0
src/gogs-client.ts

@@ -31,6 +31,9 @@ import type {
   GogsDeployKey,
   GogsMarkdownRequest,
   GogsMarkdownMode,
+  GogsAdminCreateUserRequest,
+  GogsAdminEditUserRequest,
+  GogsAdminCreateOrgRequest,
 } from './types.js';
 
 export class GogsClient {
@@ -913,4 +916,112 @@ export class GogsClient {
     });
     return response.data;
   }
+
+  // ==================== Admin APIs ====================
+  // These endpoints require admin privileges
+
+  /**
+   * Create a new user (admin only)
+   * @requires admin privileges
+   */
+  async adminCreateUser(data: GogsAdminCreateUserRequest): Promise<GogsUser> {
+    const response = await this.client.post<GogsUser>('/admin/users', data);
+    return response.data;
+  }
+
+  /**
+   * Edit an existing user's properties (admin only)
+   * @requires admin privileges
+   */
+  async adminEditUser(username: string, data: GogsAdminEditUserRequest): Promise<GogsUser> {
+    const response = await this.client.patch<GogsUser>(`/admin/users/${username}`, data);
+    return response.data;
+  }
+
+  /**
+   * Delete a user (admin only)
+   * @requires admin privileges
+   */
+  async adminDeleteUser(username: string): Promise<void> {
+    await this.client.delete(`/admin/users/${username}`);
+  }
+
+  /**
+   * Create a public key for a user (admin only)
+   * @requires admin privileges
+   */
+  async adminCreateUserPublicKey(
+    username: string,
+    data: { title: string; key: string }
+  ): Promise<GogsPublicKey> {
+    const response = await this.client.post<GogsPublicKey>(
+      `/admin/users/${username}/keys`,
+      data
+    );
+    return response.data;
+  }
+
+  /**
+   * Delete a public key for a user (admin only)
+   * @requires admin privileges
+   */
+  async adminDeleteUserPublicKey(username: string, keyId: number): Promise<void> {
+    await this.client.delete(`/admin/users/${username}/keys/${keyId}`);
+  }
+
+  /**
+   * Create an organization (admin only)
+   * @requires admin privileges
+   */
+  async adminCreateOrg(data: GogsAdminCreateOrgRequest): Promise<GogsOrganization> {
+    const response = await this.client.post<GogsOrganization>('/admin/orgs', data);
+    return response.data;
+  }
+
+  /**
+   * List teams in an organization (admin only)
+   * @requires admin privileges
+   */
+  async adminListOrgTeams(orgname: string): Promise<GogsTeam[]> {
+    const response = await this.client.get<GogsTeam[]>(`/admin/orgs/${orgname}/teams`);
+    return response.data;
+  }
+
+  /**
+   * Create an organization for a user (admin only)
+   * @requires admin privileges
+   */
+  async adminCreateUserOrg(
+    username: string,
+    data: GogsAdminCreateOrgRequest
+  ): Promise<GogsOrganization> {
+    const response = await this.client.post<GogsOrganization>(
+      `/admin/users/${username}/orgs`,
+      data
+    );
+    return response.data;
+  }
+
+  /**
+   * Create a repository for a user (admin only)
+   * @requires admin privileges
+   */
+  async adminCreateUserRepo(
+    username: string,
+    data: {
+      name: string;
+      description?: string;
+      private?: boolean;
+      auto_init?: boolean;
+      gitignores?: string;
+      license?: string;
+      readme?: string;
+    }
+  ): Promise<GogsRepository> {
+    const response = await this.client.post<GogsRepository>(
+      `/admin/users/${username}/repos`,
+      data
+    );
+    return response.data;
+  }
 }

+ 488 - 0
src/server.ts

@@ -456,6 +456,82 @@ const RenderMarkdownRawSchema = z.object({
   text: z.string().describe('Raw markdown text to render to HTML'),
 });
 
+// Admin API Schemas
+const AdminCreateUserSchema = z.object({
+  source_id: z.number().describe('Authentication source ID (0 for local)'),
+  login_name: z.string().describe('Login name for authentication'),
+  username: z.string().describe('Username for the account'),
+  full_name: z.string().optional().describe('Full name of the user'),
+  email: z.string().describe('Email address'),
+  password: z.string().describe('Password for the user'),
+  send_notify: z.boolean().optional().describe('Send notification email to user (default: false)'),
+});
+
+const AdminEditUserSchema = z.object({
+  username: z.string().describe('Username of the user to edit'),
+  source_id: z.number().optional().describe('Authentication source ID'),
+  login_name: z.string().optional().describe('Login name for authentication'),
+  full_name: z.string().optional().describe('Full name of the user'),
+  email: z.string().optional().describe('Email address'),
+  password: z.string().optional().describe('New password'),
+  website: z.string().optional().describe('Website URL'),
+  location: z.string().optional().describe('Location'),
+  active: z.boolean().optional().describe('Whether the account is active'),
+  admin: z.boolean().optional().describe('Whether the user is an admin'),
+  allow_git_hook: z.boolean().optional().describe('Allow git hooks'),
+  allow_import_local: z.boolean().optional().describe('Allow importing local repositories'),
+  max_repo_creation: z.number().optional().describe('Maximum number of repositories'),
+  prohibit_login: z.boolean().optional().describe('Prohibit user login'),
+  allow_create_organization: z.boolean().optional().describe('Allow creating organizations'),
+});
+
+const AdminDeleteUserSchema = z.object({
+  username: z.string().describe('Username of the user to delete'),
+});
+
+const AdminCreateUserPublicKeySchema = z.object({
+  username: z.string().describe('Username to add the key to'),
+  title: z.string().describe('Title/name for the key'),
+  key: z.string().describe('Public key content'),
+});
+
+const AdminDeleteUserPublicKeySchema = z.object({
+  username: z.string().describe('Username to remove the key from'),
+  key_id: z.number().describe('ID of the public key to delete'),
+});
+
+const AdminCreateOrgSchema = z.object({
+  username: z.string().describe('Organization username'),
+  full_name: z.string().optional().describe('Full name of the organization'),
+  description: z.string().optional().describe('Organization description'),
+  website: z.string().optional().describe('Organization website'),
+  location: z.string().optional().describe('Organization location'),
+});
+
+const AdminListOrgTeamsSchema = z.object({
+  orgname: z.string().describe('Organization name'),
+});
+
+const AdminCreateUserOrgSchema = z.object({
+  username: z.string().describe('Username who will own the organization'),
+  org_username: z.string().describe('Organization username'),
+  full_name: z.string().optional().describe('Full name of the organization'),
+  description: z.string().optional().describe('Organization description'),
+  website: z.string().optional().describe('Organization website'),
+  location: z.string().optional().describe('Organization location'),
+});
+
+const AdminCreateUserRepoSchema = z.object({
+  username: z.string().describe('Username who will own the repository'),
+  name: z.string().describe('Repository name'),
+  description: z.string().optional().describe('Repository description'),
+  private: z.boolean().optional().describe('Create as private repository (default: false)'),
+  auto_init: z.boolean().optional().describe('Initialize with README (default: false)'),
+  gitignores: z.string().optional().describe('Gitignore templates (e.g., "Go,VisualStudioCode")'),
+  license: z.string().optional().describe('License template (e.g., "MIT License")'),
+  readme: z.string().optional().describe('README template (default: "Default")'),
+});
+
 /**
  * Create and configure an MCP server with all tools and handlers
  */
@@ -2154,6 +2230,288 @@ export function createMcpServer(gogsClient: GogsClient): Server {
             required: ['text'],
           },
         },
+        {
+          name: 'admin_create_user',
+          description: '⚠️ [ADMIN ONLY] Create a new user',
+          inputSchema: {
+            type: 'object',
+            properties: {
+              source_id: {
+                type: 'number',
+                description: 'Authentication source ID (0 for local)',
+              },
+              login_name: {
+                type: 'string',
+                description: 'Login name for authentication',
+              },
+              username: {
+                type: 'string',
+                description: 'Username for the account',
+              },
+              full_name: {
+                type: 'string',
+                description: 'Full name of the user',
+              },
+              email: {
+                type: 'string',
+                description: 'Email address',
+              },
+              password: {
+                type: 'string',
+                description: 'Password for the user',
+              },
+              send_notify: {
+                type: 'boolean',
+                description: 'Send notification email to user (default: false)',
+              },
+            },
+            required: ['source_id', 'login_name', 'username', 'email', 'password'],
+          },
+        },
+        {
+          name: 'admin_edit_user',
+          description: '⚠️ [ADMIN ONLY] Edit user properties',
+          inputSchema: {
+            type: 'object',
+            properties: {
+              username: {
+                type: 'string',
+                description: 'Username of the user to edit',
+              },
+              source_id: {
+                type: 'number',
+                description: 'Authentication source ID',
+              },
+              login_name: {
+                type: 'string',
+                description: 'Login name for authentication',
+              },
+              full_name: {
+                type: 'string',
+                description: 'Full name of the user',
+              },
+              email: {
+                type: 'string',
+                description: 'Email address',
+              },
+              password: {
+                type: 'string',
+                description: 'New password',
+              },
+              website: {
+                type: 'string',
+                description: 'Website URL',
+              },
+              location: {
+                type: 'string',
+                description: 'Location',
+              },
+              active: {
+                type: 'boolean',
+                description: 'Whether the account is active',
+              },
+              admin: {
+                type: 'boolean',
+                description: 'Whether the user is an admin',
+              },
+              allow_git_hook: {
+                type: 'boolean',
+                description: 'Allow git hooks',
+              },
+              allow_import_local: {
+                type: 'boolean',
+                description: 'Allow importing local repositories',
+              },
+              max_repo_creation: {
+                type: 'number',
+                description: 'Maximum number of repositories',
+              },
+              prohibit_login: {
+                type: 'boolean',
+                description: 'Prohibit user login',
+              },
+              allow_create_organization: {
+                type: 'boolean',
+                description: 'Allow creating organizations',
+              },
+            },
+            required: ['username'],
+          },
+        },
+        {
+          name: 'admin_delete_user',
+          description: '⚠️ [ADMIN ONLY] Delete a user',
+          inputSchema: {
+            type: 'object',
+            properties: {
+              username: {
+                type: 'string',
+                description: 'Username of the user to delete',
+              },
+            },
+            required: ['username'],
+          },
+        },
+        {
+          name: 'admin_create_user_public_key',
+          description: '⚠️ [ADMIN ONLY] Create public key for user',
+          inputSchema: {
+            type: 'object',
+            properties: {
+              username: {
+                type: 'string',
+                description: 'Username to add the key to',
+              },
+              title: {
+                type: 'string',
+                description: 'Title/name for the key',
+              },
+              key: {
+                type: 'string',
+                description: 'Public key content',
+              },
+            },
+            required: ['username', 'title', 'key'],
+          },
+        },
+        {
+          name: 'admin_delete_user_public_key',
+          description: '⚠️ [ADMIN ONLY] Delete public key for user',
+          inputSchema: {
+            type: 'object',
+            properties: {
+              username: {
+                type: 'string',
+                description: 'Username to remove the key from',
+              },
+              key_id: {
+                type: 'number',
+                description: 'ID of the public key to delete',
+              },
+            },
+            required: ['username', 'key_id'],
+          },
+        },
+        {
+          name: 'admin_create_org',
+          description: '⚠️ [ADMIN ONLY] Create an organization',
+          inputSchema: {
+            type: 'object',
+            properties: {
+              username: {
+                type: 'string',
+                description: 'Organization username',
+              },
+              full_name: {
+                type: 'string',
+                description: 'Full name of the organization',
+              },
+              description: {
+                type: 'string',
+                description: 'Organization description',
+              },
+              website: {
+                type: 'string',
+                description: 'Organization website',
+              },
+              location: {
+                type: 'string',
+                description: 'Organization location',
+              },
+            },
+            required: ['username'],
+          },
+        },
+        {
+          name: 'admin_list_org_teams',
+          description: '⚠️ [ADMIN ONLY] List organization teams',
+          inputSchema: {
+            type: 'object',
+            properties: {
+              orgname: {
+                type: 'string',
+                description: 'Organization name',
+              },
+            },
+            required: ['orgname'],
+          },
+        },
+        {
+          name: 'admin_create_user_org',
+          description: '⚠️ [ADMIN ONLY] Create organization for user',
+          inputSchema: {
+            type: 'object',
+            properties: {
+              username: {
+                type: 'string',
+                description: 'Username who will own the organization',
+              },
+              org_username: {
+                type: 'string',
+                description: 'Organization username',
+              },
+              full_name: {
+                type: 'string',
+                description: 'Full name of the organization',
+              },
+              description: {
+                type: 'string',
+                description: 'Organization description',
+              },
+              website: {
+                type: 'string',
+                description: 'Organization website',
+              },
+              location: {
+                type: 'string',
+                description: 'Organization location',
+              },
+            },
+            required: ['username', 'org_username'],
+          },
+        },
+        {
+          name: 'admin_create_user_repo',
+          description: '⚠️ [ADMIN ONLY] Create repository for user',
+          inputSchema: {
+            type: 'object',
+            properties: {
+              username: {
+                type: 'string',
+                description: 'Username who will own the repository',
+              },
+              name: {
+                type: 'string',
+                description: 'Repository name',
+              },
+              description: {
+                type: 'string',
+                description: 'Repository description',
+              },
+              private: {
+                type: 'boolean',
+                description: 'Create as private repository (default: false)',
+              },
+              auto_init: {
+                type: 'boolean',
+                description: 'Initialize with README (default: false)',
+              },
+              gitignores: {
+                type: 'string',
+                description: 'Gitignore templates (e.g., "Go,VisualStudioCode")',
+              },
+              license: {
+                type: 'string',
+                description: 'License template (e.g., "MIT License")',
+              },
+              readme: {
+                type: 'string',
+                description: 'README template (default: "Default")',
+              },
+            },
+            required: ['username', 'name'],
+          },
+        },
       ],
     };
   });
@@ -3234,6 +3592,136 @@ export function createMcpServer(gogsClient: GogsClient): Server {
           };
         }
 
+        // Admin API handlers
+        case 'admin_create_user': {
+          const data = AdminCreateUserSchema.parse(args);
+          const user = await gogsClient.adminCreateUser(data);
+          return {
+            content: [
+              {
+                type: 'text',
+                text: JSON.stringify(user, null, 2),
+              },
+            ],
+          };
+        }
+
+        case 'admin_edit_user': {
+          const { username, ...data } = AdminEditUserSchema.parse(args);
+          const user = await gogsClient.adminEditUser(username, data);
+          return {
+            content: [
+              {
+                type: 'text',
+                text: JSON.stringify(user, null, 2),
+              },
+            ],
+          };
+        }
+
+        case 'admin_delete_user': {
+          const { username } = AdminDeleteUserSchema.parse(args);
+          await gogsClient.adminDeleteUser(username);
+          return {
+            content: [
+              {
+                type: 'text',
+                text: JSON.stringify({
+                  success: true,
+                  message: `Successfully deleted user ${username}`,
+                  username,
+                }, null, 2),
+              },
+            ],
+          };
+        }
+
+        case 'admin_create_user_public_key': {
+          const { username, title, key } = AdminCreateUserPublicKeySchema.parse(args);
+          const publicKey = await gogsClient.adminCreateUserPublicKey(username, { title, key });
+          return {
+            content: [
+              {
+                type: 'text',
+                text: JSON.stringify(publicKey, null, 2),
+              },
+            ],
+          };
+        }
+
+        case 'admin_delete_user_public_key': {
+          const { username, key_id } = AdminDeleteUserPublicKeySchema.parse(args);
+          await gogsClient.adminDeleteUserPublicKey(username, key_id);
+          return {
+            content: [
+              {
+                type: 'text',
+                text: JSON.stringify({
+                  success: true,
+                  message: `Successfully deleted public key ${key_id} for user ${username}`,
+                  username,
+                  key_id,
+                }, null, 2),
+              },
+            ],
+          };
+        }
+
+        case 'admin_create_org': {
+          const data = AdminCreateOrgSchema.parse(args);
+          const org = await gogsClient.adminCreateOrg(data);
+          return {
+            content: [
+              {
+                type: 'text',
+                text: JSON.stringify(org, null, 2),
+              },
+            ],
+          };
+        }
+
+        case 'admin_list_org_teams': {
+          const { orgname } = AdminListOrgTeamsSchema.parse(args);
+          const teams = await gogsClient.adminListOrgTeams(orgname);
+          return {
+            content: [
+              {
+                type: 'text',
+                text: JSON.stringify(teams, null, 2),
+              },
+            ],
+          };
+        }
+
+        case 'admin_create_user_org': {
+          const { username, org_username, ...orgData } = AdminCreateUserOrgSchema.parse(args);
+          const org = await gogsClient.adminCreateUserOrg(username, {
+            username: org_username,
+            ...orgData,
+          });
+          return {
+            content: [
+              {
+                type: 'text',
+                text: JSON.stringify(org, null, 2),
+              },
+            ],
+          };
+        }
+
+        case 'admin_create_user_repo': {
+          const { username, ...repoData } = AdminCreateUserRepoSchema.parse(args);
+          const repo = await gogsClient.adminCreateUserRepo(username, repoData);
+          return {
+            content: [
+              {
+                type: 'text',
+                text: JSON.stringify(repo, null, 2),
+              },
+            ],
+          };
+        }
+
         default:
           throw new Error(`Unknown tool: ${name}`);
       }

+ 36 - 0
src/types.ts

@@ -270,3 +270,39 @@ export interface GogsMarkdownRequest {
 export interface GogsMarkdownResponse {
   html: string;
 }
+
+// Admin API types
+export interface GogsAdminCreateUserRequest {
+  source_id: number;
+  login_name: string;
+  username: string;
+  full_name?: string;
+  email: string;
+  password: string;
+  send_notify?: boolean;
+}
+
+export interface GogsAdminEditUserRequest {
+  source_id?: number;
+  login_name?: string;
+  full_name?: string;
+  email?: string;
+  password?: string;
+  website?: string;
+  location?: string;
+  active?: boolean;
+  admin?: boolean;
+  allow_git_hook?: boolean;
+  allow_import_local?: boolean;
+  max_repo_creation?: number;
+  prohibit_login?: boolean;
+  allow_create_organization?: boolean;
+}
+
+export interface GogsAdminCreateOrgRequest {
+  username: string;
+  full_name?: string;
+  description?: string;
+  website?: string;
+  location?: string;
+}