initial go cli setup
diff --git a/cli/.gitignore b/cli/.gitignore
new file mode 100644
index 0000000..9039fed
--- /dev/null
+++ b/cli/.gitignore
@@ -0,0 +1,29 @@
+# Binaries
+/airavata
+/cli/airavata
+/bin/
+
+# Generated Thrift code
+/gen-go/
+
+# Go build artifacts
+*.exe
+*.dll
+*.so
+*.dylib
+*.test
+*.out
+
+# IDE
+.idea/
+.vscode/
+*.swp
+*.swo
+*~
+
+# macOS
+.DS_Store
+
+# Config files (contains tokens)
+config.yaml
+.airavata-cli/
diff --git a/cli/Makefile b/cli/Makefile
new file mode 100644
index 0000000..fcfd8da
--- /dev/null
+++ b/cli/Makefile
@@ -0,0 +1,112 @@
+# Airavata CLI Makefile
+
+# Variables
+THRIFT_DIR := ../thrift-interface-descriptions
+THRIFT_FILE := $(THRIFT_DIR)/airavata-service/airavata_service.thrift
+GEN_GO_DIR := gen-go
+BINARY_NAME := airavata
+BUILD_DIR := bin
+
+# Default target
+.PHONY: all
+all: generate-thrift build
+
+# Generate Go client from Thrift definitions
+.PHONY: generate-thrift
+generate-thrift:
+	@echo "Generating Go client from Thrift definitions..."
+	@if [ ! -f "$(THRIFT_FILE)" ]; then \
+		echo "Error: Thrift file not found at $(THRIFT_FILE)"; \
+		echo "Please ensure you're running from the cli/ directory"; \
+		exit 1; \
+	fi
+	@mkdir -p $(GEN_GO_DIR)
+	thrift --gen go:package_prefix=github.com/apache/airavata/cli/gen-go/ \
+		-r $(THRIFT_FILE)
+	@echo "Thrift client generated successfully"
+
+# Build the CLI binary
+.PHONY: build
+build: generate-thrift
+	@echo "Building $(BINARY_NAME)..."
+	@mkdir -p $(BUILD_DIR)
+	go build -o $(BUILD_DIR)/$(BINARY_NAME) ./cmd/airavata
+	@echo "Build completed: $(BUILD_DIR)/$(BINARY_NAME)"
+
+# Install to GOPATH/bin
+.PHONY: install
+install: build
+	@echo "Installing $(BINARY_NAME) to $(GOPATH)/bin..."
+	@cp $(BUILD_DIR)/$(BINARY_NAME) $(GOPATH)/bin/
+	@echo "Installation completed"
+
+# Run tests
+.PHONY: test
+test:
+	@echo "Running tests..."
+	go test ./...
+
+# Clean generated files and build artifacts
+.PHONY: clean
+clean:
+	@echo "Cleaning generated code and build artifacts..."
+	@rm -rf $(GEN_GO_DIR)
+	@rm -rf $(BUILD_DIR)
+	@go clean
+	@echo "Clean completed"
+
+# Format code
+.PHONY: fmt
+fmt:
+	@echo "Formatting code..."
+	go fmt ./...
+
+# Lint code
+.PHONY: lint
+lint:
+	@echo "Linting code..."
+	@if command -v golangci-lint >/dev/null 2>&1; then \
+		golangci-lint run; \
+	else \
+		echo "golangci-lint not found, skipping linting"; \
+	fi
+
+# Run the CLI (for testing)
+.PHONY: run
+run: build
+	@echo "Running $(BINARY_NAME)..."
+	@./$(BUILD_DIR)/$(BINARY_NAME) --help
+
+# Development setup
+.PHONY: dev-setup
+dev-setup:
+	@echo "Setting up development environment..."
+	@go mod download
+	@go mod tidy
+	@echo "Development setup completed"
+
+# Check if thrift is installed
+.PHONY: check-thrift
+check-thrift:
+	@if ! command -v thrift >/dev/null 2>&1; then \
+		echo "Error: Apache Thrift compiler not found"; \
+		echo "Please install thrift: https://thrift.apache.org/download"; \
+		exit 1; \
+	fi
+	@echo "Thrift compiler found: $$(thrift --version)"
+
+# Help
+.PHONY: help
+help:
+	@echo "Available targets:"
+	@echo "  generate-thrift  - Generate Go client from Thrift definitions"
+	@echo "  build           - Build the CLI binary"
+	@echo "  install         - Install to GOPATH/bin"
+	@echo "  test            - Run tests"
+	@echo "  clean           - Clean generated code and build artifacts"
+	@echo "  fmt             - Format code"
+	@echo "  lint            - Lint code"
+	@echo "  run             - Run the CLI (for testing)"
+	@echo "  dev-setup       - Set up development environment"
+	@echo "  check-thrift    - Check if Thrift compiler is installed"
+	@echo "  help            - Show this help message"
diff --git a/cli/README.md b/cli/README.md
new file mode 100644
index 0000000..40a333d
--- /dev/null
+++ b/cli/README.md
@@ -0,0 +1,845 @@
+# Airavata CLI
+
+A comprehensive command-line interface for Apache Airavata that provides access to all major Airavata services through a unified CLI tool.
+
+## Features
+
+- **Complete API Coverage**: Supports all 10 Airavata services with 300+ methods
+- **Device Authentication**: OAuth2 device authorization flow for secure authentication
+- **Multiple Output Formats**: Table, JSON, and CSV output formats
+- **Configuration Management**: Persistent configuration with automatic token refresh
+- **Service Multiplexing**: Uses TMultiplexedProtocol to access all services through a single connection
+
+## Installation
+
+### Prerequisites
+
+- Go 1.21 or later
+- Apache Thrift compiler (for building from source)
+
+### Build from Source
+
+```bash
+# Clone the repository
+git clone https://github.com/apache/airavata.git
+cd airavata/cli
+
+# Install dependencies
+go mod download
+
+# Generate Thrift client code
+make generate-thrift
+
+# Build the CLI
+make build
+
+# Install to your PATH
+make install
+```
+
+### Using Make
+
+```bash
+# Check if Thrift is installed
+make check-thrift
+
+# Generate Thrift client code
+make generate-thrift
+
+# Build the binary
+make build
+
+# Install to GOPATH/bin
+make install
+
+# Run tests
+make test
+
+# Clean generated files
+make clean
+
+# Format code
+make fmt
+
+# Lint code
+make lint
+```
+
+## Quick Start
+
+### 1. Authentication
+
+First, authenticate with your Airavata server:
+
+```bash
+airavata auth login api.scigap.org:9930
+```
+
+This will:
+1. Discover the Keycloak configuration for the server
+2. Start an OAuth2 device authorization flow
+3. Display a user code and verification URL
+4. Wait for you to complete authentication in your browser
+5. Store the authentication tokens for future use
+
+### 2. Basic Usage
+
+```bash
+# Check authentication status
+airavata auth status
+
+# List available gateways
+airavata gateway list
+
+# List projects
+airavata project list --gateway <gateway-id>
+
+# Create a new experiment
+airavata experiment create --gateway <gateway-id> --project <project-id> --name "My Experiment"
+
+# Launch an experiment
+airavata experiment launch <experiment-id>
+```
+
+### 3. Output Formats
+
+```bash
+# Table output (default)
+airavata gateway list
+
+# JSON output
+airavata gateway list --output json
+
+# CSV output
+airavata gateway list --output csv
+```
+
+## Configuration
+
+The CLI stores configuration in `~/.airavata-cli/config.yaml`:
+
+```yaml
+server:
+  hostname: api.scigap.org
+  port: 9930
+  tls: true
+auth:
+  keycloak_url: https://iam.scigap.org
+  realm: airavata
+  client_id: airavata-cli
+  access_token: <token>
+  refresh_token: <token>
+  expires_at: <timestamp>
+  username: <user>
+gateway:
+  id: default-gateway
+```
+
+## Command Reference
+
+### Authentication Commands
+
+```bash
+# Authenticate with a server
+airavata auth login <hostname:port>
+
+# Logout and clear stored tokens
+airavata auth logout
+
+# Show authentication status
+airavata auth status
+
+# Manually refresh token
+airavata auth refresh
+```
+
+### Gateway Commands
+
+```bash
+# Create a gateway
+airavata gateway create --name <name> --domain <domain>
+
+# Update a gateway
+airavata gateway update <id> --name <name>
+
+# Get gateway details
+airavata gateway get <id>
+
+# List all gateways
+airavata gateway list
+
+# Delete a gateway
+airavata gateway delete <id>
+
+# Check if gateway exists
+airavata gateway exists <id>
+```
+
+### Project Commands
+
+```bash
+# Create a project
+airavata project create --gateway <id> --name <name> --owner <user>
+
+# Update a project
+airavata project update <id> --name <name>
+
+# Get project details
+airavata project get <id>
+
+# List projects
+airavata project list --gateway <id> [--user <user>]
+
+# Delete a project
+airavata project delete <id>
+```
+
+### Experiment Commands
+
+```bash
+# Create an experiment
+airavata experiment create --gateway <id> --project <id> --name <name>
+
+# Update an experiment
+airavata experiment update <id>
+
+# Get experiment details
+airavata experiment get <id>
+
+# List experiments
+airavata experiment list --gateway <id> [--project <id>] [--user <user>]
+
+# Delete an experiment
+airavata experiment delete <id>
+
+# Launch an experiment
+airavata experiment launch <id>
+
+# Terminate an experiment
+airavata experiment terminate <id>
+
+# Clone an experiment
+airavata experiment clone <id> --new-name <name>
+
+# Validate an experiment
+airavata experiment validate <id>
+
+# Get experiment status
+airavata experiment get-status <id>
+
+# Get experiment outputs
+airavata experiment get-outputs <id>
+```
+
+### Application Commands
+
+#### Application Modules
+
+```bash
+# Create an application module
+airavata app module create --gateway <id> --name <name> --version <ver>
+
+# Update an application module
+airavata app module update <id>
+
+# Get application module details
+airavata app module get <id>
+
+# List application modules
+airavata app module list --gateway <id>
+
+# Delete an application module
+airavata app module delete <id>
+```
+
+#### Application Deployments
+
+```bash
+# Create an application deployment
+airavata app deployment create --gateway <id> --module <id> --compute <id>
+
+# Update an application deployment
+airavata app deployment update <id>
+
+# Get application deployment details
+airavata app deployment get <id>
+
+# List application deployments
+airavata app deployment list --gateway <id> [--module <id>]
+
+# Delete an application deployment
+airavata app deployment delete <id>
+```
+
+#### Application Interfaces
+
+```bash
+# Create an application interface
+airavata app interface create --gateway <id> --name <name>
+
+# Update an application interface
+airavata app interface update <id>
+
+# Get application interface details
+airavata app interface get <id>
+
+# List application interfaces
+airavata app interface list --gateway <id>
+
+# Delete an application interface
+airavata app interface delete <id>
+
+# Clone an application interface
+airavata app interface clone <id> --new-name <name>
+```
+
+### Compute Resource Commands
+
+```bash
+# Create a compute resource
+airavata compute create --name <name> --host <host>
+
+# Update a compute resource
+airavata compute update <id>
+
+# Get compute resource details
+airavata compute get <id>
+
+# List compute resources
+airavata compute list
+
+# Delete a compute resource
+airavata compute delete <id>
+
+# Add job submission interface
+airavata compute add-job-submission <id> --type <ssh|local|cloud|unicore>
+
+# Add data movement interface
+airavata compute add-data-movement <id> --type <scp|gridftp|unicore|local>
+
+# Add batch queue
+airavata compute add-batch-queue <id> --queue-name <name>
+
+# Delete batch queue
+airavata compute delete-batch-queue <id> --queue-name <name>
+```
+
+### Storage Resource Commands
+
+```bash
+# Create a storage resource
+airavata storage create --name <name> --host <host>
+
+# Update a storage resource
+airavata storage update <id>
+
+# Get storage resource details
+airavata storage get <id>
+
+# List storage resources
+airavata storage list
+
+# Delete a storage resource
+airavata storage delete <id>
+```
+
+### Credential Commands
+
+```bash
+# Add SSH credential
+airavata credential add-ssh --gateway <id> --token <id> --private-key <file>
+
+# Add password credential
+airavata credential add-password --gateway <id> --token <id> --username <user> --password <pwd>
+
+# Add certificate credential
+airavata credential add-cert --gateway <id> --token <id>
+
+# Get SSH credential
+airavata credential get-ssh <token> --gateway <id>
+
+# Get password credential
+airavata credential get-password <token> --gateway <id>
+
+# Get certificate credential
+airavata credential get-cert <token> --gateway <id>
+
+# List credentials
+airavata credential list --gateway <id> --type <ssh|password|cert>
+
+# Delete SSH credential
+airavata credential delete-ssh <token> --gateway <id>
+
+# Delete password credential
+airavata credential delete-password <token> --gateway <id>
+```
+
+### Resource Profile Commands
+
+#### Gateway Resource Profiles
+
+```bash
+# Create gateway resource profile
+airavata resource-profile gateway create <gateway-id>
+
+# Update gateway resource profile
+airavata resource-profile gateway update <gateway-id>
+
+# Get gateway resource profile
+airavata resource-profile gateway get <gateway-id>
+
+# Delete gateway resource profile
+airavata resource-profile gateway delete <gateway-id>
+
+# Add compute preference
+airavata resource-profile gateway add-compute-preference <gateway-id> --compute <id>
+
+# Add storage preference
+airavata resource-profile gateway add-storage-preference <gateway-id> --storage <id>
+```
+
+#### User Resource Profiles
+
+```bash
+# Create user resource profile
+airavata resource-profile user create --user <id> --gateway <id>
+
+# Update user resource profile
+airavata resource-profile user update --user <id> --gateway <id>
+
+# Get user resource profile
+airavata resource-profile user get --user <id> --gateway <id>
+
+# Delete user resource profile
+airavata resource-profile user delete --user <id> --gateway <id>
+
+# Add compute preference
+airavata resource-profile user add-compute-preference --user <id> --gateway <id> --compute <id>
+```
+
+#### Group Resource Profiles
+
+```bash
+# Create group resource profile
+airavata resource-profile group create --name <name>
+
+# Update group resource profile
+airavata resource-profile group update <id>
+
+# Get group resource profile
+airavata resource-profile group get <id>
+
+# Delete group resource profile
+airavata resource-profile group delete <id>
+```
+
+### Workflow Commands
+
+```bash
+# Create a workflow
+airavata workflow create --name <name> --definition <file>
+
+# Update a workflow
+airavata workflow update <id> --definition <file>
+
+# Get workflow details
+airavata workflow get <id>
+
+# List workflows
+airavata workflow list
+
+# Delete a workflow
+airavata workflow delete <id>
+
+# Check if workflow exists
+airavata workflow exists --name <name>
+```
+
+### Sharing Registry Commands
+
+#### Domain Commands
+
+```bash
+# Create a domain
+airavata sharing domain create --name <name> --description <desc>
+
+# Update a domain
+airavata sharing domain update <id>
+
+# Get domain details
+airavata sharing domain get <id>
+
+# List domains
+airavata sharing domain list
+
+# Delete a domain
+airavata sharing domain delete <id>
+```
+
+#### User Commands
+
+```bash
+# Create a user
+airavata sharing user create --domain <id> --user-id <id> --username <name>
+
+# Update a user
+airavata sharing user update --domain <id> --user-id <id>
+
+# Get user details
+airavata sharing user get --domain <id> --user-id <id>
+
+# List users
+airavata sharing user list --domain <id>
+
+# Delete a user
+airavata sharing user delete --domain <id> --user-id <id>
+```
+
+#### Group Commands
+
+```bash
+# Create a group
+airavata sharing group create --domain <id> --name <name>
+
+# Update a group
+airavata sharing group update --domain <id> --group-id <id>
+
+# Get group details
+airavata sharing group get --domain <id> --group-id <id>
+
+# List groups
+airavata sharing group list --domain <id>
+
+# Delete a group
+airavata sharing group delete --domain <id> --group-id <id>
+
+# Add users to group
+airavata sharing group add-users --domain <id> --group-id <id> --users <id1,id2>
+
+# Remove users from group
+airavata sharing group remove-users --domain <id> --group-id <id> --users <id1,id2>
+```
+
+#### Entity Commands
+
+```bash
+# Create an entity
+airavata sharing entity create --domain <id> --entity-id <id> --type <type>
+
+# Share entity with users
+airavata sharing entity share --domain <id> --entity-id <id> --users <ids> --permission <id>
+
+# Revoke entity sharing
+airavata sharing entity revoke --domain <id> --entity-id <id> --users <ids> --permission <id>
+```
+
+#### Permission Commands
+
+```bash
+# Create a permission
+airavata sharing permission create --domain <id> --name <name>
+```
+
+### Orchestrator Commands
+
+```bash
+# Launch an experiment
+airavata orchestrator launch-experiment <experiment-id> --gateway <id>
+
+# Launch a process
+airavata orchestrator launch-process <process-id> --gateway <id> --token <cred-token>
+
+# Validate an experiment
+airavata orchestrator validate-experiment <experiment-id>
+
+# Validate a process
+airavata orchestrator validate-process <experiment-id>
+
+# Terminate an experiment
+airavata orchestrator terminate-experiment <experiment-id> --gateway <id>
+```
+
+### User Profile Commands
+
+```bash
+# Initialize user profile from IAM
+airavata user-profile init
+
+# Update user profile
+airavata user-profile update --first-name <name> --last-name <name>
+
+# Get user profile
+airavata user-profile get <user-id> --gateway <id>
+
+# List user profiles
+airavata user-profile list --gateway <id> [--offset 0] [--limit 50]
+
+# Delete user profile
+airavata user-profile delete <user-id> --gateway <id>
+
+# Check if user profile exists
+airavata user-profile exists <user-id> --gateway <id>
+```
+
+### Tenant Profile Commands
+
+```bash
+# Add a gateway
+airavata tenant add-gateway --name <name> --domain <domain>
+
+# Update a gateway
+airavata tenant update-gateway <id>
+
+# Get gateway details
+airavata tenant get-gateway <id>
+
+# List all gateways
+airavata tenant list-gateways
+
+# Delete a gateway
+airavata tenant delete-gateway <id>
+
+# Check if gateway exists
+airavata tenant gateway-exists <id>
+```
+
+### IAM Admin Commands
+
+```bash
+# Set up a gateway
+airavata iam-admin setup-gateway --name <name> --domain <domain>
+
+# Register a new user
+airavata iam-admin register-user --username <user> --email <email> --first-name <fn> --last-name <ln> --password <pwd>
+
+# Get user details
+airavata iam-admin get-user <username>
+
+# List users
+airavata iam-admin list-users [--offset 0] [--limit 50] [--search <query>]
+
+# Enable a user
+airavata iam-admin enable-user <username>
+
+# Disable a user
+airavata iam-admin disable-user <username>
+
+# Delete a user
+airavata iam-admin delete-user <username>
+
+# Reset user password
+airavata iam-admin reset-password <username> --new-password <pwd>
+
+# Add role to user
+airavata iam-admin add-role <username> --role <role-name>
+
+# Remove role from user
+airavata iam-admin remove-role <username> --role <role-name>
+
+# List users with role
+airavata iam-admin list-users-with-role <role-name>
+
+# Check if username is available
+airavata iam-admin username-available <username>
+
+# Check if user exists
+airavata iam-admin user-exists <username>
+```
+
+### Group Manager Commands
+
+```bash
+# Create a group
+airavata group-manager create --name <name> --description <desc>
+
+# Update a group
+airavata group-manager update <group-id> --name <name>
+
+# Get group details
+airavata group-manager get <group-id>
+
+# List groups
+airavata group-manager list
+
+# Delete a group
+airavata group-manager delete <group-id> --owner <owner-id>
+
+# Add users to group
+airavata group-manager add-users <group-id> --users <id1,id2,...>
+
+# Remove users from group
+airavata group-manager remove-users <group-id> --users <id1,id2,...>
+
+# Transfer group ownership
+airavata group-manager transfer-ownership <group-id> --new-owner <owner-id>
+
+# Add admins to group
+airavata group-manager add-admins <group-id> --admins <id1,id2,...>
+
+# Remove admins from group
+airavata group-manager remove-admins <group-id> --admins <id1,id2,...>
+
+# List groups for user
+airavata group-manager list-user-groups <username>
+```
+
+## Global Options
+
+```bash
+# Output format (table, json, csv)
+--output, -o string
+
+# Suppress output except errors
+--quiet, -q
+
+# Verbose output
+--verbose, -v
+
+# Show help
+--help, -h
+
+# Show version
+--version
+```
+
+## Examples
+
+### Complete Workflow Example
+
+```bash
+# 1. Authenticate
+airavata auth login api.scigap.org:9930
+
+# 2. List available gateways
+airavata gateway list
+
+# 3. Create a project
+airavata project create --gateway <gateway-id> --name "My Research Project" --owner <username>
+
+# 4. List compute resources
+airavata compute list
+
+# 5. Create an experiment
+airavata experiment create --gateway <gateway-id> --project <project-id> --name "My Experiment"
+
+# 6. Launch the experiment
+airavata experiment launch <experiment-id>
+
+# 7. Check experiment status
+airavata experiment get-status <experiment-id>
+
+# 8. Get experiment outputs
+airavata experiment get-outputs <experiment-id>
+```
+
+### Batch Operations
+
+```bash
+# List all experiments in JSON format
+airavata experiment list --gateway <gateway-id> --output json
+
+# Export project list to CSV
+airavata project list --gateway <gateway-id> --output csv > projects.csv
+
+# Get detailed experiment information
+airavata experiment get <experiment-id> --output json | jq '.'
+```
+
+## Development
+
+### Project Structure
+
+```
+cli/
+├── cmd/airavata/          # Main CLI entry point
+├── pkg/
+│   ├── auth/              # Authentication (OAuth2 device flow)
+│   ├── client/             # Thrift client management
+│   ├── config/             # Configuration management
+│   ├── output/             # Output formatting (table/JSON/CSV)
+│   └── commands/           # CLI command implementations
+├── gen-go/                 # Generated Thrift client code
+├── Makefile               # Build automation
+└── README.md              # This file
+```
+
+### Adding New Commands
+
+1. Create a new command file in `pkg/commands/`
+2. Implement the command structure using Cobra
+3. Add the command to the root command in `pkg/commands/root.go`
+4. Implement the actual Thrift client calls
+5. Add tests for the new command
+
+### Regenerating Thrift Client
+
+```bash
+# Generate Go client from Thrift definitions
+make generate-thrift
+```
+
+This will:
+1. Use the Apache Thrift compiler
+2. Generate Go client code from `airavata_service.thrift`
+3. Place generated code in `gen-go/` directory
+
+### Testing
+
+```bash
+# Run all tests
+make test
+
+# Run specific package tests
+go test ./pkg/auth/...
+
+# Run with coverage
+go test -cover ./...
+```
+
+## Troubleshooting
+
+### Authentication Issues
+
+```bash
+# Check authentication status
+airavata auth status
+
+# Refresh token if expired
+airavata auth refresh
+
+# Re-authenticate if needed
+airavata auth logout
+airavata auth login <hostname:port>
+```
+
+### Connection Issues
+
+- Ensure the Airavata server is running and accessible
+- Check that the hostname:port format is correct
+- Verify network connectivity to the server
+- Check if TLS is required (most production servers use TLS)
+
+### Output Format Issues
+
+- Use `--output json` for machine-readable output
+- Use `--output table` for human-readable output
+- Use `--output csv` for spreadsheet-compatible output
+
+## Contributing
+
+1. Fork the repository
+2. Create a feature branch
+3. Make your changes
+4. Add tests for new functionality
+5. Run `make fmt` and `make lint`
+6. Submit a pull request
+
+## License
+
+Licensed under the Apache License, Version 2.0. See the LICENSE file for details.
+
+## Support
+
+- Documentation: [Airavata Documentation](https://airavata.apache.org/)
+- Issues: [GitHub Issues](https://github.com/apache/airavata/issues)
+- Mailing List: [Airavata Mailing Lists](https://airavata.apache.org/mailing-lists.html)
diff --git a/cli/cmd/airavata/main.go b/cli/cmd/airavata/main.go
new file mode 100644
index 0000000..b6ebf73
--- /dev/null
+++ b/cli/cmd/airavata/main.go
@@ -0,0 +1,31 @@
+package main
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/apache/airavata/cli/pkg/commands"
+	"github.com/spf13/cobra"
+)
+
+var (
+	version = "0.1.0"
+	build   = "dev"
+)
+
+func main() {
+	rootCmd := commands.NewRootCommand()
+
+	// Add version information
+	rootCmd.AddCommand(&cobra.Command{
+		Use:   "version",
+		Short: "Show version information",
+		Run: func(cmd *cobra.Command, args []string) {
+			fmt.Printf("Airavata CLI %s (build %s)\n", version, build)
+		},
+	})
+
+	if err := rootCmd.Execute(); err != nil {
+		os.Exit(1)
+	}
+}
diff --git a/cli/go.mod b/cli/go.mod
new file mode 100644
index 0000000..8898616
--- /dev/null
+++ b/cli/go.mod
@@ -0,0 +1,18 @@
+module github.com/apache/airavata/cli
+
+go 1.23
+
+require (
+	github.com/apache/thrift v0.22.0
+	github.com/olekukonko/tablewriter v0.0.5
+	github.com/spf13/cobra v1.8.0
+	gopkg.in/yaml.v3 v3.0.1
+)
+
+require (
+	github.com/inconshreveable/mousetrap v1.1.0 // indirect
+	github.com/kr/pretty v0.3.1 // indirect
+	github.com/mattn/go-runewidth v0.0.9 // indirect
+	github.com/spf13/pflag v1.0.5 // indirect
+	gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
+)
diff --git a/cli/go.sum b/cli/go.sum
new file mode 100644
index 0000000..5a0566a
--- /dev/null
+++ b/cli/go.sum
@@ -0,0 +1,27 @@
+github.com/apache/thrift v0.22.0 h1:r7mTJdj51TMDe6RtcmNdQxgn9XcyfGDOzegMDRg47uc=
+github.com/apache/thrift v0.22.0/go.mod h1:1e7J/O1Ae6ZQMTYdy9xa3w9k+XHWPfRvdPyJeynQ+/g=
+github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
+github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
+github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
+github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
+github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
+github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
+github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/cli/pkg/auth/auth.go b/cli/pkg/auth/auth.go
new file mode 100644
index 0000000..adf3afa
--- /dev/null
+++ b/cli/pkg/auth/auth.go
@@ -0,0 +1,229 @@
+package auth
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"strings"
+	"time"
+)
+
+// DeviceAuthResponse represents the response from device authorization endpoint
+type DeviceAuthResponse struct {
+	DeviceCode              string `json:"device_code"`
+	UserCode                string `json:"user_code"`
+	VerificationURI         string `json:"verification_uri"`
+	VerificationURIComplete string `json:"verification_uri_complete,omitempty"`
+	ExpiresIn               int    `json:"expires_in"`
+	Interval                int    `json:"interval"`
+}
+
+// TokenResponse represents the response from token endpoint
+type TokenResponse struct {
+	AccessToken  string `json:"access_token"`
+	RefreshToken string `json:"refresh_token"`
+	ExpiresIn    int    `json:"expires_in"`
+	TokenType    string `json:"token_type"`
+}
+
+// UserInfo represents user information from token
+type UserInfo struct {
+	Username  string `json:"preferred_username"`
+	Email     string `json:"email"`
+	FirstName string `json:"given_name"`
+	LastName  string `json:"family_name"`
+}
+
+// AuthManager handles OAuth2 device flow authentication
+type AuthManager struct {
+	keycloakURL string
+	realm       string
+	clientID    string
+	httpClient  *http.Client
+}
+
+// NewAuthManager creates a new authentication manager
+func NewAuthManager(keycloakURL, realm, clientID string) *AuthManager {
+	return &AuthManager{
+		keycloakURL: keycloakURL,
+		realm:       realm,
+		clientID:    clientID,
+		httpClient:  &http.Client{Timeout: 30 * time.Second},
+	}
+}
+
+// StartDeviceAuth initiates the device authorization flow
+func (am *AuthManager) StartDeviceAuth() (*DeviceAuthResponse, error) {
+	deviceURL := fmt.Sprintf("%s/realms/%s/protocol/openid-connect/auth/device",
+		am.keycloakURL, am.realm)
+
+	data := url.Values{}
+	data.Set("client_id", am.clientID)
+
+	req, err := http.NewRequest("POST", deviceURL, strings.NewReader(data.Encode()))
+	if err != nil {
+		return nil, fmt.Errorf("failed to create device auth request: %w", err)
+	}
+
+	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+
+	resp, err := am.httpClient.Do(req)
+	if err != nil {
+		return nil, fmt.Errorf("failed to make device auth request: %w", err)
+	}
+	defer resp.Body.Close()
+
+	if resp.StatusCode != http.StatusOK {
+		body, _ := io.ReadAll(resp.Body)
+		return nil, fmt.Errorf("device auth failed with status %d: %s", resp.StatusCode, string(body))
+	}
+
+	var deviceResp DeviceAuthResponse
+	if err := json.NewDecoder(resp.Body).Decode(&deviceResp); err != nil {
+		return nil, fmt.Errorf("failed to decode device auth response: %w", err)
+	}
+
+	return &deviceResp, nil
+}
+
+// PollForToken polls the token endpoint until user completes authorization
+func (am *AuthManager) PollForToken(deviceCode string, interval time.Duration) (*TokenResponse, error) {
+	tokenURL := fmt.Sprintf("%s/realms/%s/protocol/openid-connect/token",
+		am.keycloakURL, am.realm)
+
+	data := url.Values{}
+	data.Set("grant_type", "urn:ietf:params:oauth:grant-type:device_code")
+	data.Set("client_id", am.clientID)
+	data.Set("device_code", deviceCode)
+
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
+	defer cancel()
+
+	ticker := time.NewTicker(interval)
+	defer ticker.Stop()
+
+	for {
+		select {
+		case <-ctx.Done():
+			return nil, fmt.Errorf("device auth timed out")
+		case <-ticker.C:
+			token, err := am.requestToken(tokenURL, data)
+			if err == nil {
+				return token, nil
+			}
+
+			// Check if it's a "slow_down" or "authorization_pending" error
+			if strings.Contains(err.Error(), "slow_down") {
+				// Increase polling interval
+				interval = time.Duration(float64(interval) * 1.5)
+				ticker.Reset(interval)
+			} else if !strings.Contains(err.Error(), "authorization_pending") {
+				return nil, err
+			}
+		}
+	}
+}
+
+// requestToken makes a request to the token endpoint
+func (am *AuthManager) requestToken(tokenURL string, data url.Values) (*TokenResponse, error) {
+	req, err := http.NewRequest("POST", tokenURL, strings.NewReader(data.Encode()))
+	if err != nil {
+		return nil, fmt.Errorf("failed to create token request: %w", err)
+	}
+
+	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+
+	resp, err := am.httpClient.Do(req)
+	if err != nil {
+		return nil, fmt.Errorf("failed to make token request: %w", err)
+	}
+	defer resp.Body.Close()
+
+	if resp.StatusCode != http.StatusOK {
+		body, _ := io.ReadAll(resp.Body)
+		return nil, fmt.Errorf("token request failed with status %d: %s", resp.StatusCode, string(body))
+	}
+
+	var tokenResp TokenResponse
+	if err := json.NewDecoder(resp.Body).Decode(&tokenResp); err != nil {
+		return nil, fmt.Errorf("failed to decode token response: %w", err)
+	}
+
+	return &tokenResp, nil
+}
+
+// GetUserInfo retrieves user information from the access token
+func (am *AuthManager) GetUserInfo(accessToken string) (*UserInfo, error) {
+	userInfoURL := fmt.Sprintf("%s/realms/%s/protocol/openid-connect/userinfo",
+		am.keycloakURL, am.realm)
+
+	req, err := http.NewRequest("GET", userInfoURL, nil)
+	if err != nil {
+		return nil, fmt.Errorf("failed to create userinfo request: %w", err)
+	}
+
+	req.Header.Set("Authorization", "Bearer "+accessToken)
+
+	resp, err := am.httpClient.Do(req)
+	if err != nil {
+		return nil, fmt.Errorf("failed to make userinfo request: %w", err)
+	}
+	defer resp.Body.Close()
+
+	if resp.StatusCode != http.StatusOK {
+		body, _ := io.ReadAll(resp.Body)
+		return nil, fmt.Errorf("userinfo request failed with status %d: %s", resp.StatusCode, string(body))
+	}
+
+	var userInfo UserInfo
+	if err := json.NewDecoder(resp.Body).Decode(&userInfo); err != nil {
+		return nil, fmt.Errorf("failed to decode userinfo response: %w", err)
+	}
+
+	return &userInfo, nil
+}
+
+// RefreshToken refreshes an access token using the refresh token
+func (am *AuthManager) RefreshToken(refreshToken string) (*TokenResponse, error) {
+	tokenURL := fmt.Sprintf("%s/realms/%s/protocol/openid-connect/token",
+		am.keycloakURL, am.realm)
+
+	data := url.Values{}
+	data.Set("grant_type", "refresh_token")
+	data.Set("client_id", am.clientID)
+	data.Set("refresh_token", refreshToken)
+
+	return am.requestToken(tokenURL, data)
+}
+
+// DiscoverKeycloakInfo discovers Keycloak configuration from server
+func DiscoverKeycloakInfo(serverHostname string) (string, string, error) {
+	// Try common Keycloak discovery patterns
+	possibleURLs := []string{
+		fmt.Sprintf("https://%s/auth", serverHostname),
+		fmt.Sprintf("https://%s/realms/airavata", serverHostname),
+		fmt.Sprintf("https://iam.%s", serverHostname),
+		fmt.Sprintf("https://%s:8080/auth", serverHostname),
+	}
+
+	httpClient := &http.Client{Timeout: 10 * time.Second}
+
+	for _, baseURL := range possibleURLs {
+		// Try to find realm info
+		realmURL := fmt.Sprintf("%s/realms/airavata", baseURL)
+		resp, err := httpClient.Get(realmURL)
+		if err == nil && resp.StatusCode == http.StatusOK {
+			resp.Body.Close()
+			return baseURL, "airavata", nil
+		}
+		if resp != nil {
+			resp.Body.Close()
+		}
+	}
+
+	// Default fallback
+	return fmt.Sprintf("https://iam.%s", serverHostname), "airavata", nil
+}
diff --git a/cli/pkg/client/client.go b/cli/pkg/client/client.go
new file mode 100644
index 0000000..5455c06
--- /dev/null
+++ b/cli/pkg/client/client.go
@@ -0,0 +1,88 @@
+package client
+
+import (
+	"fmt"
+	"time"
+
+	"github.com/apache/thrift/lib/go/thrift"
+)
+
+// ClientManager manages Thrift client connections
+type ClientManager struct {
+	serverAddress string
+	transport     thrift.TTransport
+	protocol      thrift.TProtocol
+}
+
+// NewClientManager creates a new client manager
+func NewClientManager(serverAddress string) *ClientManager {
+	return &ClientManager{
+		serverAddress: serverAddress,
+	}
+}
+
+// Connect establishes a connection to the Airavata server
+func (cm *ClientManager) Connect() error {
+	// Create socket transport
+	transport := thrift.NewTSocketConf(cm.serverAddress, &thrift.TConfiguration{
+		ConnectTimeout: 30 * time.Second,
+		SocketTimeout:  30 * time.Second,
+	})
+
+	// Open transport
+	if err := transport.Open(); err != nil {
+		return fmt.Errorf("failed to open transport: %w", err)
+	}
+
+	// Create binary protocol
+	protocol := thrift.NewTBinaryProtocolTransport(transport)
+
+	cm.transport = transport
+	cm.protocol = protocol
+
+	return nil
+}
+
+// Close closes the connection
+func (cm *ClientManager) Close() error {
+	if cm.transport != nil {
+		return cm.transport.Close()
+	}
+	return nil
+}
+
+// GetProtocol returns the protocol for creating clients
+func (cm *ClientManager) GetProtocol() thrift.TProtocol {
+	return cm.protocol
+}
+
+// IsConnected checks if the client is connected
+func (cm *ClientManager) IsConnected() bool {
+	return cm.transport != nil && cm.transport.IsOpen()
+}
+
+// Reconnect reconnects to the server
+func (cm *ClientManager) Reconnect() error {
+	if cm.transport != nil {
+		cm.transport.Close()
+	}
+	return cm.Connect()
+}
+
+// GetMultiplexedProtocol creates a multiplexed protocol for a specific service
+func (cm *ClientManager) GetMultiplexedProtocol(serviceName string) (thrift.TProtocol, error) {
+	if !cm.IsConnected() {
+		if err := cm.Connect(); err != nil {
+			return nil, fmt.Errorf("failed to connect: %w", err)
+		}
+	}
+
+	// Create multiplexed protocol for the specific service
+	multiplexedProtocol := thrift.NewTMultiplexedProtocol(cm.protocol, serviceName)
+	return multiplexedProtocol, nil
+}
+
+// GetTransport returns the underlying transport
+func (cm *ClientManager) GetTransport() thrift.TTransport {
+	return cm.transport
+}
diff --git a/cli/pkg/commands/application.go b/cli/pkg/commands/application.go
new file mode 100644
index 0000000..5913968
--- /dev/null
+++ b/cli/pkg/commands/application.go
@@ -0,0 +1,631 @@
+package commands
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/apache/airavata/cli/gen-go/airavata_api"
+	"github.com/apache/airavata/cli/gen-go/security_model"
+	"github.com/apache/airavata/cli/pkg/client"
+	"github.com/spf13/cobra"
+)
+
+// NewApplicationCommand creates the application command
+func NewApplicationCommand() *cobra.Command {
+	appCmd := &cobra.Command{
+		Use:   "app",
+		Short: "Application management commands",
+		Long:  "Manage Airavata applications (modules, deployments, interfaces)",
+	}
+
+	// Application Modules
+	moduleCmd := &cobra.Command{
+		Use:   "module",
+		Short: "Application module commands",
+	}
+	moduleCmd.AddCommand(NewAppModuleCreateCommand())
+	moduleCmd.AddCommand(NewAppModuleUpdateCommand())
+	moduleCmd.AddCommand(NewAppModuleGetCommand())
+	moduleCmd.AddCommand(NewAppModuleListCommand())
+	moduleCmd.AddCommand(NewAppModuleDeleteCommand())
+
+	// Application Deployments
+	deploymentCmd := &cobra.Command{
+		Use:   "deployment",
+		Short: "Application deployment commands",
+	}
+	deploymentCmd.AddCommand(NewAppDeploymentCreateCommand())
+	deploymentCmd.AddCommand(NewAppDeploymentUpdateCommand())
+	deploymentCmd.AddCommand(NewAppDeploymentGetCommand())
+	deploymentCmd.AddCommand(NewAppDeploymentListCommand())
+	deploymentCmd.AddCommand(NewAppDeploymentDeleteCommand())
+
+	// Application Interfaces
+	interfaceCmd := &cobra.Command{
+		Use:   "interface",
+		Short: "Application interface commands",
+	}
+	interfaceCmd.AddCommand(NewAppInterfaceCreateCommand())
+	interfaceCmd.AddCommand(NewAppInterfaceUpdateCommand())
+	interfaceCmd.AddCommand(NewAppInterfaceGetCommand())
+	interfaceCmd.AddCommand(NewAppInterfaceListCommand())
+	interfaceCmd.AddCommand(NewAppInterfaceDeleteCommand())
+	interfaceCmd.AddCommand(NewAppInterfaceCloneCommand())
+
+	appCmd.AddCommand(moduleCmd)
+	appCmd.AddCommand(deploymentCmd)
+	appCmd.AddCommand(interfaceCmd)
+
+	return appCmd
+}
+
+// Application Module Commands
+func NewAppModuleCreateCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "create --gateway <id> --name <name> --version <ver>",
+		Short: "Create a new application module",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("app module create not yet implemented")
+		},
+	}
+}
+
+func NewAppModuleUpdateCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "update <id>",
+		Short: "Update an application module",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("app module update not yet implemented")
+		},
+	}
+}
+
+func NewAppModuleGetCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "get <id>",
+		Short: "Get application module details",
+		Long:  "Get detailed information about a specific application module",
+		Args:  cobra.ExactArgs(1),
+		RunE:  runAppModuleGet,
+	}
+}
+
+func runAppModuleGet(cmd *cobra.Command, args []string) error {
+	moduleID := args[0]
+
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetApplicationModule
+	ctx := context.Background()
+	module, err := airavataClient.GetApplicationModule(ctx, authzToken, moduleID)
+	if err != nil {
+		return fmt.Errorf("failed to get application module: %w", err)
+	}
+
+	// Format output
+	outputData := map[string]interface{}{
+		"ID":          module.GetAppModuleId(),
+		"Name":        module.GetAppModuleName(),
+		"Version":     module.GetAppModuleVersion(),
+		"Description": module.GetAppModuleDescription(),
+	}
+
+	// Display results
+	headers := []string{"Field", "Value"}
+	var rows [][]string
+	for key, value := range outputData {
+		rows = append(rows, []string{key, fmt.Sprintf("%v", value)})
+	}
+
+	return formatter.Write(rows, headers)
+}
+
+func NewAppModuleListCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "list",
+		Short: "List application modules",
+		Long:  "List all available application modules",
+		RunE:  runAppModuleList,
+	}
+}
+
+func runAppModuleList(cmd *cobra.Command, args []string) error {
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetAllAppModules
+	ctx := context.Background()
+	modules, err := airavataClient.GetAllAppModules(ctx, authzToken, cfg.Gateway.ID)
+	if err != nil {
+		return fmt.Errorf("failed to get application modules: %w", err)
+	}
+
+	// Format output
+	if len(modules) == 0 {
+		fmt.Println("No application modules found")
+		return nil
+	}
+
+	// Convert to output format
+	var outputData []map[string]interface{}
+	for _, module := range modules {
+		outputData = append(outputData, map[string]interface{}{
+			"ID":          module.GetAppModuleId(),
+			"Name":        module.GetAppModuleName(),
+			"Version":     module.GetAppModuleVersion(),
+			"Description": module.GetAppModuleDescription(),
+		})
+	}
+
+	// Display results
+	headers := []string{"ID", "Name", "Version", "Description"}
+	return formatter.Write(outputData, headers)
+}
+
+func NewAppModuleDeleteCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "delete <id>",
+		Short: "Delete an application module",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("app module delete not yet implemented")
+		},
+	}
+}
+
+// Application Deployment Commands
+func NewAppDeploymentCreateCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "create --gateway <id> --module <id> --compute <id>",
+		Short: "Create a new application deployment",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("app deployment create not yet implemented")
+		},
+	}
+}
+
+func NewAppDeploymentUpdateCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "update <id>",
+		Short: "Update an application deployment",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("app deployment update not yet implemented")
+		},
+	}
+}
+
+func NewAppDeploymentGetCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "get <id>",
+		Short: "Get application deployment details",
+		Long:  "Get detailed information about a specific application deployment",
+		Args:  cobra.ExactArgs(1),
+		RunE:  runAppDeploymentGet,
+	}
+}
+
+func runAppDeploymentGet(cmd *cobra.Command, args []string) error {
+	deploymentID := args[0]
+
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetApplicationDeployment
+	ctx := context.Background()
+	deployment, err := airavataClient.GetApplicationDeployment(ctx, authzToken, deploymentID)
+	if err != nil {
+		return fmt.Errorf("failed to get application deployment: %w", err)
+	}
+
+	// Format output
+	outputData := map[string]interface{}{
+		"ID":          deployment.GetAppDeploymentId(),
+		"Module":      deployment.GetAppModuleId(),
+		"Description": deployment.GetAppDeploymentDescription(),
+	}
+
+	// Display results
+	headers := []string{"Field", "Value"}
+	var rows [][]string
+	for key, value := range outputData {
+		rows = append(rows, []string{key, fmt.Sprintf("%v", value)})
+	}
+
+	return formatter.Write(rows, headers)
+}
+
+func NewAppDeploymentListCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "list",
+		Short: "List application deployments",
+		Long:  "List all available application deployments",
+		RunE:  runAppDeploymentList,
+	}
+}
+
+func runAppDeploymentList(cmd *cobra.Command, args []string) error {
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetAllApplicationDeployments
+	ctx := context.Background()
+	deployments, err := airavataClient.GetAllApplicationDeployments(ctx, authzToken, cfg.Gateway.ID)
+	if err != nil {
+		return fmt.Errorf("failed to get application deployments: %w", err)
+	}
+
+	// Format output
+	if len(deployments) == 0 {
+		fmt.Println("No application deployments found")
+		return nil
+	}
+
+	// Convert to output format
+	var outputData []map[string]interface{}
+	for _, deployment := range deployments {
+		outputData = append(outputData, map[string]interface{}{
+			"ID":          deployment.GetAppDeploymentId(),
+			"Module":      deployment.GetAppModuleId(),
+			"Description": deployment.GetAppDeploymentDescription(),
+		})
+	}
+
+	// Display results
+	headers := []string{"ID", "Module", "Description"}
+	return formatter.Write(outputData, headers)
+}
+
+func NewAppDeploymentDeleteCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "delete <id>",
+		Short: "Delete an application deployment",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("app deployment delete not yet implemented")
+		},
+	}
+}
+
+// Application Interface Commands
+func NewAppInterfaceCreateCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "create --gateway <id> --name <name>",
+		Short: "Create a new application interface",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("app interface create not yet implemented")
+		},
+	}
+}
+
+func NewAppInterfaceUpdateCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "update <id>",
+		Short: "Update an application interface",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("app interface update not yet implemented")
+		},
+	}
+}
+
+func NewAppInterfaceGetCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "get <id>",
+		Short: "Get application interface details",
+		Long:  "Get detailed information about a specific application interface",
+		Args:  cobra.ExactArgs(1),
+		RunE:  runAppInterfaceGet,
+	}
+}
+
+func runAppInterfaceGet(cmd *cobra.Command, args []string) error {
+	interfaceID := args[0]
+
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetApplicationInterface
+	ctx := context.Background()
+	iface, err := airavataClient.GetApplicationInterface(ctx, authzToken, interfaceID)
+	if err != nil {
+		return fmt.Errorf("failed to get application interface: %w", err)
+	}
+
+	// Format output
+	outputData := map[string]interface{}{
+		"ID":          iface.GetApplicationInterfaceId(),
+		"Name":        iface.GetApplicationName(),
+		"Description": iface.GetApplicationDescription(),
+	}
+
+	// Display results
+	headers := []string{"Field", "Value"}
+	var rows [][]string
+	for key, value := range outputData {
+		rows = append(rows, []string{key, fmt.Sprintf("%v", value)})
+	}
+
+	return formatter.Write(rows, headers)
+}
+
+func NewAppInterfaceListCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "list",
+		Short: "List application interfaces",
+		Long:  "List all available application interfaces",
+		RunE:  runAppInterfaceList,
+	}
+}
+
+func runAppInterfaceList(cmd *cobra.Command, args []string) error {
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetAllApplicationInterfaces
+	ctx := context.Background()
+	interfaces, err := airavataClient.GetAllApplicationInterfaces(ctx, authzToken, cfg.Gateway.ID)
+	if err != nil {
+		return fmt.Errorf("failed to get application interfaces: %w", err)
+	}
+
+	// Format output
+	if len(interfaces) == 0 {
+		fmt.Println("No application interfaces found")
+		return nil
+	}
+
+	// Convert to output format
+	var outputData []map[string]interface{}
+	for _, iface := range interfaces {
+		outputData = append(outputData, map[string]interface{}{
+			"ID":          iface.GetApplicationInterfaceId(),
+			"Name":        iface.GetApplicationName(),
+			"Description": iface.GetApplicationDescription(),
+		})
+	}
+
+	// Display results
+	headers := []string{"ID", "Name", "Description"}
+	return formatter.Write(outputData, headers)
+}
+
+func NewAppInterfaceDeleteCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "delete <id>",
+		Short: "Delete an application interface",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("app interface delete not yet implemented")
+		},
+	}
+}
+
+func NewAppInterfaceCloneCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "clone <id> --new-name <name>",
+		Short: "Clone an application interface",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("app interface clone not yet implemented")
+		},
+	}
+}
diff --git a/cli/pkg/commands/auth.go b/cli/pkg/commands/auth.go
new file mode 100644
index 0000000..61a2669
--- /dev/null
+++ b/cli/pkg/commands/auth.go
@@ -0,0 +1,271 @@
+package commands
+
+import (
+	"fmt"
+	"strings"
+	"time"
+
+	"github.com/apache/airavata/cli/pkg/auth"
+	"github.com/apache/airavata/cli/pkg/config"
+	"github.com/spf13/cobra"
+)
+
+// NewAuthCommand creates the auth command
+func NewAuthCommand() *cobra.Command {
+	authCmd := &cobra.Command{
+		Use:   "auth",
+		Short: "Authentication commands",
+		Long:  "Manage authentication with Airavata server",
+	}
+
+	authCmd.AddCommand(NewAuthLoginCommand())
+	authCmd.AddCommand(NewAuthLogoutCommand())
+	authCmd.AddCommand(NewAuthStatusCommand())
+	authCmd.AddCommand(NewAuthRefreshCommand())
+
+	return authCmd
+}
+
+// NewAuthLoginCommand creates the login command
+func NewAuthLoginCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "login <hostname:port>",
+		Short: "Authenticate with Airavata server using device flow",
+		Long: `Authenticate with an Airavata server using OAuth2 device authorization flow.
+
+This command will:
+1. Connect to the specified Airavata server
+2. Initiate OAuth2 device authorization flow
+3. Display a user code and verification URL
+4. Wait for you to complete authentication in your browser
+5. Store the authentication tokens for future use
+
+Examples:
+  airavata auth login api.scigap.org:9930
+  airavata auth login localhost:9930
+  airavata auth login 192.168.1.100:9930`,
+		Args: cobra.ExactArgs(1),
+		RunE: runAuthLogin,
+	}
+}
+
+// NewAuthLogoutCommand creates the logout command
+func NewAuthLogoutCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "logout",
+		Short: "Clear stored authentication tokens",
+		Long:  "Remove stored authentication tokens and server configuration",
+		RunE:  runAuthLogout,
+	}
+}
+
+// NewAuthStatusCommand creates the status command
+func NewAuthStatusCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "status",
+		Short: "Show authentication status",
+		Long:  "Display current authentication status and server information",
+		RunE:  runAuthStatus,
+	}
+}
+
+// NewAuthRefreshCommand creates the refresh command
+func NewAuthRefreshCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "refresh",
+		Short: "Refresh authentication token",
+		Long:  "Manually refresh the stored authentication token",
+		RunE:  runAuthRefresh,
+	}
+}
+
+func runAuthLogin(cmd *cobra.Command, args []string) error {
+	serverArg := args[0]
+
+	// Parse hostname:port
+	parts := strings.Split(serverArg, ":")
+	if len(parts) != 2 {
+		return fmt.Errorf("invalid server format. Expected hostname:port, got: %s", serverArg)
+	}
+
+	hostname := parts[0]
+	port := parts[1]
+
+	// Validate hostname and port
+	if hostname == "" {
+		return fmt.Errorf("hostname cannot be empty")
+	}
+	if port == "" {
+		return fmt.Errorf("port cannot be empty")
+	}
+
+	// Discover Keycloak configuration
+	fmt.Printf("Discovering Keycloak configuration for %s...\n", serverArg)
+	keycloakURL, realm, err := auth.DiscoverKeycloakInfo(hostname)
+	if err != nil {
+		return fmt.Errorf("failed to discover Keycloak configuration: %w", err)
+	}
+
+	fmt.Printf("Found Keycloak at: %s (realm: %s)\n", keycloakURL, realm)
+
+	// Create auth manager
+	authManager := auth.NewAuthManager(keycloakURL, realm, "airavata-cli")
+
+	// Start device auth flow
+	fmt.Println("Starting device authorization flow...")
+	deviceResp, err := authManager.StartDeviceAuth()
+	if err != nil {
+		return fmt.Errorf("failed to start device auth: %w", err)
+	}
+
+	// Display instructions to user
+	fmt.Println("\n" + strings.Repeat("=", 60))
+	fmt.Println("DEVICE AUTHORIZATION REQUIRED")
+	fmt.Println(strings.Repeat("=", 60))
+	fmt.Printf("1. Open your browser and go to: %s\n", deviceResp.VerificationURI)
+	fmt.Printf("2. Enter the following code: %s\n", deviceResp.UserCode)
+	fmt.Println("3. Complete the authentication in your browser")
+	fmt.Println("4. This window will automatically continue once authenticated")
+	fmt.Println(strings.Repeat("=", 60))
+	fmt.Println()
+
+	// Poll for token
+	fmt.Println("Waiting for authentication...")
+	interval := time.Duration(deviceResp.Interval) * time.Second
+	if interval == 0 {
+		interval = 5 * time.Second
+	}
+
+	tokenResp, err := authManager.PollForToken(deviceResp.DeviceCode, interval)
+	if err != nil {
+		return fmt.Errorf("failed to get token: %w", err)
+	}
+
+	// Get user info
+	fmt.Println("Getting user information...")
+	userInfo, err := authManager.GetUserInfo(tokenResp.AccessToken)
+	if err != nil {
+		return fmt.Errorf("failed to get user info: %w", err)
+	}
+
+	// Create configuration
+	cfg := config.DefaultConfig()
+	cfg.Server.Hostname = hostname
+	cfg.Server.Port = 9930 // Default port, could be parsed from port
+	cfg.Server.TLS = true  // Assume TLS for production servers
+
+	cfg.Auth.KeycloakURL = keycloakURL
+	cfg.Auth.Realm = realm
+	cfg.Auth.AccessToken = tokenResp.AccessToken
+	cfg.Auth.RefreshToken = tokenResp.RefreshToken
+	cfg.Auth.ExpiresAt = time.Now().Add(time.Duration(tokenResp.ExpiresIn) * time.Second)
+	cfg.Auth.Username = userInfo.Username
+
+	// Save configuration
+	if err := configManager.Save(cfg); err != nil {
+		return fmt.Errorf("failed to save configuration: %w", err)
+	}
+
+	// Success message
+	fmt.Println("✅ Authentication successful!")
+	fmt.Printf("Logged in as: %s (%s)\n", userInfo.Username, userInfo.Email)
+	fmt.Printf("Server: %s\n", serverArg)
+	fmt.Printf("Token expires: %s\n", cfg.Auth.ExpiresAt.Format(time.RFC3339))
+
+	return nil
+}
+
+func runAuthLogout(cmd *cobra.Command, args []string) error {
+	// Load current config to show what we're logging out from
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	if cfg.Auth.Username == "" {
+		fmt.Println("Not currently authenticated")
+		return nil
+	}
+
+	// Clear configuration
+	if err := configManager.Clear(); err != nil {
+		return fmt.Errorf("failed to clear configuration: %w", err)
+	}
+
+	fmt.Printf("✅ Logged out from %s (user: %s)\n",
+		fmt.Sprintf("%s:%d", cfg.Server.Hostname, cfg.Server.Port),
+		cfg.Auth.Username)
+
+	return nil
+}
+
+func runAuthStatus(cmd *cobra.Command, args []string) error {
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	if !configManager.IsAuthenticated() {
+		fmt.Println("❌ Not authenticated")
+		fmt.Println("Run 'airavata auth login <hostname:port>' to authenticate")
+		return nil
+	}
+
+	// Show status
+	fmt.Println("✅ Authenticated")
+	fmt.Printf("User: %s\n", cfg.Auth.Username)
+	fmt.Printf("Server: %s:%d\n", cfg.Server.Hostname, cfg.Server.Port)
+	fmt.Printf("Keycloak: %s\n", cfg.Auth.KeycloakURL)
+	fmt.Printf("Realm: %s\n", cfg.Auth.Realm)
+	fmt.Printf("Token expires: %s\n", cfg.Auth.ExpiresAt.Format(time.RFC3339))
+
+	// Check if token is close to expiry
+	timeUntilExpiry := time.Until(cfg.Auth.ExpiresAt)
+	if timeUntilExpiry < 5*time.Minute {
+		fmt.Println("⚠️  Token expires soon, consider running 'airavata auth refresh'")
+	}
+
+	return nil
+}
+
+func runAuthRefresh(cmd *cobra.Command, args []string) error {
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	if !configManager.IsAuthenticated() {
+		return fmt.Errorf("not authenticated")
+	}
+
+	if cfg.Auth.RefreshToken == "" {
+		return fmt.Errorf("no refresh token available")
+	}
+
+	// Create auth manager
+	authManager := auth.NewAuthManager(cfg.Auth.KeycloakURL, cfg.Auth.Realm, cfg.Auth.ClientID)
+
+	// Refresh token
+	fmt.Println("Refreshing authentication token...")
+	tokenResp, err := authManager.RefreshToken(cfg.Auth.RefreshToken)
+	if err != nil {
+		return fmt.Errorf("failed to refresh token: %w", err)
+	}
+
+	// Update configuration
+	cfg.Auth.AccessToken = tokenResp.AccessToken
+	if tokenResp.RefreshToken != "" {
+		cfg.Auth.RefreshToken = tokenResp.RefreshToken
+	}
+	cfg.Auth.ExpiresAt = time.Now().Add(time.Duration(tokenResp.ExpiresIn) * time.Second)
+
+	// Save configuration
+	if err := configManager.Save(cfg); err != nil {
+		return fmt.Errorf("failed to save refreshed configuration: %w", err)
+	}
+
+	fmt.Println("✅ Token refreshed successfully")
+	fmt.Printf("New expiry: %s\n", cfg.Auth.ExpiresAt.Format(time.RFC3339))
+
+	return nil
+}
diff --git a/cli/pkg/commands/compute.go b/cli/pkg/commands/compute.go
new file mode 100644
index 0000000..37ef500
--- /dev/null
+++ b/cli/pkg/commands/compute.go
@@ -0,0 +1,195 @@
+package commands
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/apache/airavata/cli/gen-go/airavata_api"
+	"github.com/apache/airavata/cli/gen-go/security_model"
+	"github.com/apache/airavata/cli/pkg/client"
+	"github.com/spf13/cobra"
+)
+
+func NewComputeCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "compute",
+		Short: "Compute resource management commands",
+		Long:  "Manage compute resources (create, update, delete, get, list)",
+	}
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "create --name <name> --host <host>",
+		Short: "Create a compute resource",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("compute create not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "update <id>",
+		Short: "Update a compute resource",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("compute update not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "get <id>",
+		Short: "Get compute resource details",
+		Long:  "Get detailed information about a specific compute resource",
+		Args:  cobra.ExactArgs(1),
+		RunE:  runComputeGet,
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "list",
+		Short: "List compute resources",
+		Long:  "List all available compute resources",
+		RunE:  runComputeList,
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "delete <id>",
+		Short: "Delete a compute resource",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("compute delete not yet implemented")
+		},
+	})
+
+	return cmd
+}
+
+func runComputeList(cmd *cobra.Command, args []string) error {
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetAllComputeResourceNames
+	ctx := context.Background()
+	resourceNames, err := airavataClient.GetAllComputeResourceNames(ctx, authzToken)
+	if err != nil {
+		return fmt.Errorf("failed to get compute resources: %w", err)
+	}
+
+	// Format output
+	if len(resourceNames) == 0 {
+		fmt.Println("No compute resources found")
+		return nil
+	}
+
+	// Convert to output format
+	var outputData []map[string]interface{}
+	for id, name := range resourceNames {
+		outputData = append(outputData, map[string]interface{}{
+			"ID":   id,
+			"Name": name,
+		})
+	}
+
+	// Display results
+	headers := []string{"ID", "Name"}
+	return formatter.Write(outputData, headers)
+}
+
+func runComputeGet(cmd *cobra.Command, args []string) error {
+	resourceID := args[0]
+
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetComputeResource
+	ctx := context.Background()
+	resource, err := airavataClient.GetComputeResource(ctx, authzToken, resourceID)
+	if err != nil {
+		return fmt.Errorf("failed to get compute resource: %w", err)
+	}
+
+	// Format output
+	outputData := map[string]interface{}{
+		"ID":          resource.GetComputeResourceId(),
+		"Name":        resource.GetHostName(),
+		"Description": resource.GetResourceDescription(),
+	}
+
+	// Display results
+	headers := []string{"Field", "Value"}
+	var rows [][]string
+	for key, value := range outputData {
+		rows = append(rows, []string{key, fmt.Sprintf("%v", value)})
+	}
+
+	return formatter.Write(rows, headers)
+}
diff --git a/cli/pkg/commands/credential.go b/cli/pkg/commands/credential.go
new file mode 100644
index 0000000..03bfc2c
--- /dev/null
+++ b/cli/pkg/commands/credential.go
@@ -0,0 +1,94 @@
+package commands
+
+import (
+	"fmt"
+
+	"github.com/spf13/cobra"
+)
+
+func NewCredentialCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "credential",
+		Short: "Credential management commands",
+		Long:  "Manage credentials (SSH, password, certificate)",
+	}
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "add-ssh --gateway <id> --token <id> --private-key <file>",
+		Short: "Add SSH credential",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("credential add-ssh not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "add-password --gateway <id> --token <id> --username <user> --password <pwd>",
+		Short: "Add password credential",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("credential add-password not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "add-cert --gateway <id> --token <id>",
+		Short: "Add certificate credential",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("credential add-cert not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "get-ssh <token> --gateway <id>",
+		Short: "Get SSH credential",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("credential get-ssh not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "get-password <token> --gateway <id>",
+		Short: "Get password credential",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("credential get-password not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "get-cert <token> --gateway <id>",
+		Short: "Get certificate credential",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("credential get-cert not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "list --gateway <id> --type <ssh|password|cert>",
+		Short: "List credentials",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("credential list not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "delete-ssh <token> --gateway <id>",
+		Short: "Delete SSH credential",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("credential delete-ssh not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "delete-password <token> --gateway <id>",
+		Short: "Delete password credential",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("credential delete-password not yet implemented")
+		},
+	})
+
+	return cmd
+}
diff --git a/cli/pkg/commands/experiment.go b/cli/pkg/commands/experiment.go
new file mode 100644
index 0000000..f69e527
--- /dev/null
+++ b/cli/pkg/commands/experiment.go
@@ -0,0 +1,410 @@
+package commands
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/apache/airavata/cli/gen-go/airavata_api"
+	"github.com/apache/airavata/cli/gen-go/security_model"
+	"github.com/apache/airavata/cli/pkg/client"
+	"github.com/spf13/cobra"
+)
+
+// NewExperimentCommand creates the experiment command
+func NewExperimentCommand() *cobra.Command {
+	experimentCmd := &cobra.Command{
+		Use:   "experiment",
+		Short: "Experiment management commands",
+		Long:  "Manage Airavata experiments (create, launch, clone, terminate, get, list)",
+	}
+
+	experimentCmd.AddCommand(NewExperimentCreateCommand())
+	experimentCmd.AddCommand(NewExperimentUpdateCommand())
+	experimentCmd.AddCommand(NewExperimentGetCommand())
+	experimentCmd.AddCommand(NewExperimentListCommand())
+	experimentCmd.AddCommand(NewExperimentDeleteCommand())
+	experimentCmd.AddCommand(NewExperimentLaunchCommand())
+	experimentCmd.AddCommand(NewExperimentTerminateCommand())
+	experimentCmd.AddCommand(NewExperimentCloneCommand())
+	experimentCmd.AddCommand(NewExperimentValidateCommand())
+	experimentCmd.AddCommand(NewExperimentGetStatusCommand())
+	experimentCmd.AddCommand(NewExperimentGetOutputsCommand())
+
+	return experimentCmd
+}
+
+func NewExperimentCreateCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "create --gateway <id> --project <id> --name <name>",
+		Short: "Create a new experiment",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("experiment create not yet implemented")
+		},
+	}
+}
+
+func NewExperimentUpdateCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "update <id>",
+		Short: "Update an existing experiment",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("experiment update not yet implemented")
+		},
+	}
+}
+
+func NewExperimentGetCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "get <id>",
+		Short: "Get experiment details",
+		Long:  "Get detailed information about a specific experiment",
+		Args:  cobra.ExactArgs(1),
+		RunE:  runExperimentGet,
+	}
+}
+
+func runExperimentGet(cmd *cobra.Command, args []string) error {
+	experimentID := args[0]
+
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetExperiment
+	ctx := context.Background()
+	experiment, err := airavataClient.GetExperiment(ctx, authzToken, experimentID)
+	if err != nil {
+		return fmt.Errorf("failed to get experiment: %w", err)
+	}
+
+	// Format output
+	outputData := map[string]interface{}{
+		"ID":          experiment.GetExperimentId(),
+		"Name":        experiment.GetExperimentName(),
+		"Description": experiment.GetDescription(),
+		"Project":     experiment.GetProjectId(),
+		"User":        experiment.GetUserName(),
+		"Created":     experiment.GetCreationTime(),
+		"Gateway":     experiment.GetGatewayId(),
+	}
+
+	// Display results
+	headers := []string{"Field", "Value"}
+	var rows [][]string
+	for key, value := range outputData {
+		rows = append(rows, []string{key, fmt.Sprintf("%v", value)})
+	}
+
+	return formatter.Write(rows, headers)
+}
+
+func NewExperimentListCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "list",
+		Short: "List experiments",
+		Long:  "List all available Airavata experiments",
+		RunE:  runExperimentList,
+	}
+}
+
+func runExperimentList(cmd *cobra.Command, args []string) error {
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetUserExperiments
+	ctx := context.Background()
+	experiments, err := airavataClient.GetUserExperiments(ctx, authzToken, cfg.Gateway.ID, cfg.Auth.Username, 100, 0)
+	if err != nil {
+		return fmt.Errorf("failed to get experiments: %w", err)
+	}
+
+	// Format output
+	if len(experiments) == 0 {
+		fmt.Println("No experiments found")
+		return nil
+	}
+
+	// Convert to output format
+	var outputData []map[string]interface{}
+	for _, experiment := range experiments {
+		outputData = append(outputData, map[string]interface{}{
+			"ID":          experiment.GetExperimentId(),
+			"Name":        experiment.GetExperimentName(),
+			"Description": experiment.GetDescription(),
+			"Project":     experiment.GetProjectId(),
+			"User":        experiment.GetUserName(),
+			"Created":     experiment.GetCreationTime(),
+		})
+	}
+
+	// Display results
+	headers := []string{"ID", "Name", "Description", "Project", "User", "Created"}
+	return formatter.Write(outputData, headers)
+}
+
+func NewExperimentDeleteCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "delete <id>",
+		Short: "Delete an experiment",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("experiment delete not yet implemented")
+		},
+	}
+}
+
+func NewExperimentLaunchCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "launch <id>",
+		Short: "Launch an experiment",
+		Long:  "Launch an experiment for execution",
+		Args:  cobra.ExactArgs(1),
+		RunE:  runExperimentLaunch,
+	}
+}
+
+func runExperimentLaunch(cmd *cobra.Command, args []string) error {
+	experimentID := args[0]
+
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call LaunchExperiment
+	ctx := context.Background()
+	err = airavataClient.LaunchExperiment(ctx, authzToken, experimentID, cfg.Gateway.ID)
+	if err != nil {
+		return fmt.Errorf("failed to launch experiment: %w", err)
+	}
+
+	fmt.Printf("Experiment %s launched successfully\n", experimentID)
+	return nil
+}
+
+func NewExperimentTerminateCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "terminate <id>",
+		Short: "Terminate an experiment",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("experiment terminate not yet implemented")
+		},
+	}
+}
+
+func NewExperimentCloneCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "clone <id> --new-name <name>",
+		Short: "Clone an experiment",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("experiment clone not yet implemented")
+		},
+	}
+}
+
+func NewExperimentValidateCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "validate <id>",
+		Short: "Validate an experiment",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("experiment validate not yet implemented")
+		},
+	}
+}
+
+func NewExperimentGetStatusCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "get-status <id>",
+		Short: "Get experiment status",
+		Long:  "Get the current status of an experiment",
+		Args:  cobra.ExactArgs(1),
+		RunE:  runExperimentStatus,
+	}
+}
+
+func runExperimentStatus(cmd *cobra.Command, args []string) error {
+	experimentID := args[0]
+
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetExperimentStatus
+	ctx := context.Background()
+	status, err := airavataClient.GetExperimentStatus(ctx, authzToken, experimentID)
+	if err != nil {
+		return fmt.Errorf("failed to get experiment status: %w", err)
+	}
+
+	// Format output
+	outputData := map[string]interface{}{
+		"Experiment ID":        experimentID,
+		"State":                status.GetState(),
+		"Time of State Change": status.GetTimeOfStateChange(),
+		"Reason":               status.GetReason(),
+	}
+
+	// Display results
+	headers := []string{"Field", "Value"}
+	var rows [][]string
+	for key, value := range outputData {
+		rows = append(rows, []string{key, fmt.Sprintf("%v", value)})
+	}
+
+	return formatter.Write(rows, headers)
+}
+
+func NewExperimentGetOutputsCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "get-outputs <id>",
+		Short: "Get experiment outputs",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("experiment get-outputs not yet implemented")
+		},
+	}
+}
diff --git a/cli/pkg/commands/gateway.go b/cli/pkg/commands/gateway.go
new file mode 100644
index 0000000..4f028da
--- /dev/null
+++ b/cli/pkg/commands/gateway.go
@@ -0,0 +1,315 @@
+package commands
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/apache/airavata/cli/gen-go/airavata_api"
+	"github.com/apache/airavata/cli/gen-go/security_model"
+	"github.com/apache/airavata/cli/pkg/client"
+	"github.com/spf13/cobra"
+)
+
+// NewGatewayCommand creates the gateway command
+func NewGatewayCommand() *cobra.Command {
+	gatewayCmd := &cobra.Command{
+		Use:   "gateway",
+		Short: "Gateway management commands",
+		Long:  "Manage Airavata gateways (create, update, delete, get, list)",
+	}
+
+	gatewayCmd.AddCommand(NewGatewayCreateCommand())
+	gatewayCmd.AddCommand(NewGatewayUpdateCommand())
+	gatewayCmd.AddCommand(NewGatewayGetCommand())
+	gatewayCmd.AddCommand(NewGatewayListCommand())
+	gatewayCmd.AddCommand(NewGatewayDeleteCommand())
+	gatewayCmd.AddCommand(NewGatewayExistsCommand())
+
+	return gatewayCmd
+}
+
+// NewGatewayCreateCommand creates the gateway create command
+func NewGatewayCreateCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "create --name <name> --domain <domain>",
+		Short: "Create a new gateway",
+		Long:  "Create a new Airavata gateway with the specified name and domain",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			// TODO: Implement gateway creation
+			return fmt.Errorf("gateway create not yet implemented")
+		},
+	}
+}
+
+// NewGatewayUpdateCommand creates the gateway update command
+func NewGatewayUpdateCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "update <id> --name <name>",
+		Short: "Update an existing gateway",
+		Long:  "Update an existing Airavata gateway",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			// TODO: Implement gateway update
+			return fmt.Errorf("gateway update not yet implemented")
+		},
+	}
+}
+
+// NewGatewayGetCommand creates the gateway get command
+func NewGatewayGetCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "get <id>",
+		Short: "Get gateway details",
+		Long:  "Get detailed information about a specific gateway",
+		Args:  cobra.ExactArgs(1),
+		RunE:  runGatewayGet,
+	}
+}
+
+func runGatewayGet(cmd *cobra.Command, args []string) error {
+	gatewayID := args[0]
+
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetGateway
+	ctx := context.Background()
+	gateway, err := airavataClient.GetGateway(ctx, authzToken, gatewayID)
+	if err != nil {
+		return fmt.Errorf("failed to get gateway: %w", err)
+	}
+
+	// Format output
+	adminName := ""
+	if gateway.GatewayAdminFirstName != nil && gateway.GatewayAdminLastName != nil {
+		adminName = *gateway.GatewayAdminFirstName + " " + *gateway.GatewayAdminLastName
+	}
+
+	outputData := map[string]interface{}{
+		"ID":          gateway.GetAiravataInternalGatewayId(),
+		"Name":        gateway.GetGatewayName(),
+		"Domain":      gateway.GetDomain(),
+		"Email":       gateway.GetEmailAddress(),
+		"Description": gateway.GetGatewayPublicAbstract(),
+		"URL":         gateway.GetGatewayURL(),
+		"Admin":       adminName,
+		"Admin Email": gateway.GetGatewayAdminEmail(),
+		"Status":      gateway.GetGatewayApprovalStatus(),
+	}
+
+	// Display results
+	headers := []string{"Field", "Value"}
+	var rows [][]string
+	for key, value := range outputData {
+		rows = append(rows, []string{key, fmt.Sprintf("%v", value)})
+	}
+
+	return formatter.Write(rows, headers)
+}
+
+// NewGatewayListCommand creates the gateway list command
+func NewGatewayListCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "list",
+		Short: "List all gateways",
+		Long:  "List all available Airavata gateways",
+		RunE:  runGatewayList,
+	}
+}
+
+func runGatewayList(cmd *cobra.Command, args []string) error {
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetAllGateways
+	ctx := context.Background()
+	gateways, err := airavataClient.GetAllGateways(ctx, authzToken)
+	if err != nil {
+		return fmt.Errorf("failed to get gateways: %w", err)
+	}
+
+	// Format output
+	if len(gateways) == 0 {
+		fmt.Println("No gateways found")
+		return nil
+	}
+
+	// Convert to output format
+	var outputData []map[string]interface{}
+	for _, gateway := range gateways {
+		adminName := ""
+		if gateway.GatewayAdminFirstName != nil && gateway.GatewayAdminLastName != nil {
+			adminName = *gateway.GatewayAdminFirstName + " " + *gateway.GatewayAdminLastName
+		}
+
+		outputData = append(outputData, map[string]interface{}{
+			"ID":          gateway.GetAiravataInternalGatewayId(),
+			"Name":        gateway.GetGatewayName(),
+			"Domain":      gateway.GetDomain(),
+			"Email":       gateway.GetEmailAddress(),
+			"Description": gateway.GetGatewayPublicAbstract(),
+			"URL":         gateway.GetGatewayURL(),
+			"Admin":       adminName,
+		})
+	}
+
+	// Display results
+	headers := []string{"ID", "Name", "Domain", "Email", "Description", "URL", "Admin"}
+	return formatter.Write(outputData, headers)
+}
+
+// NewGatewayDeleteCommand creates the gateway delete command
+func NewGatewayDeleteCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "delete <id>",
+		Short: "Delete a gateway",
+		Long:  "Delete an Airavata gateway",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			// TODO: Implement gateway delete
+			return fmt.Errorf("gateway delete not yet implemented")
+		},
+	}
+}
+
+// NewGatewayExistsCommand creates the gateway exists command
+func NewGatewayExistsCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "exists <id>",
+		Short: "Check if gateway exists",
+		Long:  "Check if a gateway with the specified ID exists",
+		Args:  cobra.ExactArgs(1),
+		RunE:  runGatewayExists,
+	}
+}
+
+func runGatewayExists(cmd *cobra.Command, args []string) error {
+	gatewayID := args[0]
+
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call IsGatewayExist
+	ctx := context.Background()
+	exists, err := airavataClient.IsGatewayExist(ctx, authzToken, gatewayID)
+	if err != nil {
+		return fmt.Errorf("failed to check if gateway exists: %w", err)
+	}
+
+	// Display result
+	if exists {
+		fmt.Printf("Gateway %s exists\n", gatewayID)
+	} else {
+		fmt.Printf("Gateway %s does not exist\n", gatewayID)
+	}
+
+	return nil
+}
diff --git a/cli/pkg/commands/group_manager.go b/cli/pkg/commands/group_manager.go
new file mode 100644
index 0000000..a7edfef
--- /dev/null
+++ b/cli/pkg/commands/group_manager.go
@@ -0,0 +1,114 @@
+package commands
+
+import (
+	"fmt"
+
+	"github.com/spf13/cobra"
+)
+
+func NewGroupManagerCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "group-manager",
+		Short: "Group manager commands",
+		Long:  "Manage groups (create, update, delete, add-users, remove-users)",
+	}
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "create --name <name> --description <desc>",
+		Short: "Create a group",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("group-manager create not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "update <group-id> --name <name>",
+		Short: "Update a group",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("group-manager update not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "get <group-id>",
+		Short: "Get group details",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("group-manager get not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "list",
+		Short: "List groups",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("group-manager list not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "delete <group-id> --owner <owner-id>",
+		Short: "Delete a group",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("group-manager delete not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "add-users <group-id> --users <id1,id2,...>",
+		Short: "Add users to group",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("group-manager add-users not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "remove-users <group-id> --users <id1,id2,...>",
+		Short: "Remove users from group",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("group-manager remove-users not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "transfer-ownership <group-id> --new-owner <owner-id>",
+		Short: "Transfer group ownership",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("group-manager transfer-ownership not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "add-admins <group-id> --admins <id1,id2,...>",
+		Short: "Add admins to group",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("group-manager add-admins not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "remove-admins <group-id> --admins <id1,id2,...>",
+		Short: "Remove admins from group",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("group-manager remove-admins not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "list-user-groups <username>",
+		Short: "List groups for user",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("group-manager list-user-groups not yet implemented")
+		},
+	})
+
+	return cmd
+}
diff --git a/cli/pkg/commands/iam_admin.go b/cli/pkg/commands/iam_admin.go
new file mode 100644
index 0000000..1599152
--- /dev/null
+++ b/cli/pkg/commands/iam_admin.go
@@ -0,0 +1,131 @@
+package commands
+
+import (
+	"fmt"
+
+	"github.com/spf13/cobra"
+)
+
+func NewIAMAdminCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "iam-admin",
+		Short: "IAM admin commands",
+		Long:  "Manage IAM admin services (user/role management)",
+	}
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "setup-gateway --name <name> --domain <domain>",
+		Short: "Set up a gateway",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("iam-admin setup-gateway not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "register-user --username <user> --email <email> --first-name <fn> --last-name <ln> --password <pwd>",
+		Short: "Register a new user",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("iam-admin register-user not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "get-user <username>",
+		Short: "Get user details",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("iam-admin get-user not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "list-users [--offset 0] [--limit 50] [--search <query>]",
+		Short: "List users",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("iam-admin list-users not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "enable-user <username>",
+		Short: "Enable a user",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("iam-admin enable-user not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "disable-user <username>",
+		Short: "Disable a user",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("iam-admin disable-user not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "delete-user <username>",
+		Short: "Delete a user",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("iam-admin delete-user not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "reset-password <username> --new-password <pwd>",
+		Short: "Reset user password",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("iam-admin reset-password not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "add-role <username> --role <role-name>",
+		Short: "Add role to user",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("iam-admin add-role not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "remove-role <username> --role <role-name>",
+		Short: "Remove role from user",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("iam-admin remove-role not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "list-users-with-role <role-name>",
+		Short: "List users with role",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("iam-admin list-users-with-role not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "username-available <username>",
+		Short: "Check if username is available",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("iam-admin username-available not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "user-exists <username>",
+		Short: "Check if user exists",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("iam-admin user-exists not yet implemented")
+		},
+	})
+
+	return cmd
+}
diff --git a/cli/pkg/commands/orchestrator.go b/cli/pkg/commands/orchestrator.go
new file mode 100644
index 0000000..09a7b03
--- /dev/null
+++ b/cli/pkg/commands/orchestrator.go
@@ -0,0 +1,62 @@
+package commands
+
+import (
+	"fmt"
+
+	"github.com/spf13/cobra"
+)
+
+func NewOrchestratorCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "orchestrator",
+		Short: "Orchestrator commands",
+		Long:  "Manage experiment orchestration (launch, validate, terminate)",
+	}
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "launch-experiment <experiment-id> --gateway <id>",
+		Short: "Launch an experiment",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("orchestrator launch-experiment not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "launch-process <process-id> --gateway <id> --token <cred-token>",
+		Short: "Launch a process",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("orchestrator launch-process not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "validate-experiment <experiment-id>",
+		Short: "Validate an experiment",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("orchestrator validate-experiment not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "validate-process <experiment-id>",
+		Short: "Validate a process",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("orchestrator validate-process not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "terminate-experiment <experiment-id> --gateway <id>",
+		Short: "Terminate an experiment",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("orchestrator terminate-experiment not yet implemented")
+		},
+	})
+
+	return cmd
+}
diff --git a/cli/pkg/commands/project.go b/cli/pkg/commands/project.go
new file mode 100644
index 0000000..20d2f91
--- /dev/null
+++ b/cli/pkg/commands/project.go
@@ -0,0 +1,218 @@
+package commands
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/apache/airavata/cli/gen-go/airavata_api"
+	"github.com/apache/airavata/cli/gen-go/security_model"
+	"github.com/apache/airavata/cli/pkg/client"
+	"github.com/spf13/cobra"
+)
+
+// NewProjectCommand creates the project command
+func NewProjectCommand() *cobra.Command {
+	projectCmd := &cobra.Command{
+		Use:   "project",
+		Short: "Project management commands",
+		Long:  "Manage Airavata projects (create, update, delete, get, list)",
+	}
+
+	projectCmd.AddCommand(NewProjectCreateCommand())
+	projectCmd.AddCommand(NewProjectUpdateCommand())
+	projectCmd.AddCommand(NewProjectGetCommand())
+	projectCmd.AddCommand(NewProjectListCommand())
+	projectCmd.AddCommand(NewProjectDeleteCommand())
+
+	return projectCmd
+}
+
+func NewProjectCreateCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "create --gateway <id> --name <name> --owner <user>",
+		Short: "Create a new project",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("project create not yet implemented")
+		},
+	}
+}
+
+func NewProjectUpdateCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "update <id> --name <name>",
+		Short: "Update an existing project",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("project update not yet implemented")
+		},
+	}
+}
+
+func NewProjectGetCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "get <id>",
+		Short: "Get project details",
+		Long:  "Get detailed information about a specific project",
+		Args:  cobra.ExactArgs(1),
+		RunE:  runProjectGet,
+	}
+}
+
+func runProjectGet(cmd *cobra.Command, args []string) error {
+	projectID := args[0]
+
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetProject
+	ctx := context.Background()
+	project, err := airavataClient.GetProject(ctx, authzToken, projectID)
+	if err != nil {
+		return fmt.Errorf("failed to get project: %w", err)
+	}
+
+	// Format output
+	outputData := map[string]interface{}{
+		"ID":          project.GetProjectID(),
+		"Name":        project.GetName(),
+		"Description": project.GetDescription(),
+		"Owner":       project.GetOwner(),
+		"Created":     project.GetCreationTime(),
+		"Gateway":     project.GetGatewayId(),
+	}
+
+	// Display results
+	headers := []string{"Field", "Value"}
+	var rows [][]string
+	for key, value := range outputData {
+		rows = append(rows, []string{key, fmt.Sprintf("%v", value)})
+	}
+
+	return formatter.Write(rows, headers)
+}
+
+func NewProjectListCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "list",
+		Short: "List projects",
+		Long:  "List all available Airavata projects",
+		RunE:  runProjectList,
+	}
+}
+
+func runProjectList(cmd *cobra.Command, args []string) error {
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetUserProjects
+	ctx := context.Background()
+	projects, err := airavataClient.GetUserProjects(ctx, authzToken, cfg.Gateway.ID, cfg.Auth.Username, 100, 0)
+	if err != nil {
+		return fmt.Errorf("failed to get projects: %w", err)
+	}
+
+	// Format output
+	if len(projects) == 0 {
+		fmt.Println("No projects found")
+		return nil
+	}
+
+	// Convert to output format
+	var outputData []map[string]interface{}
+	for _, project := range projects {
+		outputData = append(outputData, map[string]interface{}{
+			"ID":          project.GetProjectID(),
+			"Name":        project.GetName(),
+			"Description": project.GetDescription(),
+			"Owner":       project.GetOwner(),
+			"Created":     project.GetCreationTime(),
+		})
+	}
+
+	// Display results
+	headers := []string{"ID", "Name", "Description", "Owner", "Created"}
+	return formatter.Write(outputData, headers)
+}
+
+func NewProjectDeleteCommand() *cobra.Command {
+	return &cobra.Command{
+		Use:   "delete <id>",
+		Short: "Delete a project",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("project delete not yet implemented")
+		},
+	}
+}
diff --git a/cli/pkg/commands/resource_profile.go b/cli/pkg/commands/resource_profile.go
new file mode 100644
index 0000000..69012b3
--- /dev/null
+++ b/cli/pkg/commands/resource_profile.go
@@ -0,0 +1,130 @@
+package commands
+
+import (
+	"fmt"
+
+	"github.com/spf13/cobra"
+)
+
+func NewResourceProfileCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "resource-profile",
+		Short: "Resource profile management commands",
+		Long:  "Manage resource profiles (gateway, user, group)",
+	}
+
+	// Gateway resource profiles
+	gatewayCmd := &cobra.Command{
+		Use:   "gateway",
+		Short: "Gateway resource profile commands",
+	}
+	gatewayCmd.AddCommand(&cobra.Command{
+		Use:   "create <gateway-id>",
+		Short: "Create gateway resource profile",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("resource-profile gateway create not yet implemented")
+		},
+	})
+	gatewayCmd.AddCommand(&cobra.Command{
+		Use:   "update <gateway-id>",
+		Short: "Update gateway resource profile",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("resource-profile gateway update not yet implemented")
+		},
+	})
+	gatewayCmd.AddCommand(&cobra.Command{
+		Use:   "get <gateway-id>",
+		Short: "Get gateway resource profile",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("resource-profile gateway get not yet implemented")
+		},
+	})
+	gatewayCmd.AddCommand(&cobra.Command{
+		Use:   "delete <gateway-id>",
+		Short: "Delete gateway resource profile",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("resource-profile gateway delete not yet implemented")
+		},
+	})
+
+	// User resource profiles
+	userCmd := &cobra.Command{
+		Use:   "user",
+		Short: "User resource profile commands",
+	}
+	userCmd.AddCommand(&cobra.Command{
+		Use:   "create --user <id> --gateway <id>",
+		Short: "Create user resource profile",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("resource-profile user create not yet implemented")
+		},
+	})
+	userCmd.AddCommand(&cobra.Command{
+		Use:   "update --user <id> --gateway <id>",
+		Short: "Update user resource profile",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("resource-profile user update not yet implemented")
+		},
+	})
+	userCmd.AddCommand(&cobra.Command{
+		Use:   "get --user <id> --gateway <id>",
+		Short: "Get user resource profile",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("resource-profile user get not yet implemented")
+		},
+	})
+	userCmd.AddCommand(&cobra.Command{
+		Use:   "delete --user <id> --gateway <id>",
+		Short: "Delete user resource profile",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("resource-profile user delete not yet implemented")
+		},
+	})
+
+	// Group resource profiles
+	groupCmd := &cobra.Command{
+		Use:   "group",
+		Short: "Group resource profile commands",
+	}
+	groupCmd.AddCommand(&cobra.Command{
+		Use:   "create --name <name>",
+		Short: "Create group resource profile",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("resource-profile group create not yet implemented")
+		},
+	})
+	groupCmd.AddCommand(&cobra.Command{
+		Use:   "update <id>",
+		Short: "Update group resource profile",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("resource-profile group update not yet implemented")
+		},
+	})
+	groupCmd.AddCommand(&cobra.Command{
+		Use:   "get <id>",
+		Short: "Get group resource profile",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("resource-profile group get not yet implemented")
+		},
+	})
+	groupCmd.AddCommand(&cobra.Command{
+		Use:   "delete <id>",
+		Short: "Delete group resource profile",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("resource-profile group delete not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(gatewayCmd)
+	cmd.AddCommand(userCmd)
+	cmd.AddCommand(groupCmd)
+
+	return cmd
+}
diff --git a/cli/pkg/commands/root.go b/cli/pkg/commands/root.go
new file mode 100644
index 0000000..1c4075a
--- /dev/null
+++ b/cli/pkg/commands/root.go
@@ -0,0 +1,116 @@
+package commands
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/apache/airavata/cli/pkg/config"
+	"github.com/apache/airavata/cli/pkg/output"
+	"github.com/spf13/cobra"
+)
+
+var (
+	// Global flags
+	outputFormat string
+	quiet        bool
+	verbose      bool
+
+	// Global config
+	configManager *config.ConfigManager
+	formatter     *output.Formatter
+)
+
+// NewRootCommand creates the root command
+func NewRootCommand() *cobra.Command {
+	configManager = config.NewConfigManager()
+	formatter = output.NewFormatter(output.FormatTable, os.Stdout)
+
+	rootCmd := &cobra.Command{
+		Use:   "airavata",
+		Short: "Airavata CLI - Command line interface for Apache Airavata",
+		Long: `Airavata CLI provides a comprehensive command-line interface for Apache Airavata.
+
+This CLI supports all major Airavata services including:
+- Gateway and project management
+- Experiment lifecycle management
+- Application catalog management
+- Compute and storage resource management
+- User and group management
+- Workflow management
+- And much more...
+
+Authentication is required for most operations. Use 'airavata auth login <hostname:port>' to authenticate.`,
+		PersistentPreRun: func(cmd *cobra.Command, args []string) {
+			// Skip auth check for auth commands
+			if cmd.Parent() != nil && cmd.Parent().Name() == "auth" {
+				return
+			}
+
+			// Check authentication for all other commands
+			if !configManager.IsAuthenticated() {
+				fmt.Fprintf(os.Stderr, "Error: Not authenticated. Please run 'airavata auth login <hostname:port>' first.\n")
+				os.Exit(2)
+			}
+		},
+	}
+
+	// Global flags
+	rootCmd.PersistentFlags().StringVarP(&outputFormat, "output", "o", "table", "Output format (table, json, csv)")
+	rootCmd.PersistentFlags().BoolVarP(&quiet, "quiet", "q", false, "Suppress output except errors")
+	rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Verbose output")
+
+	// Parse output format
+	rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
+		// Set output format
+		format := output.Format(outputFormat)
+		switch format {
+		case output.FormatTable, output.FormatJSON, output.FormatCSV:
+			formatter = output.NewFormatter(format, os.Stdout)
+		default:
+			return fmt.Errorf("invalid output format: %s", outputFormat)
+		}
+
+		// Skip auth check for auth commands and version
+		if cmd.Parent() != nil && (cmd.Parent().Name() == "auth" || cmd.Name() == "version") {
+			return nil
+		}
+
+		// Check authentication for all other commands
+		if !configManager.IsAuthenticated() {
+			fmt.Fprintf(os.Stderr, "Error: Not authenticated. Please run 'airavata auth login <hostname:port>' first.\n")
+			os.Exit(2)
+		}
+
+		return nil
+	}
+
+	// Add subcommands
+	rootCmd.AddCommand(NewAuthCommand())
+	rootCmd.AddCommand(NewGatewayCommand())
+	rootCmd.AddCommand(NewProjectCommand())
+	rootCmd.AddCommand(NewExperimentCommand())
+	rootCmd.AddCommand(NewApplicationCommand())
+	rootCmd.AddCommand(NewComputeCommand())
+	rootCmd.AddCommand(NewStorageCommand())
+	rootCmd.AddCommand(NewCredentialCommand())
+	rootCmd.AddCommand(NewResourceProfileCommand())
+	rootCmd.AddCommand(NewWorkflowCommand())
+	rootCmd.AddCommand(NewSharingCommand())
+	rootCmd.AddCommand(NewOrchestratorCommand())
+	rootCmd.AddCommand(NewUserProfileCommand())
+	rootCmd.AddCommand(NewTenantCommand())
+	rootCmd.AddCommand(NewIAMAdminCommand())
+	rootCmd.AddCommand(NewGroupManagerCommand())
+
+	return rootCmd
+}
+
+// GetConfigManager returns the global config manager
+func GetConfigManager() *config.ConfigManager {
+	return configManager
+}
+
+// GetFormatter returns the global formatter
+func GetFormatter() *output.Formatter {
+	return formatter
+}
diff --git a/cli/pkg/commands/sharing.go b/cli/pkg/commands/sharing.go
new file mode 100644
index 0000000..f0693b2
--- /dev/null
+++ b/cli/pkg/commands/sharing.go
@@ -0,0 +1,203 @@
+package commands
+
+import (
+	"fmt"
+
+	"github.com/spf13/cobra"
+)
+
+func NewSharingCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "sharing",
+		Short: "Sharing registry commands",
+		Long:  "Manage sharing registry (domains, users, groups, entities, permissions)",
+	}
+
+	// Domain commands
+	domainCmd := &cobra.Command{
+		Use:   "domain",
+		Short: "Domain commands",
+	}
+	domainCmd.AddCommand(&cobra.Command{
+		Use:   "create --name <name> --description <desc>",
+		Short: "Create a domain",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing domain create not yet implemented")
+		},
+	})
+	domainCmd.AddCommand(&cobra.Command{
+		Use:   "update <id>",
+		Short: "Update a domain",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing domain update not yet implemented")
+		},
+	})
+	domainCmd.AddCommand(&cobra.Command{
+		Use:   "get <id>",
+		Short: "Get domain details",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing domain get not yet implemented")
+		},
+	})
+	domainCmd.AddCommand(&cobra.Command{
+		Use:   "list",
+		Short: "List domains",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing domain list not yet implemented")
+		},
+	})
+	domainCmd.AddCommand(&cobra.Command{
+		Use:   "delete <id>",
+		Short: "Delete a domain",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing domain delete not yet implemented")
+		},
+	})
+
+	// User commands
+	userCmd := &cobra.Command{
+		Use:   "user",
+		Short: "User commands",
+	}
+	userCmd.AddCommand(&cobra.Command{
+		Use:   "create --domain <id> --user-id <id> --username <name>",
+		Short: "Create a user",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing user create not yet implemented")
+		},
+	})
+	userCmd.AddCommand(&cobra.Command{
+		Use:   "update --domain <id> --user-id <id>",
+		Short: "Update a user",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing user update not yet implemented")
+		},
+	})
+	userCmd.AddCommand(&cobra.Command{
+		Use:   "get --domain <id> --user-id <id>",
+		Short: "Get user details",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing user get not yet implemented")
+		},
+	})
+	userCmd.AddCommand(&cobra.Command{
+		Use:   "list --domain <id>",
+		Short: "List users",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing user list not yet implemented")
+		},
+	})
+	userCmd.AddCommand(&cobra.Command{
+		Use:   "delete --domain <id> --user-id <id>",
+		Short: "Delete a user",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing user delete not yet implemented")
+		},
+	})
+
+	// Group commands
+	groupCmd := &cobra.Command{
+		Use:   "group",
+		Short: "Group commands",
+	}
+	groupCmd.AddCommand(&cobra.Command{
+		Use:   "create --domain <id> --name <name>",
+		Short: "Create a group",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing group create not yet implemented")
+		},
+	})
+	groupCmd.AddCommand(&cobra.Command{
+		Use:   "update --domain <id> --group-id <id>",
+		Short: "Update a group",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing group update not yet implemented")
+		},
+	})
+	groupCmd.AddCommand(&cobra.Command{
+		Use:   "get --domain <id> --group-id <id>",
+		Short: "Get group details",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing group get not yet implemented")
+		},
+	})
+	groupCmd.AddCommand(&cobra.Command{
+		Use:   "list --domain <id>",
+		Short: "List groups",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing group list not yet implemented")
+		},
+	})
+	groupCmd.AddCommand(&cobra.Command{
+		Use:   "delete --domain <id> --group-id <id>",
+		Short: "Delete a group",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing group delete not yet implemented")
+		},
+	})
+	groupCmd.AddCommand(&cobra.Command{
+		Use:   "add-users --domain <id> --group-id <id> --users <id1,id2>",
+		Short: "Add users to group",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing group add-users not yet implemented")
+		},
+	})
+	groupCmd.AddCommand(&cobra.Command{
+		Use:   "remove-users --domain <id> --group-id <id> --users <id1,id2>",
+		Short: "Remove users from group",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing group remove-users not yet implemented")
+		},
+	})
+
+	// Entity commands
+	entityCmd := &cobra.Command{
+		Use:   "entity",
+		Short: "Entity commands",
+	}
+	entityCmd.AddCommand(&cobra.Command{
+		Use:   "create --domain <id> --entity-id <id> --type <type>",
+		Short: "Create an entity",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing entity create not yet implemented")
+		},
+	})
+	entityCmd.AddCommand(&cobra.Command{
+		Use:   "share --domain <id> --entity-id <id> --users <ids> --permission <id>",
+		Short: "Share entity with users",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing entity share not yet implemented")
+		},
+	})
+	entityCmd.AddCommand(&cobra.Command{
+		Use:   "revoke --domain <id> --entity-id <id> --users <ids> --permission <id>",
+		Short: "Revoke entity sharing",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing entity revoke not yet implemented")
+		},
+	})
+
+	// Permission commands
+	permissionCmd := &cobra.Command{
+		Use:   "permission",
+		Short: "Permission commands",
+	}
+	permissionCmd.AddCommand(&cobra.Command{
+		Use:   "create --domain <id> --name <name>",
+		Short: "Create a permission",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("sharing permission create not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(domainCmd)
+	cmd.AddCommand(userCmd)
+	cmd.AddCommand(groupCmd)
+	cmd.AddCommand(entityCmd)
+	cmd.AddCommand(permissionCmd)
+
+	return cmd
+}
diff --git a/cli/pkg/commands/storage.go b/cli/pkg/commands/storage.go
new file mode 100644
index 0000000..00da959
--- /dev/null
+++ b/cli/pkg/commands/storage.go
@@ -0,0 +1,195 @@
+package commands
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/apache/airavata/cli/gen-go/airavata_api"
+	"github.com/apache/airavata/cli/gen-go/security_model"
+	"github.com/apache/airavata/cli/pkg/client"
+	"github.com/spf13/cobra"
+)
+
+func NewStorageCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "storage",
+		Short: "Storage resource management commands",
+		Long:  "Manage storage resources (create, update, delete, get, list)",
+	}
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "create --name <name> --host <host>",
+		Short: "Create a storage resource",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("storage create not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "update <id>",
+		Short: "Update a storage resource",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("storage update not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "get <id>",
+		Short: "Get storage resource details",
+		Long:  "Get detailed information about a specific storage resource",
+		Args:  cobra.ExactArgs(1),
+		RunE:  runStorageGet,
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "list",
+		Short: "List storage resources",
+		Long:  "List all available storage resources",
+		RunE:  runStorageList,
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "delete <id>",
+		Short: "Delete a storage resource",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("storage delete not yet implemented")
+		},
+	})
+
+	return cmd
+}
+
+func runStorageList(cmd *cobra.Command, args []string) error {
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetAllStorageResourceNames
+	ctx := context.Background()
+	resourceNames, err := airavataClient.GetAllStorageResourceNames(ctx, authzToken)
+	if err != nil {
+		return fmt.Errorf("failed to get storage resources: %w", err)
+	}
+
+	// Format output
+	if len(resourceNames) == 0 {
+		fmt.Println("No storage resources found")
+		return nil
+	}
+
+	// Convert to output format
+	var outputData []map[string]interface{}
+	for id, name := range resourceNames {
+		outputData = append(outputData, map[string]interface{}{
+			"ID":   id,
+			"Name": name,
+		})
+	}
+
+	// Display results
+	headers := []string{"ID", "Name"}
+	return formatter.Write(outputData, headers)
+}
+
+func runStorageGet(cmd *cobra.Command, args []string) error {
+	resourceID := args[0]
+
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetStorageResource
+	ctx := context.Background()
+	resource, err := airavataClient.GetStorageResource(ctx, authzToken, resourceID)
+	if err != nil {
+		return fmt.Errorf("failed to get storage resource: %w", err)
+	}
+
+	// Format output
+	outputData := map[string]interface{}{
+		"ID":          resource.GetStorageResourceId(),
+		"Name":        resource.GetHostName(),
+		"Description": resource.GetStorageResourceDescription(),
+	}
+
+	// Display results
+	headers := []string{"Field", "Value"}
+	var rows [][]string
+	for key, value := range outputData {
+		rows = append(rows, []string{key, fmt.Sprintf("%v", value)})
+	}
+
+	return formatter.Write(rows, headers)
+}
diff --git a/cli/pkg/commands/tenant.go b/cli/pkg/commands/tenant.go
new file mode 100644
index 0000000..8ab414c
--- /dev/null
+++ b/cli/pkg/commands/tenant.go
@@ -0,0 +1,209 @@
+package commands
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/apache/airavata/cli/gen-go/airavata_api"
+	"github.com/apache/airavata/cli/gen-go/security_model"
+	"github.com/apache/airavata/cli/pkg/client"
+	"github.com/spf13/cobra"
+)
+
+func NewTenantCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "tenant",
+		Short: "Tenant profile commands",
+		Long:  "Manage tenant profiles (gateway management)",
+	}
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "add-gateway --name <name> --domain <domain>",
+		Short: "Add a gateway",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("tenant add-gateway not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "update-gateway <id>",
+		Short: "Update a gateway",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("tenant update-gateway not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "get <id>",
+		Short: "Get tenant profile",
+		Long:  "Get detailed information about a specific tenant",
+		Args:  cobra.ExactArgs(1),
+		RunE:  runTenantGet,
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "list",
+		Short: "List all tenants",
+		Long:  "List all available tenant profiles",
+		RunE:  runTenantList,
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "delete-gateway <id>",
+		Short: "Delete a gateway",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("tenant delete-gateway not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "gateway-exists <id>",
+		Short: "Check if gateway exists",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("tenant gateway-exists not yet implemented")
+		},
+	})
+
+	return cmd
+}
+
+func runTenantGet(cmd *cobra.Command, args []string) error {
+	tenantID := args[0]
+
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetGateway (using gateway as tenant for now)
+	ctx := context.Background()
+	gateway, err := airavataClient.GetGateway(ctx, authzToken, tenantID)
+	if err != nil {
+		return fmt.Errorf("failed to get gateway: %w", err)
+	}
+
+	// Format output
+	outputData := map[string]interface{}{
+		"Gateway ID":    gateway.GetAiravataInternalGatewayId(),
+		"Name":          gateway.GetGatewayName(),
+		"Description":   gateway.GetGatewayPublicAbstract(),
+		"Domain":        gateway.GetDomain(),
+		"Contact Email": gateway.GetEmailAddress(),
+	}
+
+	// Display results
+	headers := []string{"Field", "Value"}
+	var rows [][]string
+	for key, value := range outputData {
+		rows = append(rows, []string{key, fmt.Sprintf("%v", value)})
+	}
+
+	return formatter.Write(rows, headers)
+}
+
+func runTenantList(cmd *cobra.Command, args []string) error {
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetAllGateways (using gateways as tenants for now)
+	ctx := context.Background()
+	gateways, err := airavataClient.GetAllGateways(ctx, authzToken)
+	if err != nil {
+		return fmt.Errorf("failed to get gateways: %w", err)
+	}
+
+	// Format output
+	if len(gateways) == 0 {
+		fmt.Println("No gateways found")
+		return nil
+	}
+
+	// Convert to output format
+	var outputData []map[string]interface{}
+	for _, gateway := range gateways {
+		outputData = append(outputData, map[string]interface{}{
+			"Gateway ID":    gateway.GetAiravataInternalGatewayId(),
+			"Name":          gateway.GetGatewayName(),
+			"Description":   gateway.GetGatewayPublicAbstract(),
+			"Domain":        gateway.GetDomain(),
+			"Contact Email": gateway.GetEmailAddress(),
+		})
+	}
+
+	// Display results
+	headers := []string{"Gateway ID", "Name", "Description", "Domain", "Contact Email"}
+	return formatter.Write(outputData, headers)
+}
diff --git a/cli/pkg/commands/user_profile.go b/cli/pkg/commands/user_profile.go
new file mode 100644
index 0000000..85666ec
--- /dev/null
+++ b/cli/pkg/commands/user_profile.go
@@ -0,0 +1,136 @@
+package commands
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/apache/airavata/cli/gen-go/airavata_api"
+	"github.com/apache/airavata/cli/gen-go/security_model"
+	"github.com/apache/airavata/cli/pkg/client"
+	"github.com/spf13/cobra"
+)
+
+func NewUserProfileCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "user-profile",
+		Short: "User profile commands",
+		Long:  "Manage user profiles (init, update, get, delete, list)",
+	}
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "init",
+		Short: "Initialize user profile from IAM",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("user-profile init not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "update --first-name <name> --last-name <name>",
+		Short: "Update user profile",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("user-profile update not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "get",
+		Short: "Get current user profile",
+		Long:  "Get the current user's profile information",
+		RunE:  runUserProfileGet,
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "list --gateway <id> [--offset 0] [--limit 50]",
+		Short: "List user profiles",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("user-profile list not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "delete <user-id> --gateway <id>",
+		Short: "Delete user profile",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("user-profile delete not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "exists <user-id> --gateway <id>",
+		Short: "Check if user profile exists",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("user-profile exists not yet implemented")
+		},
+	})
+
+	return cmd
+}
+
+func runUserProfileGet(cmd *cobra.Command, args []string) error {
+	// Load configuration
+	cfg, err := configManager.Load()
+	if err != nil {
+		return fmt.Errorf("failed to load configuration: %w", err)
+	}
+
+	// Get server address
+	serverAddress, err := configManager.GetServerAddress()
+	if err != nil {
+		return fmt.Errorf("failed to get server address: %w", err)
+	}
+
+	// Create client manager
+	clientManager := client.NewClientManager(serverAddress)
+	defer clientManager.Close()
+
+	// Connect to server
+	if err := clientManager.Connect(); err != nil {
+		return fmt.Errorf("failed to connect to server: %w", err)
+	}
+
+	// Create multiplexed protocol for Airavata service
+	protocol, err := clientManager.GetMultiplexedProtocol("Airavata")
+	if err != nil {
+		return fmt.Errorf("failed to create multiplexed protocol: %w", err)
+	}
+
+	// Create Airavata client using the protocol factory
+	airavataClient := airavata_api.NewAiravataClientProtocol(clientManager.GetTransport(), protocol, protocol)
+
+	// Create AuthzToken
+	authzToken := &security_model.AuthzToken{
+		AccessToken: cfg.Auth.AccessToken,
+		ClaimsMap: map[string]string{
+			"userName":  cfg.Auth.Username,
+			"gatewayID": cfg.Gateway.ID,
+		},
+	}
+
+	// Call GetUserResourceProfile
+	ctx := context.Background()
+	profile, err := airavataClient.GetUserResourceProfile(ctx, authzToken, cfg.Auth.Username, cfg.Gateway.ID)
+	if err != nil {
+		return fmt.Errorf("failed to get user profile: %w", err)
+	}
+
+	// Format output
+	outputData := map[string]interface{}{
+		"User ID":                   profile.GetUserId(),
+		"Gateway ID":                profile.GetGatewayID(),
+		"Credential Store Token":    profile.GetCredentialStoreToken(),
+		"Identity Server Tenant":    profile.GetIdentityServerTenant(),
+		"Identity Server Pwd Token": profile.GetIdentityServerPwdCredToken(),
+	}
+
+	// Display results
+	headers := []string{"Field", "Value"}
+	var rows [][]string
+	for key, value := range outputData {
+		rows = append(rows, []string{key, fmt.Sprintf("%v", value)})
+	}
+
+	return formatter.Write(rows, headers)
+}
diff --git a/cli/pkg/commands/workflow.go b/cli/pkg/commands/workflow.go
new file mode 100644
index 0000000..e379cba
--- /dev/null
+++ b/cli/pkg/commands/workflow.go
@@ -0,0 +1,68 @@
+package commands
+
+import (
+	"fmt"
+
+	"github.com/spf13/cobra"
+)
+
+func NewWorkflowCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "workflow",
+		Short: "Workflow management commands",
+		Long:  "Manage workflows (create, update, delete, get, list)",
+	}
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "create --name <name> --definition <file>",
+		Short: "Create a workflow",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("workflow create not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "update <id> --definition <file>",
+		Short: "Update a workflow",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("workflow update not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "get <id>",
+		Short: "Get workflow details",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("workflow get not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "list",
+		Short: "List workflows",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("workflow list not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "delete <id>",
+		Short: "Delete a workflow",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("workflow delete not yet implemented")
+		},
+	})
+
+	cmd.AddCommand(&cobra.Command{
+		Use:   "exists --name <name>",
+		Short: "Check if workflow exists",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			return fmt.Errorf("workflow exists not yet implemented")
+		},
+	})
+
+	return cmd
+}
diff --git a/cli/pkg/config/config.go b/cli/pkg/config/config.go
new file mode 100644
index 0000000..7807fad
--- /dev/null
+++ b/cli/pkg/config/config.go
@@ -0,0 +1,203 @@
+package config
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+	"time"
+
+	"gopkg.in/yaml.v3"
+)
+
+// Config represents the CLI configuration
+type Config struct {
+	Server  ServerConfig  `yaml:"server"`
+	Auth    AuthConfig    `yaml:"auth"`
+	Gateway GatewayConfig `yaml:"gateway"`
+}
+
+// ServerConfig holds server connection information
+type ServerConfig struct {
+	Hostname string `yaml:"hostname"`
+	Port     int    `yaml:"port"`
+	TLS      bool   `yaml:"tls"`
+}
+
+// AuthConfig holds authentication information
+type AuthConfig struct {
+	KeycloakURL  string    `yaml:"keycloak_url"`
+	Realm        string    `yaml:"realm"`
+	ClientID     string    `yaml:"client_id"`
+	AccessToken  string    `yaml:"access_token"`
+	RefreshToken string    `yaml:"refresh_token"`
+	ExpiresAt    time.Time `yaml:"expires_at"`
+	Username     string    `yaml:"username"`
+}
+
+// GatewayConfig holds default gateway information
+type GatewayConfig struct {
+	ID string `yaml:"id"`
+}
+
+// DefaultConfig returns a default configuration
+func DefaultConfig() *Config {
+	return &Config{
+		Server: ServerConfig{
+			Port: 9930,
+			TLS:  true,
+		},
+		Auth: AuthConfig{
+			ClientID: "airavata-cli",
+		},
+		Gateway: GatewayConfig{
+			ID: "default-gateway",
+		},
+	}
+}
+
+// ConfigManager handles configuration file operations
+type ConfigManager struct {
+	configPath string
+	config     *Config
+}
+
+// NewConfigManager creates a new configuration manager
+func NewConfigManager() *ConfigManager {
+	homeDir, err := os.UserHomeDir()
+	if err != nil {
+		panic(fmt.Sprintf("Failed to get user home directory: %v", err))
+	}
+
+	configDir := filepath.Join(homeDir, ".airavata-cli")
+	configPath := filepath.Join(configDir, "config.yaml")
+
+	return &ConfigManager{
+		configPath: configPath,
+		config:     nil,
+	}
+}
+
+// Load loads configuration from file
+func (cm *ConfigManager) Load() (*Config, error) {
+	if cm.config != nil {
+		return cm.config, nil
+	}
+
+	// Check if config file exists
+	if _, err := os.Stat(cm.configPath); os.IsNotExist(err) {
+		cm.config = DefaultConfig()
+		return cm.config, nil
+	}
+
+	// Read config file
+	data, err := os.ReadFile(cm.configPath)
+	if err != nil {
+		return nil, fmt.Errorf("failed to read config file: %w", err)
+	}
+
+	// Parse YAML
+	config := DefaultConfig()
+	if err := yaml.Unmarshal(data, config); err != nil {
+		return nil, fmt.Errorf("failed to parse config file: %w", err)
+	}
+
+	cm.config = config
+	return config, nil
+}
+
+// Save saves configuration to file
+func (cm *ConfigManager) Save(config *Config) error {
+	// Create config directory if it doesn't exist
+	configDir := filepath.Dir(cm.configPath)
+	if err := os.MkdirAll(configDir, 0755); err != nil {
+		return fmt.Errorf("failed to create config directory: %w", err)
+	}
+
+	// Marshal to YAML
+	data, err := yaml.Marshal(config)
+	if err != nil {
+		return fmt.Errorf("failed to marshal config: %w", err)
+	}
+
+	// Write to file
+	if err := os.WriteFile(cm.configPath, data, 0600); err != nil {
+		return fmt.Errorf("failed to write config file: %w", err)
+	}
+
+	cm.config = config
+	return nil
+}
+
+// Clear clears the configuration (for logout)
+func (cm *ConfigManager) Clear() error {
+	if _, err := os.Stat(cm.configPath); os.IsNotExist(err) {
+		return nil // Nothing to clear
+	}
+
+	if err := os.Remove(cm.configPath); err != nil {
+		return fmt.Errorf("failed to remove config file: %w", err)
+	}
+
+	cm.config = nil
+	return nil
+}
+
+// IsAuthenticated checks if the user is authenticated
+func (cm *ConfigManager) IsAuthenticated() bool {
+	config, err := cm.Load()
+	if err != nil {
+		return false
+	}
+
+	// Check if we have required auth fields
+	if config.Auth.AccessToken == "" || config.Auth.Username == "" {
+		return false
+	}
+
+	// Check if token is expired
+	if !config.Auth.ExpiresAt.IsZero() && time.Now().After(config.Auth.ExpiresAt) {
+		return false
+	}
+
+	return true
+}
+
+// GetServerAddress returns the server address
+func (cm *ConfigManager) GetServerAddress() (string, error) {
+	config, err := cm.Load()
+	if err != nil {
+		return "", err
+	}
+
+	if config.Server.Hostname == "" {
+		return "", fmt.Errorf("server hostname not configured")
+	}
+
+	protocol := "thrift"
+	if config.Server.TLS {
+		protocol = "thrift+ssl"
+	}
+
+	return fmt.Sprintf("%s://%s:%d", protocol, config.Server.Hostname, config.Server.Port), nil
+}
+
+// GetAuthzToken returns the authorization token for Thrift calls
+func (cm *ConfigManager) GetAuthzToken() (map[string]string, error) {
+	config, err := cm.Load()
+	if err != nil {
+		return nil, err
+	}
+
+	if !cm.IsAuthenticated() {
+		return nil, fmt.Errorf("not authenticated")
+	}
+
+	// Create claims map for AuthzToken
+	claims := map[string]string{
+		"accessToken": config.Auth.AccessToken,
+		"userName":    config.Auth.Username,
+		"gatewayID":   config.Gateway.ID,
+	}
+
+	return claims, nil
+}
diff --git a/cli/pkg/output/formatter.go b/cli/pkg/output/formatter.go
new file mode 100644
index 0000000..56280f6
--- /dev/null
+++ b/cli/pkg/output/formatter.go
@@ -0,0 +1,266 @@
+package output
+
+import (
+	"encoding/csv"
+	"encoding/json"
+	"fmt"
+	"io"
+	"reflect"
+	"strings"
+
+	"github.com/olekukonko/tablewriter"
+)
+
+// Format represents the output format
+type Format string
+
+const (
+	FormatTable Format = "table"
+	FormatJSON  Format = "json"
+	FormatCSV   Format = "csv"
+)
+
+// Formatter handles output formatting
+type Formatter struct {
+	format Format
+	writer io.Writer
+}
+
+// NewFormatter creates a new formatter
+func NewFormatter(format Format, writer io.Writer) *Formatter {
+	return &Formatter{
+		format: format,
+		writer: writer,
+	}
+}
+
+// WriteTable writes data as a table
+func (f *Formatter) WriteTable(data interface{}, headers []string) error {
+	table := tablewriter.NewWriter(f.writer)
+	table.SetHeader(headers)
+	table.SetBorder(true)
+	table.SetCenterSeparator("|")
+	table.SetColumnSeparator("|")
+	table.SetRowSeparator("-")
+	table.SetHeaderLine(true)
+	table.SetTablePadding(" ")
+	table.SetNoWhiteSpace(true)
+	table.SetAutoWrapText(false)
+	table.SetReflowDuringAutoWrap(false)
+
+	// Convert data to rows
+	rows := f.convertToRows(data)
+	for _, row := range rows {
+		table.Append(row)
+	}
+
+	table.Render()
+	return nil
+}
+
+// WriteJSON writes data as JSON
+func (f *Formatter) WriteJSON(data interface{}) error {
+	encoder := json.NewEncoder(f.writer)
+	encoder.SetIndent("", "  ")
+	return encoder.Encode(data)
+}
+
+// WriteCSV writes data as CSV
+func (f *Formatter) WriteCSV(data interface{}, headers []string) error {
+	writer := csv.NewWriter(f.writer)
+	defer writer.Flush()
+
+	// Write headers
+	if err := writer.Write(headers); err != nil {
+		return fmt.Errorf("failed to write CSV headers: %w", err)
+	}
+
+	// Convert data to rows
+	rows := f.convertToRows(data)
+	for _, row := range rows {
+		if err := writer.Write(row); err != nil {
+			return fmt.Errorf("failed to write CSV row: %w", err)
+		}
+	}
+
+	return nil
+}
+
+// Write writes data in the specified format
+func (f *Formatter) Write(data interface{}, headers []string) error {
+	switch f.format {
+	case FormatTable:
+		return f.WriteTable(data, headers)
+	case FormatJSON:
+		return f.WriteJSON(data)
+	case FormatCSV:
+		return f.WriteCSV(data, headers)
+	default:
+		return fmt.Errorf("unsupported format: %s", f.format)
+	}
+}
+
+// convertToRows converts data to string rows for table/CSV output
+func (f *Formatter) convertToRows(data interface{}) [][]string {
+	var rows [][]string
+
+	// Handle different data types
+	switch v := data.(type) {
+	case []map[string]interface{}:
+		for _, item := range v {
+			row := make([]string, 0, len(item))
+			for _, value := range item {
+				row = append(row, f.formatValue(value))
+			}
+			rows = append(rows, row)
+		}
+	case []interface{}:
+		for _, item := range v {
+			row := f.convertItemToRow(item)
+			rows = append(rows, row)
+		}
+	case map[string]interface{}:
+		// Single item
+		row := f.convertItemToRow(v)
+		rows = append(rows, row)
+	default:
+		// Try to convert using reflection
+		rows = f.convertUsingReflection(data)
+	}
+
+	return rows
+}
+
+// convertItemToRow converts a single item to a string row
+func (f *Formatter) convertItemToRow(item interface{}) []string {
+	var row []string
+
+	switch v := item.(type) {
+	case map[string]interface{}:
+		for _, value := range v {
+			row = append(row, f.formatValue(value))
+		}
+	case []interface{}:
+		for _, value := range v {
+			row = append(row, f.formatValue(value))
+		}
+	default:
+		row = append(row, f.formatValue(v))
+	}
+
+	return row
+}
+
+// convertUsingReflection converts data using reflection
+func (f *Formatter) convertUsingReflection(data interface{}) [][]string {
+	var rows [][]string
+
+	val := reflect.ValueOf(data)
+	if val.Kind() == reflect.Ptr {
+		val = val.Elem()
+	}
+
+	switch val.Kind() {
+	case reflect.Slice, reflect.Array:
+		for i := 0; i < val.Len(); i++ {
+			item := val.Index(i)
+			row := f.convertStructToRow(item)
+			rows = append(rows, row)
+		}
+	case reflect.Struct:
+		row := f.convertStructToRow(val)
+		rows = append(rows, row)
+	}
+
+	return rows
+}
+
+// convertStructToRow converts a struct to a string row
+func (f *Formatter) convertStructToRow(val reflect.Value) []string {
+	var row []string
+
+	if val.Kind() == reflect.Ptr {
+		val = val.Elem()
+	}
+
+	if val.Kind() != reflect.Struct {
+		return []string{f.formatValue(val.Interface())}
+	}
+
+	typ := val.Type()
+	for i := 0; i < val.NumField(); i++ {
+		field := val.Field(i)
+		fieldType := typ.Field(i)
+
+		// Skip unexported fields
+		if !field.CanInterface() {
+			continue
+		}
+
+		// Use field name or json tag
+		_ = fieldType.Name
+		if jsonTag := fieldType.Tag.Get("json"); jsonTag != "" {
+			parts := strings.Split(jsonTag, ",")
+			if parts[0] != "" {
+				_ = parts[0]
+			}
+		}
+
+		value := f.formatValue(field.Interface())
+		row = append(row, value)
+	}
+
+	return row
+}
+
+// formatValue formats a value for display
+func (f *Formatter) formatValue(value interface{}) string {
+	if value == nil {
+		return ""
+	}
+
+	switch v := value.(type) {
+	case string:
+		return v
+	case int, int8, int16, int32, int64:
+		return fmt.Sprintf("%d", v)
+	case uint, uint8, uint16, uint32, uint64:
+		return fmt.Sprintf("%d", v)
+	case float32, float64:
+		return fmt.Sprintf("%.2f", v)
+	case bool:
+		return fmt.Sprintf("%t", v)
+	case []interface{}:
+		var parts []string
+		for _, item := range v {
+			parts = append(parts, f.formatValue(item))
+		}
+		return strings.Join(parts, ", ")
+	case map[string]interface{}:
+		// Convert map to key=value pairs
+		var parts []string
+		for key, val := range v {
+			parts = append(parts, fmt.Sprintf("%s=%s", key, f.formatValue(val)))
+		}
+		return strings.Join(parts, ", ")
+	default:
+		return fmt.Sprintf("%v", v)
+	}
+}
+
+// WriteError writes an error message
+func (f *Formatter) WriteError(err error) error {
+	errorData := map[string]string{
+		"error": err.Error(),
+	}
+	return f.WriteJSON(errorData)
+}
+
+// WriteSuccess writes a success message
+func (f *Formatter) WriteSuccess(message string) error {
+	successData := map[string]string{
+		"message": message,
+		"status":  "success",
+	}
+	return f.WriteJSON(successData)
+}