diff --git a/README.md b/README.md
index 0f3bb15e..4a4f7c4f 100644
--- a/README.md
+++ b/README.md
@@ -42,12 +42,23 @@ Copy your Personal Key to replace `your-zilliz-cloud-api-key` in the configurati
-Get OpenAI API Key for embedding model
+Get an API Key for embedding model
-You need an OpenAI API key for the embedding model. You can get one by signing up at [OpenAI](https://platform.openai.com/api-keys).
+You need an API key for the embedding model. Claude Context supports multiple providers:
-Your API key will look like this: it always starts with `sk-`.
-Copy your key and use it in the configuration examples below as `your-openai-api-key`.
+**Option 1: OpenAI**
+- Sign up at [OpenAI](https://platform.openai.com/api-keys)
+- Your API key will start with `sk-`
+- Use as `your-openai-api-key` in configuration
+
+**Option 2: Azure OpenAI**
+- Use your Azure OpenAI resource endpoint and API key
+- Requires deployment name instead of model name
+- See [Azure OpenAI Documentation](https://learn.microsoft.com/en-us/azure/ai-services/openai/)
+
+**Option 3: Other Providers**
+- VoyageAI, Gemini, or Ollama (local)
+- See [Provider Configuration Guide](packages/mcp/README.md#embedding-provider-configuration) for details
@@ -519,8 +530,7 @@ Claude Context is a monorepo containing three main packages:
- **`@zilliz/claude-context-mcp`**: Model Context Protocol server for AI agent integration
### Supported Technologies
-
-- **Embedding Providers**: [OpenAI](https://openai.com), [VoyageAI](https://voyageai.com), [Ollama](https://ollama.ai), [Gemini](https://gemini.google.com)
+- **Embedding Providers**: [OpenAI](https://openai.com), [Azure OpenAI](https://azure.microsoft.com/en-us/products/ai-services/openai-service), [VoyageAI](https://voyageai.com), [Ollama](https://ollama.ai), [Gemini](https://gemini.google.com)
- **Vector Databases**: [Milvus](https://milvus.io) or [Zilliz Cloud](https://zilliz.com/cloud)(fully managed vector database as a service)
- **Code Splitters**: AST-based splitter (with automatic fallback), LangChain character-based splitter
- **Languages**: TypeScript, JavaScript, Python, Java, C++, C#, Go, Rust, PHP, Ruby, Swift, Kotlin, Scala, Markdown
diff --git a/docs/getting-started/environment-variables.md b/docs/getting-started/environment-variables.md
index d2b813df..4c678db3 100644
--- a/docs/getting-started/environment-variables.md
+++ b/docs/getting-started/environment-variables.md
@@ -20,10 +20,14 @@ Claude Context supports a global configuration file at `~/.context/.env` to simp
### Embedding Provider
| Variable | Description | Default |
|----------|-------------|---------|
-| `EMBEDDING_PROVIDER` | Provider: `OpenAI`, `VoyageAI`, `Gemini`, `Ollama` | `OpenAI` |
+| `EMBEDDING_PROVIDER` | Provider: `OpenAI`, `AzureOpenAI`, `VoyageAI`, `Gemini`, `Ollama` | `OpenAI` |
| `EMBEDDING_MODEL` | Embedding model name (works for all providers) | Provider-specific default |
| `OPENAI_API_KEY` | OpenAI API key | Required for OpenAI |
| `OPENAI_BASE_URL` | OpenAI API base URL (optional, for custom endpoints) | `https://api.openai.com/v1` |
+| `AZURE_OPENAI_API_KEY` | Azure OpenAI API key | Required for Azure OpenAI |
+| `AZURE_OPENAI_ENDPOINT` | Azure OpenAI endpoint URL | Required for Azure OpenAI |
+| `AZURE_OPENAI_DEPLOYMENT_NAME` | Azure deployment name | Required for Azure OpenAI |
+| `AZURE_OPENAI_API_VERSION` | Azure API version | `2024-02-01` |
| `VOYAGEAI_API_KEY` | VoyageAI API key | Required for VoyageAI |
| `GEMINI_API_KEY` | Gemini API key | Required for Gemini |
| `GEMINI_BASE_URL` | Gemini API base URL (optional, for custom endpoints) | `https://generativelanguage.googleapis.com/v1beta` |
@@ -33,6 +37,8 @@ Claude Context supports a global configuration file at `~/.context/.env` to simp
> **Supported Model Names:**
>
> - OpenAI Models: See `getSupportedModels` in [`openai-embedding.ts`](https://github.com/zilliztech/claude-context/blob/master/packages/core/src/embedding/openai-embedding.ts) for the full list of supported models.
+>
+> - Azure OpenAI: Uses deployment names instead of model names. Supports the same models as OpenAI (text-embedding-3-small, text-embedding-3-large, text-embedding-ada-002).
>
> - VoyageAI Models: See `getSupportedModels` in [`voyageai-embedding.ts`](https://github.com/zilliztech/claude-context/blob/master/packages/core/src/embedding/voyageai-embedding.ts) for the full list of supported models.
>
@@ -67,6 +73,8 @@ Claude Context supports a global configuration file at `~/.context/.env` to simp
## 🚀 Quick Setup
### 1. Create Global Config
+
+**Option A: OpenAI**
```bash
mkdir -p ~/.context
cat > ~/.context/.env << 'EOF'
@@ -77,6 +85,18 @@ MILVUS_TOKEN=your-zilliz-cloud-api-key
EOF
```
+**Option B: Azure OpenAI**
+```bash
+mkdir -p ~/.context
+cat > ~/.context/.env << 'EOF'
+EMBEDDING_PROVIDER=AzureOpenAI
+AZURE_OPENAI_API_KEY=your-azure-api-key
+AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com
+AZURE_OPENAI_DEPLOYMENT_NAME=text-embedding-3-small-deployment
+MILVUS_TOKEN=your-zilliz-cloud-api-key
+EOF
+```
+
See the [Example File](../../.env.example) for more details.
### 2. Simplified MCP Configuration
diff --git a/packages/core/README.md b/packages/core/README.md
index 3ea03911..3d187755 100644
--- a/packages/core/README.md
+++ b/packages/core/README.md
@@ -105,6 +105,7 @@ results.forEach(result => {
## Embedding Providers
- **OpenAI Embeddings** (`text-embedding-3-small`, `text-embedding-3-large`, `text-embedding-ada-002`)
+- **Azure OpenAI Embeddings** - Same models as OpenAI, deployed on Azure infrastructure
- **VoyageAI Embeddings** - High-quality embeddings optimized for code (`voyage-code-3`, `voyage-3.5`, etc.)
- **Gemini Embeddings** - Google's embedding models (`gemini-embedding-001`)
- **Ollama Embeddings** - Local embedding models via Ollama
@@ -190,6 +191,30 @@ interface SemanticSearchResult {
## Examples
+### Using Azure OpenAI Embeddings
+
+```typescript
+import { Context, MilvusVectorDatabase, AzureOpenAIEmbedding } from '@zilliz/claude-context-core';
+
+// Initialize with Azure OpenAI embedding provider
+const embedding = new AzureOpenAIEmbedding({
+ deploymentName: 'text-embedding-3-small-deployment',
+ apiKey: process.env.AZURE_OPENAI_API_KEY || 'your-azure-api-key',
+ azureEndpoint: process.env.AZURE_OPENAI_ENDPOINT || 'https://your-resource.openai.azure.com',
+ apiVersion: '2024-02-01' // Optional
+});
+
+const vectorDatabase = new MilvusVectorDatabase({
+ address: process.env.MILVUS_ADDRESS || 'localhost:19530',
+ token: process.env.MILVUS_TOKEN || ''
+});
+
+const context = new Context({
+ embedding,
+ vectorDatabase
+});
+```
+
### Using VoyageAI Embeddings
```typescript
diff --git a/packages/core/src/embedding/azure-openai-embedding.ts b/packages/core/src/embedding/azure-openai-embedding.ts
new file mode 100644
index 00000000..0e723aca
--- /dev/null
+++ b/packages/core/src/embedding/azure-openai-embedding.ts
@@ -0,0 +1,256 @@
+import { AzureOpenAI } from 'openai';
+import { Embedding, EmbeddingVector } from './base-embedding';
+
+export interface AzureOpenAIEmbeddingConfig {
+ deploymentName: string; // Azure deployment name (not model name)
+ apiKey: string; // Azure OpenAI API key
+ azureEndpoint: string; // Required: Azure endpoint URL
+ apiVersion?: string; // Optional: defaults to stable version
+}
+
+export class AzureOpenAIEmbedding extends Embedding {
+ private client: AzureOpenAI;
+ private config: AzureOpenAIEmbeddingConfig;
+ private dimension: number = 1536; // Default dimension for text-embedding-3-small
+ protected maxTokens: number = 8192; // Maximum tokens for OpenAI embedding models
+
+ constructor(config: AzureOpenAIEmbeddingConfig) {
+ super();
+ this.config = config;
+
+ // Validate endpoint format
+ if (!config.azureEndpoint.startsWith('https://')) {
+ throw new Error('Azure OpenAI endpoint must start with https://');
+ }
+
+ // Initialize Azure OpenAI client with API key authentication
+ this.client = new AzureOpenAI({
+ apiKey: config.apiKey,
+ apiVersion: config.apiVersion || '2024-02-01', // Use stable version
+ endpoint: config.azureEndpoint,
+ });
+ }
+
+ async detectDimension(testText: string = "test"): Promise {
+ const knownModels = AzureOpenAIEmbedding.getSupportedModels();
+
+ // Try to infer from deployment name if it matches known patterns
+ // Azure deployment names often include the model name with dashes
+ for (const [modelName, info] of Object.entries(knownModels)) {
+ // Check if deployment name contains model pattern (with dashes instead of dots)
+ const modelPattern = modelName.replace(/\./g, '-');
+ if (this.config.deploymentName.toLowerCase().includes(modelPattern)) {
+ return info.dimension;
+ }
+ }
+
+ // Dynamic detection via API call for custom deployments
+ try {
+ const processedText = this.preprocessText(testText);
+ const response = await this.client.embeddings.create({
+ model: this.config.deploymentName, // Use deployment name
+ input: processedText,
+ encoding_format: 'float',
+ });
+ return response.data[0].embedding.length;
+ } catch (error) {
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
+
+ // Re-throw authentication errors
+ if (errorMessage.includes('API key') || errorMessage.includes('unauthorized') || errorMessage.includes('authentication')) {
+ throw new Error(`Azure OpenAI authentication failed: ${errorMessage}`);
+ }
+
+ // Handle deployment not found errors
+ if (errorMessage.includes('deployment') || errorMessage.includes('not found')) {
+ throw new Error(`Azure OpenAI deployment '${this.config.deploymentName}' not found: ${errorMessage}`);
+ }
+
+ throw new Error(`Failed to detect dimension for Azure deployment ${this.config.deploymentName}: ${errorMessage}`);
+ }
+ }
+
+ async embed(text: string): Promise {
+ const processedText = this.preprocessText(text);
+
+ // Check if we need to detect dimension
+ const knownModels = AzureOpenAIEmbedding.getSupportedModels();
+ let needsDimensionDetection = true;
+
+ for (const [modelName, info] of Object.entries(knownModels)) {
+ const modelPattern = modelName.replace(/\./g, '-');
+ if (this.config.deploymentName.toLowerCase().includes(modelPattern)) {
+ this.dimension = info.dimension;
+ needsDimensionDetection = false;
+ break;
+ }
+ }
+
+ if (needsDimensionDetection && this.dimension === 1536) {
+ // Only detect if we haven't already and are using default
+ this.dimension = await this.detectDimension();
+ }
+
+ try {
+ const response = await this.client.embeddings.create({
+ model: this.config.deploymentName, // Use deployment name
+ input: processedText,
+ encoding_format: 'float',
+ });
+
+ // Update dimension from actual response
+ this.dimension = response.data[0].embedding.length;
+
+ return {
+ vector: response.data[0].embedding,
+ dimension: this.dimension
+ };
+ } catch (error) {
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
+
+ // Provide specific error messages for common Azure issues
+ if (errorMessage.includes('API key') || errorMessage.includes('unauthorized')) {
+ throw new Error(`Azure OpenAI authentication failed: ${errorMessage}`);
+ }
+
+ if (errorMessage.includes('deployment') || errorMessage.includes('not found')) {
+ throw new Error(`Azure OpenAI deployment '${this.config.deploymentName}' not found: ${errorMessage}`);
+ }
+
+ if (errorMessage.includes('rate limit') || errorMessage.includes('quota')) {
+ throw new Error(`Azure OpenAI rate limit exceeded: ${errorMessage}`);
+ }
+
+ throw new Error(`Failed to generate Azure OpenAI embedding: ${errorMessage}`);
+ }
+ }
+
+ async embedBatch(texts: string[]): Promise {
+ const processedTexts = this.preprocessTexts(texts);
+
+ // Check if we need to detect dimension
+ const knownModels = AzureOpenAIEmbedding.getSupportedModels();
+ let needsDimensionDetection = true;
+
+ for (const [modelName, info] of Object.entries(knownModels)) {
+ const modelPattern = modelName.replace(/\./g, '-');
+ if (this.config.deploymentName.toLowerCase().includes(modelPattern)) {
+ this.dimension = info.dimension;
+ needsDimensionDetection = false;
+ break;
+ }
+ }
+
+ if (needsDimensionDetection && this.dimension === 1536) {
+ this.dimension = await this.detectDimension();
+ }
+
+ try {
+ const response = await this.client.embeddings.create({
+ model: this.config.deploymentName, // Use deployment name
+ input: processedTexts,
+ encoding_format: 'float',
+ });
+
+ // Update dimension from actual response
+ this.dimension = response.data[0].embedding.length;
+
+ return response.data.map((item) => ({
+ vector: item.embedding,
+ dimension: this.dimension
+ }));
+ } catch (error) {
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
+
+ // Provide specific error messages for common Azure issues
+ if (errorMessage.includes('API key') || errorMessage.includes('unauthorized')) {
+ throw new Error(`Azure OpenAI authentication failed: ${errorMessage}`);
+ }
+
+ if (errorMessage.includes('deployment') || errorMessage.includes('not found')) {
+ throw new Error(`Azure OpenAI deployment '${this.config.deploymentName}' not found: ${errorMessage}`);
+ }
+
+ if (errorMessage.includes('rate limit') || errorMessage.includes('quota')) {
+ throw new Error(`Azure OpenAI rate limit exceeded: ${errorMessage}`);
+ }
+
+ throw new Error(`Failed to generate Azure OpenAI batch embeddings: ${errorMessage}`);
+ }
+ }
+
+ getDimension(): number {
+ // Check if deployment name matches known models
+ const knownModels = AzureOpenAIEmbedding.getSupportedModels();
+
+ for (const [modelName, info] of Object.entries(knownModels)) {
+ const modelPattern = modelName.replace(/\./g, '-');
+ if (this.config.deploymentName.toLowerCase().includes(modelPattern)) {
+ return info.dimension;
+ }
+ }
+
+ // For custom deployments, return the current dimension
+ // Note: This may be incorrect until detectDimension() is called
+ console.warn(`[AzureOpenAIEmbedding] ⚠️ getDimension() called for deployment '${this.config.deploymentName}' - returning ${this.dimension}. Call detectDimension() first for accurate dimension.`);
+ return this.dimension;
+ }
+
+ getProvider(): string {
+ return 'Azure OpenAI';
+ }
+
+ /**
+ * Set deployment name
+ * @param deploymentName Azure deployment name
+ */
+ async setDeployment(deploymentName: string): Promise {
+ this.config.deploymentName = deploymentName;
+
+ // Check if this matches a known model
+ const knownModels = AzureOpenAIEmbedding.getSupportedModels();
+ let foundKnownModel = false;
+
+ for (const [modelName, info] of Object.entries(knownModels)) {
+ const modelPattern = modelName.replace(/\./g, '-');
+ if (deploymentName.toLowerCase().includes(modelPattern)) {
+ this.dimension = info.dimension;
+ foundKnownModel = true;
+ break;
+ }
+ }
+
+ if (!foundKnownModel) {
+ // Detect dimension for custom deployment
+ this.dimension = await this.detectDimension();
+ }
+ }
+
+ /**
+ * Get client instance (for advanced usage)
+ */
+ getClient(): AzureOpenAI {
+ return this.client;
+ }
+
+ /**
+ * Get list of supported models (these are OpenAI model names, not Azure deployment names)
+ * Azure deployments can be named anything, but often include the model name
+ */
+ static getSupportedModels(): Record {
+ return {
+ 'text-embedding-3-small': {
+ dimension: 1536,
+ description: 'High performance and cost-effective embedding model (recommended)'
+ },
+ 'text-embedding-3-large': {
+ dimension: 3072,
+ description: 'Highest performance embedding model with larger dimensions'
+ },
+ 'text-embedding-ada-002': {
+ dimension: 1536,
+ description: 'Legacy model (use text-embedding-3-small instead)'
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/packages/core/src/embedding/index.ts b/packages/core/src/embedding/index.ts
index e6110941..4aede51c 100644
--- a/packages/core/src/embedding/index.ts
+++ b/packages/core/src/embedding/index.ts
@@ -3,6 +3,7 @@ export * from './base-embedding';
// Implementation class exports
export * from './openai-embedding';
+export * from './azure-openai-embedding';
export * from './voyageai-embedding';
export * from './ollama-embedding';
export * from './gemini-embedding';
\ No newline at end of file
diff --git a/packages/mcp/README.md b/packages/mcp/README.md
index 3591ca78..f9783c30 100644
--- a/packages/mcp/README.md
+++ b/packages/mcp/README.md
@@ -34,7 +34,7 @@ Claude Context MCP supports multiple embedding providers. Choose the one that be
> 📋 **Quick Reference**: For a complete list of environment variables and their descriptions, see the [Environment Variables Guide](../../docs/getting-started/environment-variables.md).
```bash
-# Supported providers: OpenAI, VoyageAI, Gemini, Ollama
+# Supported providers: OpenAI, AzureOpenAI, VoyageAI, Gemini, Ollama
EMBEDDING_PROVIDER=OpenAI
```
@@ -67,7 +67,36 @@ See `getSupportedModels` in [`openai-embedding.ts`](https://github.com/zilliztec
-2. VoyageAI Configuration
+2. Azure OpenAI Configuration
+
+Azure OpenAI provides the same high-quality embeddings as OpenAI through your Azure infrastructure.
+
+```bash
+# Required: Your Azure OpenAI configuration
+EMBEDDING_PROVIDER=AzureOpenAI
+AZURE_OPENAI_API_KEY=your-azure-api-key
+AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com
+AZURE_OPENAI_DEPLOYMENT_NAME=text-embedding-3-small-deployment
+
+# Optional: API version (default: 2024-02-01)
+AZURE_OPENAI_API_VERSION=2024-02-01
+```
+
+**Configuration Requirements:**
+- `AZURE_OPENAI_ENDPOINT`: Your Azure OpenAI resource endpoint
+- `AZURE_OPENAI_DEPLOYMENT_NAME`: Your deployment name (not model name)
+- `AZURE_OPENAI_API_KEY`: Your Azure OpenAI API key
+
+**Getting Started with Azure OpenAI:**
+1. Create an Azure OpenAI resource in [Azure Portal](https://portal.azure.com)
+2. Deploy an embedding model (e.g., text-embedding-3-small)
+3. Copy your endpoint URL and API key from Azure Portal
+4. Use the deployment name you created (not the model name)
+
+
+
+
+3. VoyageAI Configuration
VoyageAI offers specialized code embeddings optimized for programming languages.
@@ -92,7 +121,7 @@ See `getSupportedModels` in [`voyageai-embedding.ts`](https://github.com/zillizt
-3. Gemini Configuration
+4. Gemini Configuration
Google's Gemini provides competitive embeddings with good multilingual support.
@@ -120,7 +149,7 @@ See `getSupportedModels` in [`gemini-embedding.ts`](https://github.com/zilliztec
-4. Ollama Configuration (Local/Self-hosted)
+5. Ollama Configuration (Local/Self-hosted)
Ollama allows you to run embeddings locally without sending data to external services.
@@ -275,6 +304,25 @@ Pasting the following configuration into your Cursor `~/.cursor/mcp.json` file i
}
```
+**Azure OpenAI Configuration:**
+```json
+{
+ "mcpServers": {
+ "claude-context": {
+ "command": "npx",
+ "args": ["-y", "@zilliz/claude-context-mcp@latest"],
+ "env": {
+ "EMBEDDING_PROVIDER": "AzureOpenAI",
+ "AZURE_OPENAI_API_KEY": "your-azure-api-key",
+ "AZURE_OPENAI_ENDPOINT": "https://your-resource.openai.azure.com",
+ "AZURE_OPENAI_DEPLOYMENT_NAME": "text-embedding-3-small-deployment",
+ "MILVUS_TOKEN": "your-zilliz-cloud-api-key"
+ }
+ }
+ }
+}
+```
+
**VoyageAI Configuration:**
```json
diff --git a/packages/mcp/src/config.ts b/packages/mcp/src/config.ts
index 428f9474..69e45b27 100644
--- a/packages/mcp/src/config.ts
+++ b/packages/mcp/src/config.ts
@@ -4,11 +4,16 @@ export interface ContextMcpConfig {
name: string;
version: string;
// Embedding provider configuration
- embeddingProvider: 'OpenAI' | 'VoyageAI' | 'Gemini' | 'Ollama';
+ embeddingProvider: 'OpenAI' | 'AzureOpenAI' | 'VoyageAI' | 'Gemini' | 'Ollama';
embeddingModel: string;
// Provider-specific API keys
openaiApiKey?: string;
openaiBaseUrl?: string;
+ // Azure OpenAI configuration
+ azureOpenaiApiKey?: string;
+ azureOpenaiEndpoint?: string;
+ azureOpenaiApiVersion?: string;
+ azureOpenaiDeploymentName?: string;
voyageaiApiKey?: string;
geminiApiKey?: string;
geminiBaseUrl?: string;
@@ -72,6 +77,8 @@ export function getDefaultModelForProvider(provider: string): string {
switch (provider) {
case 'OpenAI':
return 'text-embedding-3-small';
+ case 'AzureOpenAI':
+ return 'text-embedding-3-small-deployment'; // Default deployment name
case 'VoyageAI':
return 'voyage-code-3';
case 'Gemini':
@@ -91,6 +98,11 @@ export function getEmbeddingModelForProvider(provider: string): string {
const ollamaModel = envManager.get('OLLAMA_MODEL') || envManager.get('EMBEDDING_MODEL') || getDefaultModelForProvider(provider);
console.log(`[DEBUG] 🎯 Ollama model selection: OLLAMA_MODEL=${envManager.get('OLLAMA_MODEL') || 'NOT SET'}, EMBEDDING_MODEL=${envManager.get('EMBEDDING_MODEL') || 'NOT SET'}, selected=${ollamaModel}`);
return ollamaModel;
+ case 'AzureOpenAI':
+ // For Azure OpenAI, use AZURE_OPENAI_DEPLOYMENT_NAME or EMBEDDING_MODEL
+ const azureDeployment = envManager.get('AZURE_OPENAI_DEPLOYMENT_NAME') || envManager.get('EMBEDDING_MODEL') || getDefaultModelForProvider(provider);
+ console.log(`[DEBUG] 🎯 Azure OpenAI deployment selection: AZURE_OPENAI_DEPLOYMENT_NAME=${envManager.get('AZURE_OPENAI_DEPLOYMENT_NAME') || 'NOT SET'}, EMBEDDING_MODEL=${envManager.get('EMBEDDING_MODEL') || 'NOT SET'}, selected=${azureDeployment}`);
+ return azureDeployment;
case 'OpenAI':
case 'VoyageAI':
case 'Gemini':
@@ -110,6 +122,8 @@ export function createMcpConfig(): ContextMcpConfig {
console.log(`[DEBUG] OLLAMA_MODEL: ${envManager.get('OLLAMA_MODEL') || 'NOT SET'}`);
console.log(`[DEBUG] GEMINI_API_KEY: ${envManager.get('GEMINI_API_KEY') ? 'SET (length: ' + envManager.get('GEMINI_API_KEY')!.length + ')' : 'NOT SET'}`);
console.log(`[DEBUG] OPENAI_API_KEY: ${envManager.get('OPENAI_API_KEY') ? 'SET (length: ' + envManager.get('OPENAI_API_KEY')!.length + ')' : 'NOT SET'}`);
+ console.log(`[DEBUG] AZURE_OPENAI_API_KEY: ${envManager.get('AZURE_OPENAI_API_KEY') ? 'SET (length: ' + envManager.get('AZURE_OPENAI_API_KEY')!.length + ')' : 'NOT SET'}`);
+ console.log(`[DEBUG] AZURE_OPENAI_ENDPOINT: ${envManager.get('AZURE_OPENAI_ENDPOINT') || 'NOT SET'}`);
console.log(`[DEBUG] MILVUS_ADDRESS: ${envManager.get('MILVUS_ADDRESS') || 'NOT SET'}`);
console.log(`[DEBUG] NODE_ENV: ${envManager.get('NODE_ENV') || 'NOT SET'}`);
@@ -117,11 +131,16 @@ export function createMcpConfig(): ContextMcpConfig {
name: envManager.get('MCP_SERVER_NAME') || "Context MCP Server",
version: envManager.get('MCP_SERVER_VERSION') || "1.0.0",
// Embedding provider configuration
- embeddingProvider: (envManager.get('EMBEDDING_PROVIDER') as 'OpenAI' | 'VoyageAI' | 'Gemini' | 'Ollama') || 'OpenAI',
+ embeddingProvider: (envManager.get('EMBEDDING_PROVIDER') as 'OpenAI' | 'AzureOpenAI' | 'VoyageAI' | 'Gemini' | 'Ollama') || 'OpenAI',
embeddingModel: getEmbeddingModelForProvider(envManager.get('EMBEDDING_PROVIDER') || 'OpenAI'),
// Provider-specific API keys
openaiApiKey: envManager.get('OPENAI_API_KEY'),
openaiBaseUrl: envManager.get('OPENAI_BASE_URL'),
+ // Azure OpenAI configuration
+ azureOpenaiApiKey: envManager.get('AZURE_OPENAI_API_KEY'),
+ azureOpenaiEndpoint: envManager.get('AZURE_OPENAI_ENDPOINT'),
+ azureOpenaiApiVersion: envManager.get('AZURE_OPENAI_API_VERSION'),
+ azureOpenaiDeploymentName: envManager.get('AZURE_OPENAI_DEPLOYMENT_NAME'),
voyageaiApiKey: envManager.get('VOYAGEAI_API_KEY'),
geminiApiKey: envManager.get('GEMINI_API_KEY'),
geminiBaseUrl: envManager.get('GEMINI_BASE_URL'),
@@ -153,6 +172,14 @@ export function logConfigurationSummary(config: ContextMcpConfig): void {
console.log(`[MCP] OpenAI Base URL: ${config.openaiBaseUrl}`);
}
break;
+ case 'AzureOpenAI':
+ console.log(`[MCP] Azure OpenAI API Key: ${config.azureOpenaiApiKey ? '✅ Configured' : '❌ Missing'}`);
+ console.log(`[MCP] Azure OpenAI Endpoint: ${config.azureOpenaiEndpoint || '❌ Missing'}`);
+ console.log(`[MCP] Azure OpenAI Deployment: ${config.azureOpenaiDeploymentName || config.embeddingModel}`);
+ if (config.azureOpenaiApiVersion) {
+ console.log(`[MCP] Azure OpenAI API Version: ${config.azureOpenaiApiVersion}`);
+ }
+ break;
case 'VoyageAI':
console.log(`[MCP] VoyageAI API Key: ${config.voyageaiApiKey ? '✅ Configured' : '❌ Missing'}`);
break;
@@ -185,12 +212,19 @@ Environment Variables:
MCP_SERVER_VERSION Server version
Embedding Provider Configuration:
- EMBEDDING_PROVIDER Embedding provider: OpenAI, VoyageAI, Gemini, Ollama (default: OpenAI)
+ EMBEDDING_PROVIDER Embedding provider: OpenAI, AzureOpenAI, VoyageAI, Gemini, Ollama (default: OpenAI)
EMBEDDING_MODEL Embedding model name (works for all providers)
Provider-specific API Keys:
OPENAI_API_KEY OpenAI API key (required for OpenAI provider)
OPENAI_BASE_URL OpenAI API base URL (optional, for custom endpoints)
+
+ Azure OpenAI Configuration:
+ AZURE_OPENAI_API_KEY Azure OpenAI API key (required for AzureOpenAI provider)
+ AZURE_OPENAI_ENDPOINT Azure OpenAI endpoint URL (required for AzureOpenAI provider)
+ AZURE_OPENAI_API_VERSION Azure OpenAI API version (optional, default: 2024-02-01)
+ AZURE_OPENAI_DEPLOYMENT_NAME Azure deployment name (required, alternative to EMBEDDING_MODEL)
+
VOYAGEAI_API_KEY VoyageAI API key (required for VoyageAI provider)
GEMINI_API_KEY Google AI API key (required for Gemini provider)
GEMINI_BASE_URL Gemini API base URL (optional, for custom endpoints)
@@ -213,6 +247,9 @@ Examples:
# Start MCP server with VoyageAI and specific model
EMBEDDING_PROVIDER=VoyageAI VOYAGEAI_API_KEY=pa-xxx EMBEDDING_MODEL=voyage-3-large MILVUS_TOKEN=your-token npx @zilliz/claude-context-mcp@latest
+ # Start MCP server with Azure OpenAI
+ EMBEDDING_PROVIDER=AzureOpenAI AZURE_OPENAI_API_KEY=xxx AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com AZURE_OPENAI_DEPLOYMENT_NAME=text-embedding-3-small-deployment npx @zilliz/claude-context-mcp@latest
+
# Start MCP server with Gemini and specific model
EMBEDDING_PROVIDER=Gemini GEMINI_API_KEY=xxx EMBEDDING_MODEL=gemini-embedding-001 MILVUS_TOKEN=your-token npx @zilliz/claude-context-mcp@latest
diff --git a/packages/mcp/src/embedding.ts b/packages/mcp/src/embedding.ts
index 6ebd71a0..76427063 100644
--- a/packages/mcp/src/embedding.ts
+++ b/packages/mcp/src/embedding.ts
@@ -1,8 +1,8 @@
-import { OpenAIEmbedding, VoyageAIEmbedding, GeminiEmbedding, OllamaEmbedding } from "@zilliz/claude-context-core";
+import { OpenAIEmbedding, AzureOpenAIEmbedding, VoyageAIEmbedding, GeminiEmbedding, OllamaEmbedding } from "@zilliz/claude-context-core";
import { ContextMcpConfig } from "./config.js";
// Helper function to create embedding instance based on provider
-export function createEmbeddingInstance(config: ContextMcpConfig): OpenAIEmbedding | VoyageAIEmbedding | GeminiEmbedding | OllamaEmbedding {
+export function createEmbeddingInstance(config: ContextMcpConfig): OpenAIEmbedding | AzureOpenAIEmbedding | VoyageAIEmbedding | GeminiEmbedding | OllamaEmbedding {
console.log(`[EMBEDDING] Creating ${config.embeddingProvider} embedding instance...`);
switch (config.embeddingProvider) {
@@ -20,6 +20,30 @@ export function createEmbeddingInstance(config: ContextMcpConfig): OpenAIEmbeddi
console.log(`[EMBEDDING] ✅ OpenAI embedding instance created successfully`);
return openaiEmbedding;
+ case 'AzureOpenAI':
+ if (!config.azureOpenaiEndpoint) {
+ console.error(`[EMBEDDING] ❌ Azure OpenAI endpoint is required but not provided`);
+ throw new Error('AZURE_OPENAI_ENDPOINT is required for Azure OpenAI embedding provider');
+ }
+ if (!config.azureOpenaiApiKey) {
+ console.error(`[EMBEDDING] ❌ Azure OpenAI API key is required but not provided`);
+ throw new Error('AZURE_OPENAI_API_KEY is required for Azure OpenAI embedding provider');
+ }
+ if (!config.azureOpenaiDeploymentName && !config.embeddingModel) {
+ console.error(`[EMBEDDING] ❌ Azure OpenAI deployment name is required but not provided`);
+ throw new Error('AZURE_OPENAI_DEPLOYMENT_NAME or EMBEDDING_MODEL is required for Azure OpenAI embedding provider');
+ }
+
+ console.log(`[EMBEDDING] 🔧 Configuring Azure OpenAI with deployment: ${config.azureOpenaiDeploymentName || config.embeddingModel}`);
+ const azureOpenaiEmbedding = new AzureOpenAIEmbedding({
+ deploymentName: config.azureOpenaiDeploymentName || config.embeddingModel,
+ azureEndpoint: config.azureOpenaiEndpoint,
+ apiVersion: config.azureOpenaiApiVersion,
+ apiKey: config.azureOpenaiApiKey,
+ });
+ console.log(`[EMBEDDING] ✅ Azure OpenAI embedding instance created successfully`);
+ return azureOpenaiEmbedding;
+
case 'VoyageAI':
if (!config.voyageaiApiKey) {
console.error(`[EMBEDDING] ❌ VoyageAI API key is required but not provided`);
@@ -63,7 +87,7 @@ export function createEmbeddingInstance(config: ContextMcpConfig): OpenAIEmbeddi
}
}
-export function logEmbeddingProviderInfo(config: ContextMcpConfig, embedding: OpenAIEmbedding | VoyageAIEmbedding | GeminiEmbedding | OllamaEmbedding): void {
+export function logEmbeddingProviderInfo(config: ContextMcpConfig, embedding: OpenAIEmbedding | AzureOpenAIEmbedding | VoyageAIEmbedding | GeminiEmbedding | OllamaEmbedding): void {
console.log(`[EMBEDDING] ✅ Successfully initialized ${config.embeddingProvider} embedding provider`);
console.log(`[EMBEDDING] Provider details - Model: ${config.embeddingModel}, Dimension: ${embedding.getDimension()}`);
@@ -72,6 +96,9 @@ export function logEmbeddingProviderInfo(config: ContextMcpConfig, embedding: Op
case 'OpenAI':
console.log(`[EMBEDDING] OpenAI configuration - API Key: ${config.openaiApiKey ? '✅ Provided' : '❌ Missing'}, Base URL: ${config.openaiBaseUrl || 'Default'}`);
break;
+ case 'AzureOpenAI':
+ console.log(`[EMBEDDING] Azure OpenAI configuration - API Key: ${config.azureOpenaiApiKey ? '✅ Provided' : '❌ Missing'}, Endpoint: ${config.azureOpenaiEndpoint}, Deployment: ${config.azureOpenaiDeploymentName || config.embeddingModel}`);
+ break;
case 'VoyageAI':
console.log(`[EMBEDDING] VoyageAI configuration - API Key: ${config.voyageaiApiKey ? '✅ Provided' : '❌ Missing'}`);
break;
diff --git a/packages/vscode-extension/README.md b/packages/vscode-extension/README.md
index 495cb5de..56751fb8 100644
--- a/packages/vscode-extension/README.md
+++ b/packages/vscode-extension/README.md
@@ -14,7 +14,7 @@ A code indexing and semantic search VSCode extension powered by [Claude Context]
- 🔍 **Semantic Search**: Intelligent code search based on semantic understanding, not just keyword matching
- 📁 **Codebase Indexing**: Automatically index entire codebase and build semantic vector database
- 🎯 **Context Search**: Search related code by selecting code snippets
-- 🔧 **Multi-platform Support**: Support for OpenAI, VoyageAI, Gemini, and Ollama as embedding providers
+- 🔧 **Multi-platform Support**: Support for OpenAI, Azure OpenAI, VoyageAI, Gemini, and Ollama as embedding providers
- 💾 **Vector Storage**: Integrated with Milvus vector database for efficient storage and retrieval
## Requirements
@@ -46,6 +46,13 @@ Configure your embedding provider to convert code into semantic vectors.
- `OpenAI API key`: Your OpenAI API key for authentication
- `Custom API endpoint URL`: Optional custom endpoint (defaults to `https://api.openai.com/v1`)
+**Azure OpenAI Configuration:**
+- `Embedding Provider`: Select "Azure OpenAI" from the dropdown
+- `Deployment name`: Your Azure deployment name (not model name)
+- `Azure OpenAI endpoint URL`: Your Azure OpenAI resource endpoint
+- `Azure OpenAI API key`: Your Azure API key for authentication
+- `API version`: Optional API version (defaults to 2024-02-01)
+
**Other Supported Providers:**
- **Gemini**: Google's state-of-the-art embedding model with Matryoshka representation learning
- **VoyageAI**: Alternative embedding provider with competitive performance
diff --git a/packages/vscode-extension/src/config/configManager.ts b/packages/vscode-extension/src/config/configManager.ts
index ee6adffe..888e5d6d 100644
--- a/packages/vscode-extension/src/config/configManager.ts
+++ b/packages/vscode-extension/src/config/configManager.ts
@@ -1,5 +1,5 @@
import * as vscode from 'vscode';
-import { OpenAIEmbedding, OpenAIEmbeddingConfig, VoyageAIEmbedding, VoyageAIEmbeddingConfig, OllamaEmbedding, OllamaEmbeddingConfig, GeminiEmbedding, GeminiEmbeddingConfig, MilvusConfig, SplitterType, SplitterConfig, AstCodeSplitter, LangChainCodeSplitter } from '@zilliz/claude-context-core';
+import { OpenAIEmbedding, OpenAIEmbeddingConfig, AzureOpenAIEmbedding, AzureOpenAIEmbeddingConfig, VoyageAIEmbedding, VoyageAIEmbeddingConfig, OllamaEmbedding, OllamaEmbeddingConfig, GeminiEmbedding, GeminiEmbeddingConfig, MilvusConfig, SplitterType, SplitterConfig, AstCodeSplitter, LangChainCodeSplitter } from '@zilliz/claude-context-core';
// Simplified Milvus configuration interface for frontend
export interface MilvusWebConfig {
@@ -10,6 +10,9 @@ export interface MilvusWebConfig {
export type EmbeddingProviderConfig = {
provider: 'OpenAI';
config: OpenAIEmbeddingConfig;
+} | {
+ provider: 'AzureOpenAI';
+ config: AzureOpenAIEmbeddingConfig;
} | {
provider: 'VoyageAI';
config: VoyageAIEmbeddingConfig;
@@ -61,6 +64,22 @@ const EMBEDDING_PROVIDERS = {
model: 'text-embedding-3-small'
}
},
+ 'AzureOpenAI': {
+ name: 'Azure OpenAI',
+ class: AzureOpenAIEmbedding,
+ requiredFields: [
+ { name: 'deploymentName', type: 'string', description: 'Azure deployment name', inputType: 'text', required: true },
+ { name: 'azureEndpoint', type: 'string', description: 'Azure OpenAI endpoint URL', inputType: 'url', required: true, placeholder: 'https://your-resource.openai.azure.com' },
+ { name: 'apiKey', type: 'string', description: 'Azure OpenAI API key', inputType: 'password', required: true }
+ ] as FieldDefinition[],
+ optionalFields: [
+ { name: 'apiVersion', type: 'string', description: 'API version', inputType: 'text', placeholder: '2024-02-01' }
+ ] as FieldDefinition[],
+ defaultConfig: {
+ deploymentName: 'text-embedding-3-small-deployment',
+ apiVersion: '2024-02-01'
+ }
+ },
'VoyageAI': {
name: 'VoyageAI',
class: VoyageAIEmbedding,
diff --git a/packages/vscode-extension/src/extension.ts b/packages/vscode-extension/src/extension.ts
index 462e282a..d2453695 100644
--- a/packages/vscode-extension/src/extension.ts
+++ b/packages/vscode-extension/src/extension.ts
@@ -132,7 +132,10 @@ function createContextWithConfig(configManager: ConfigManager): Context {
// Create embedding instance
if (embeddingConfig) {
embedding = ConfigManager.createEmbeddingInstance(embeddingConfig.provider, embeddingConfig.config);
- console.log(`Embedding initialized with ${embeddingConfig.provider} (model: ${embeddingConfig.config.model})`);
+ const modelOrDeployment = embeddingConfig.provider === 'AzureOpenAI'
+ ? (embeddingConfig.config as any).deploymentName
+ : (embeddingConfig.config as any).model;
+ console.log(`Embedding initialized with ${embeddingConfig.provider} (${embeddingConfig.provider === 'AzureOpenAI' ? 'deployment' : 'model'}: ${modelOrDeployment})`);
contextConfig.embedding = embedding;
} else {
console.log('No embedding configuration found');
@@ -193,7 +196,10 @@ function reloadContextConfiguration() {
if (embeddingConfig) {
const embedding = ConfigManager.createEmbeddingInstance(embeddingConfig.provider, embeddingConfig.config);
codeContext.updateEmbedding(embedding);
- console.log(`Embedding updated with ${embeddingConfig.provider} (model: ${embeddingConfig.config.model})`);
+ const modelOrDeployment = embeddingConfig.provider === 'AzureOpenAI'
+ ? (embeddingConfig.config as any).deploymentName
+ : (embeddingConfig.config as any).model;
+ console.log(`Embedding updated with ${embeddingConfig.provider} (${embeddingConfig.provider === 'AzureOpenAI' ? 'deployment' : 'model'}: ${modelOrDeployment})`);
}
// Update vector database if configuration exists