diff --git a/auth/oauth.go b/auth/oauth.go
new file mode 100644
index 0000000..acbc978
--- /dev/null
+++ b/auth/oauth.go
@@ -0,0 +1,152 @@
+package auth
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"time"
+
+	"golang.org/x/oauth2"
+	"golang.org/x/oauth2/clientcredentials"
+
+	"github.com/korap/korap-mcp/config"
+)
+
+// OAuthClient handles OAuth2 authentication for KorAP API
+type OAuthClient struct {
+	config       *config.OAuthConfig
+	oauth2Config *oauth2.Config
+	token        *oauth2.Token
+	httpClient   *http.Client
+}
+
+// NewOAuthClient creates a new OAuth2 client
+func NewOAuthClient(cfg *config.OAuthConfig) (*OAuthClient, error) {
+	if cfg == nil {
+		return nil, fmt.Errorf("oauth config cannot be nil")
+	}
+
+	if err := cfg.Validate(); err != nil {
+		return nil, fmt.Errorf("invalid oauth config: %w", err)
+	}
+
+	client := &OAuthClient{
+		config:       cfg,
+		oauth2Config: cfg.ToOAuth2Config(),
+	}
+
+	return client, nil
+}
+
+// GetAuthURL returns the authorization URL for the OAuth2 flow
+func (c *OAuthClient) GetAuthURL(state string) string {
+	if c.oauth2Config == nil {
+		return ""
+	}
+	return c.oauth2Config.AuthCodeURL(state, oauth2.AccessTypeOnline)
+}
+
+// ExchangeCode exchanges an authorization code for an access token
+func (c *OAuthClient) ExchangeCode(ctx context.Context, code string) error {
+	if c.oauth2Config == nil {
+		return fmt.Errorf("oauth2 not configured")
+	}
+
+	token, err := c.oauth2Config.Exchange(ctx, code)
+	if err != nil {
+		return fmt.Errorf("failed to exchange code for token: %w", err)
+	}
+
+	c.token = token
+	c.httpClient = c.oauth2Config.Client(ctx, token)
+	return nil
+}
+
+// SetToken sets the OAuth2 token directly
+func (c *OAuthClient) SetToken(token *oauth2.Token) {
+	c.token = token
+	if c.oauth2Config != nil {
+		c.httpClient = c.oauth2Config.Client(context.Background(), token)
+	}
+}
+
+// GetToken returns the current OAuth2 token
+func (c *OAuthClient) GetToken() *oauth2.Token {
+	return c.token
+}
+
+// GetHTTPClient returns an HTTP client with OAuth2 authentication
+func (c *OAuthClient) GetHTTPClient() *http.Client {
+	if c.httpClient != nil {
+		return c.httpClient
+	}
+
+	// Return default client if not authenticated
+	return &http.Client{
+		Timeout: time.Second * 30,
+	}
+}
+
+// IsAuthenticated checks if the client has a valid token
+func (c *OAuthClient) IsAuthenticated() bool {
+	if c.token == nil {
+		return false
+	}
+
+	// Check if token is expired (with 5 minute buffer)
+	return c.token.Valid() && c.token.Expiry.After(time.Now().Add(5*time.Minute))
+}
+
+// ClientCredentialsFlow performs client credentials OAuth2 flow
+func (c *OAuthClient) ClientCredentialsFlow(ctx context.Context) error {
+	if c.config == nil || !c.config.Enabled {
+		return fmt.Errorf("oauth2 not configured")
+	}
+
+	ccConfig := &clientcredentials.Config{
+		ClientID:     c.config.ClientID,
+		ClientSecret: c.config.ClientSecret,
+		TokenURL:     c.config.TokenURL,
+		Scopes:       c.config.Scopes,
+	}
+
+	token, err := ccConfig.Token(ctx)
+	if err != nil {
+		return fmt.Errorf("failed to get client credentials token: %w", err)
+	}
+
+	c.token = token
+	c.httpClient = ccConfig.Client(ctx)
+	return nil
+}
+
+// RefreshToken refreshes the OAuth2 token if possible
+func (c *OAuthClient) RefreshToken(ctx context.Context) error {
+	if c.oauth2Config == nil {
+		return fmt.Errorf("oauth2 not configured")
+	}
+
+	if c.token == nil {
+		return fmt.Errorf("no token to refresh")
+	}
+
+	tokenSource := c.oauth2Config.TokenSource(ctx, c.token)
+	newToken, err := tokenSource.Token()
+	if err != nil {
+		return fmt.Errorf("failed to refresh token: %w", err)
+	}
+
+	c.token = newToken
+	c.httpClient = c.oauth2Config.Client(ctx, newToken)
+	return nil
+}
+
+// AddAuthHeader adds authentication header to an HTTP request
+func (c *OAuthClient) AddAuthHeader(req *http.Request) error {
+	if c.token == nil {
+		return fmt.Errorf("no authentication token available")
+	}
+
+	c.token.SetAuthHeader(req)
+	return nil
+}
diff --git a/auth/oauth_test.go b/auth/oauth_test.go
new file mode 100644
index 0000000..9c6b0cc
--- /dev/null
+++ b/auth/oauth_test.go
@@ -0,0 +1,403 @@
+package auth
+
+import (
+	"context"
+	"encoding/json"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+	"time"
+
+	"github.com/korap/korap-mcp/config"
+	"github.com/stretchr/testify/assert"
+	"golang.org/x/oauth2"
+)
+
+func TestNewOAuthClient(t *testing.T) {
+	cfg := &config.OAuthConfig{
+		ClientID:     "test-client",
+		ClientSecret: "test-secret",
+		AuthURL:      "https://example.com/auth",
+		TokenURL:     "https://example.com/token",
+		Enabled:      true,
+	}
+
+	client, err := NewOAuthClient(cfg)
+	assert.NoError(t, err)
+	assert.NotNil(t, client)
+	assert.Equal(t, cfg, client.config)
+}
+
+func TestNewOAuthClient_InvalidConfig(t *testing.T) {
+	tests := []struct {
+		name   string
+		config *config.OAuthConfig
+	}{
+		{
+			name:   "nil config",
+			config: nil,
+		},
+		{
+			name: "empty client ID",
+			config: &config.OAuthConfig{
+				ClientSecret: "test-secret",
+				AuthURL:      "https://example.com/auth",
+				TokenURL:     "https://example.com/token",
+				Enabled:      true,
+			},
+		},
+		{
+			name: "empty client secret",
+			config: &config.OAuthConfig{
+				ClientID: "test-client",
+				AuthURL:  "https://example.com/auth",
+				TokenURL: "https://example.com/token",
+				Enabled:  true,
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			client, err := NewOAuthClient(tt.config)
+			assert.Error(t, err)
+			assert.Nil(t, client)
+		})
+	}
+}
+
+func TestOAuthClient_GetAuthURL(t *testing.T) {
+	cfg := &config.OAuthConfig{
+		ClientID:     "test-client",
+		ClientSecret: "test-secret",
+		AuthURL:      "https://example.com/auth",
+		TokenURL:     "https://example.com/token",
+		RedirectURL:  "https://example.com/callback",
+		Enabled:      true,
+	}
+
+	client, err := NewOAuthClient(cfg)
+	assert.NoError(t, err)
+
+	authURL := client.GetAuthURL("test-state")
+	assert.NotEmpty(t, authURL)
+
+	// Check if the URL contains expected parameters
+	assert.Contains(t, authURL, "client_id=test-client")
+	assert.Contains(t, authURL, "state=test-state")
+}
+
+func TestOAuthClient_IsAuthenticated(t *testing.T) {
+	cfg := &config.OAuthConfig{
+		ClientID:     "test-client",
+		ClientSecret: "test-secret",
+		AuthURL:      "https://example.com/auth",
+		TokenURL:     "https://example.com/token",
+		Enabled:      true,
+	}
+
+	client, err := NewOAuthClient(cfg)
+	assert.NoError(t, err)
+
+	// Should not be authenticated initially
+	assert.False(t, client.IsAuthenticated(), "client should not be authenticated initially")
+
+	// Set a valid token
+	validToken := &oauth2.Token{
+		AccessToken: "test-token",
+		Expiry:      time.Now().Add(time.Hour),
+	}
+	client.SetToken(validToken)
+
+	assert.True(t, client.IsAuthenticated(), "client should be authenticated with valid token")
+
+	// Set an expired token
+	expiredToken := &oauth2.Token{
+		AccessToken: "test-token",
+		Expiry:      time.Now().Add(-time.Hour),
+	}
+	client.SetToken(expiredToken)
+
+	assert.False(t, client.IsAuthenticated(), "client should not be authenticated with expired token")
+}
+
+func TestOAuthClient_ExchangeCode(t *testing.T) {
+	// Create mock OAuth2 server
+	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		if r.URL.Path == "/token" {
+			w.Header().Set("Content-Type", "application/json")
+			response := map[string]interface{}{
+				"access_token": "test-access-token",
+				"token_type":   "Bearer",
+				"expires_in":   3600,
+			}
+			json.NewEncoder(w).Encode(response)
+			return
+		}
+		http.NotFound(w, r)
+	}))
+	defer server.Close()
+
+	cfg := &config.OAuthConfig{
+		ClientID:     "test-client",
+		ClientSecret: "test-secret",
+		AuthURL:      server.URL + "/auth",
+		TokenURL:     server.URL + "/token",
+		Enabled:      true,
+	}
+
+	client, err := NewOAuthClient(cfg)
+	assert.NoError(t, err)
+
+	err = client.ExchangeCode(context.Background(), "test-code")
+	assert.NoError(t, err)
+
+	token := client.GetToken()
+	assert.NotNil(t, token)
+	assert.Equal(t, "test-access-token", token.AccessToken)
+}
+
+func TestOAuthClient_ClientCredentialsFlow(t *testing.T) {
+	// Create mock OAuth2 server
+	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		if r.URL.Path == "/token" {
+			w.Header().Set("Content-Type", "application/json")
+			response := map[string]interface{}{
+				"access_token": "client-credentials-token",
+				"token_type":   "Bearer",
+				"expires_in":   3600,
+			}
+			json.NewEncoder(w).Encode(response)
+			return
+		}
+		http.NotFound(w, r)
+	}))
+	defer server.Close()
+
+	cfg := &config.OAuthConfig{
+		ClientID:     "test-client",
+		ClientSecret: "test-secret",
+		TokenURL:     server.URL + "/token",
+		Scopes:       []string{"read"},
+		Enabled:      true,
+	}
+
+	client, err := NewOAuthClient(cfg)
+	assert.NoError(t, err)
+
+	err = client.ClientCredentialsFlow(context.Background())
+	assert.NoError(t, err)
+
+	token := client.GetToken()
+	assert.NotNil(t, token)
+	assert.Equal(t, "client-credentials-token", token.AccessToken)
+}
+
+func TestOAuthClient_GetHTTPClient(t *testing.T) {
+	cfg := &config.OAuthConfig{
+		ClientID:     "test-client",
+		ClientSecret: "test-secret",
+		AuthURL:      "https://example.com/auth",
+		TokenURL:     "https://example.com/token",
+		Enabled:      true,
+	}
+
+	client, err := NewOAuthClient(cfg)
+	assert.NoError(t, err)
+
+	httpClient := client.GetHTTPClient()
+	assert.NotNil(t, httpClient)
+
+	// Should return default client when not authenticated
+	assert.Equal(t, 30*time.Second, httpClient.Timeout)
+}
+
+func TestOAuthClient_AddAuthHeader(t *testing.T) {
+	cfg := &config.OAuthConfig{
+		ClientID:     "test-client",
+		ClientSecret: "test-secret",
+		AuthURL:      "https://example.com/auth",
+		TokenURL:     "https://example.com/token",
+		Enabled:      true,
+	}
+
+	client, err := NewOAuthClient(cfg)
+	assert.NoError(t, err)
+
+	req, _ := http.NewRequest("GET", "https://example.com/api", nil)
+
+	// Should fail when no token is set
+	err = client.AddAuthHeader(req)
+	assert.Error(t, err, "expected error when no token is available")
+
+	// Set a token and try again
+	token := &oauth2.Token{
+		AccessToken: "test-token",
+		TokenType:   "Bearer",
+	}
+	client.SetToken(token)
+
+	err = client.AddAuthHeader(req)
+	assert.NoError(t, err)
+
+	authHeader := req.Header.Get("Authorization")
+	assert.Equal(t, "Bearer test-token", authHeader)
+}
+
+func TestOAuthClient_RefreshToken(t *testing.T) {
+	// Create mock OAuth2 server
+	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		if r.URL.Path == "/token" {
+			w.Header().Set("Content-Type", "application/json")
+			response := map[string]interface{}{
+				"access_token":  "refreshed-access-token",
+				"refresh_token": "new-refresh-token",
+				"token_type":    "Bearer",
+				"expires_in":    3600,
+			}
+			json.NewEncoder(w).Encode(response)
+			return
+		}
+		http.NotFound(w, r)
+	}))
+	defer server.Close()
+
+	cfg := &config.OAuthConfig{
+		ClientID:     "test-client",
+		ClientSecret: "test-secret",
+		AuthURL:      server.URL + "/auth",
+		TokenURL:     server.URL + "/token",
+		Enabled:      true,
+	}
+
+	client, err := NewOAuthClient(cfg)
+	assert.NoError(t, err)
+
+	// Set an initial token with refresh token
+	initialToken := &oauth2.Token{
+		AccessToken:  "initial-token",
+		RefreshToken: "refresh-token",
+		Expiry:       time.Now().Add(-time.Hour), // Expired
+	}
+	client.SetToken(initialToken)
+
+	err = client.RefreshToken(context.Background())
+	assert.NoError(t, err)
+
+	token := client.GetToken()
+	assert.NotNil(t, token)
+	assert.Equal(t, "refreshed-access-token", token.AccessToken)
+}
+
+func TestOAuthClient_RefreshToken_Errors(t *testing.T) {
+	cfg := &config.OAuthConfig{
+		ClientID:     "test-client",
+		ClientSecret: "test-secret",
+		AuthURL:      "https://example.com/auth",
+		TokenURL:     "https://example.com/token",
+		Enabled:      true,
+	}
+
+	client, err := NewOAuthClient(cfg)
+	assert.NoError(t, err)
+
+	// Test refresh without token
+	err = client.RefreshToken(context.Background())
+	assert.Error(t, err, "expected error when refreshing without token")
+
+	// Test refresh with unconfigured OAuth2
+	client.oauth2Config = nil
+	client.SetToken(&oauth2.Token{AccessToken: "test"})
+	err = client.RefreshToken(context.Background())
+	assert.Error(t, err, "expected error when OAuth2 not configured")
+}
+
+func TestOAuthClient_TokenExpiration(t *testing.T) {
+	cfg := &config.OAuthConfig{
+		ClientID:     "test-client",
+		ClientSecret: "test-secret",
+		TokenURL:     "https://example.com/token",
+		Enabled:      true,
+	}
+
+	client, err := NewOAuthClient(cfg)
+	assert.NoError(t, err)
+
+	// Test with token expiring soon (within 5 minute buffer)
+	soonExpiredToken := &oauth2.Token{
+		AccessToken: "test-token",
+		Expiry:      time.Now().Add(2 * time.Minute), // Expires in 2 minutes
+	}
+	client.SetToken(soonExpiredToken)
+
+	assert.False(t, client.IsAuthenticated(), "client should not be authenticated with soon-to-expire token")
+
+	// Test with token expiring later (outside 5 minute buffer)
+	validToken := &oauth2.Token{
+		AccessToken: "test-token",
+		Expiry:      time.Now().Add(10 * time.Minute), // Expires in 10 minutes
+	}
+	client.SetToken(validToken)
+
+	assert.True(t, client.IsAuthenticated(), "client should be authenticated with valid token")
+}
+
+func TestOAuthClient_ErrorHandling(t *testing.T) {
+	cfg := &config.OAuthConfig{
+		ClientID:     "test-client",
+		ClientSecret: "test-secret",
+		AuthURL:      "https://invalid-server.example.com/auth",
+		TokenURL:     "https://invalid-server.example.com/token",
+		Enabled:      true,
+	}
+
+	client, err := NewOAuthClient(cfg)
+	assert.NoError(t, err)
+
+	// Test client credentials flow with invalid server
+	err = client.ClientCredentialsFlow(context.Background())
+	assert.Error(t, err, "expected error when connecting to invalid server")
+
+	// Test code exchange with invalid server
+	err = client.ExchangeCode(context.Background(), "test-code")
+	assert.Error(t, err, "expected error when connecting to invalid server")
+}
+
+func TestOAuthClient_DisabledOAuth(t *testing.T) {
+	cfg := &config.OAuthConfig{
+		ClientID:     "test-client",
+		ClientSecret: "test-secret",
+		Enabled:      false,
+	}
+
+	client, err := NewOAuthClient(cfg)
+	assert.NoError(t, err)
+
+	httpClient := client.GetHTTPClient()
+	assert.NotNil(t, httpClient, "HTTP client should not be nil even when OAuth is disabled")
+
+	authURL := client.GetAuthURL("test-state")
+	assert.Empty(t, authURL, "auth URL should be empty when OAuth is disabled")
+
+	err = client.ClientCredentialsFlow(context.Background())
+	assert.Error(t, err, "expected error when trying client credentials flow with disabled OAuth")
+}
+
+func TestOAuthClient_ContextCancellation(t *testing.T) {
+	cfg := &config.OAuthConfig{
+		ClientID:     "test-client",
+		ClientSecret: "test-secret",
+		TokenURL:     "https://example.com/token",
+		Enabled:      true,
+	}
+
+	client, err := NewOAuthClient(cfg)
+	assert.NoError(t, err)
+
+	// Create a cancelled context
+	ctx, cancel := context.WithCancel(context.Background())
+	cancel()
+
+	err = client.ClientCredentialsFlow(ctx)
+	assert.Error(t, err, "expected error with cancelled context")
+}
