Using AWS Bedrock for ClaudeMind Plugin in IntelliJ IDEs - Explore

AWS
AWS Bedrock
ClaudeMind
AI
Using AWS Bedrock for ClaudeMind Plugin in IntelliJ IDEs

by: Jerrish Varghese

January 30, 2025

titleImage

Introduction

If you’re using ClaudeMind in your IntelliJ-based IDE (JetBrains family), you might want to avoid sending code to external APIs like Anthropic’s public Claude API. Instead, you can host Claude on AWS Bedrock and expose it locally using FastAPI.

This blog will walk you through:

  • Setting up AWS Bedrock to run Claude 3.5 Sonnet.
  • Creating a local API proxy using FastAPI that mimics Anthropic’s Claude API.
  • Configuring ClaudeMind plugin in IntelliJ to use your local API instead of the public API.

Why use AWS Bedrock instead of Anthropic API?

  • Data Privacy: No source code leaves your environment.
  • Enterprise-Ready: Works behind corporate firewalls.
  • Cost-Efficient: Pay per use instead of monthly subscriptions.
  • AI and Cloud: Leveraging AWS for AI-powered application development software.

Step 1: Set Up AWS Bedrock

AWS Bedrock provides access to foundation models like Claude. Follow these steps:

1. Enable AWS Bedrock in Your AWS Account

  • Log in to your AWS Console.
  • Navigate to AWS Bedrock → Model Access.
  • Request access to anthropic.claude-3-5-sonnet-20240620-v1:0.

2. Configure AWS CLI for Bedrock

  1. Ensure you have AWS CLI installed and configured:
       aws configure
  2. Run this to check if your AWS account has access:
       aws bedrock list-foundation-models --region us-east-1
  3. Expected Output:
      {
         "models": [
          {
            "modelId": "anthropic.claude-3-5-sonnet-20240620-v1:0",
            "provider": "Anthropic"
          }
        ]
      }

Step 2: Deploy a Local FastAPI Server

We’ll create a FastAPI server that acts as a proxy between ClaudeMind and AWS Bedrock.

1. Install Required Dependencies

pip install fastapi boto3 uvicorn pydantic

2. Create a Python Script

This script:

  • Authenticates requests with an API key.
  • Formats messages in the correct Claude API format.
  • Streams responses from AWS Bedrock back to the plugin.
import json
import uuid
from typing import List, Union, Dict, Any

import boto3
from fastapi import FastAPI, HTTPException, Header, Request
from fastapi.responses import StreamingResponse
from pydantic import BaseModel, field_validator

# Initialize FastAPI App
app = FastAPI()

# AWS Bedrock Client
bedrock_client = boto3.client("bedrock-runtime", region_name="us-east-1")

# API Key for Authentication
API_KEY = "my-secret-api-key"


class Message(BaseModel):
    role: str
    content: Union[str, List[dict]]

    @field_validator("content", mode="before")
    def extract_text(cls, value):
        if isinstance(value, list) and value and isinstance(value[0], dict) and "text" in value[0]:
            return value[0]["text"]
        return value


class AnthropicRequest(BaseModel):
    model: str
    messages: List[Message]
    max_tokens: int = 200
    temperature: float = 0.7


def process_messages(messages: List[Message]) -> List[Dict[str, str]]:
    return [
        {
            "role": msg.role,
            "content": msg.content
        }
        for msg in messages
    ]


async def generate_stream_events(streaming_response, message_id: str):
    yield 'event: message_start\n'
    yield f'''data: {json.dumps({"type": "message_start",
                                 "message": {"id": message_id,
                                             "type": "message",
                                             "role": "assistant",
                                             "content": [],
                                             "model": "claude-3-5-sonnet-20241022",
                                             "stop_reason": None,
                                             "stop_sequence": None,
                                             "usage": {"input_tokens": 0, "output_tokens": 0}}})}\n\n'''

    index = 0
    for event in streaming_response["body"]:
        chunk = json.loads(event["chunk"]["bytes"])

        if chunk["type"] == "content_block_delta":
            yield f'event: content_block_delta\n'
            yield f'''data: {json.dumps({"type": "content_block_delta",
                                         "index": index,
                                         "delta": {"type": "text_delta", "text": chunk["delta"].get("text", "")}})}\n\n'''

        elif chunk["type"] == "content_block_stop":
            yield f'event: content_block_stop\n'
            yield f'data: {json.dumps({"type": "content_block_stop", "index": index})}\n\n'
            index += 1

    yield 'event: message_stop\n'
    yield 'data: {"type": "message_stop"}\n\n'


@app.post("/v1/messages")
async def invoke_claude(request: Request, x_api_key: str = Header(None)):
    try:
        if x_api_key != API_KEY:
            raise HTTPException(status_code=401, detail="Invalid API Key")

        body = await request.json()
        parsed_request = AnthropicRequest(**body)
        processed_messages = process_messages(parsed_request.messages)
        message_id = f"msg_{uuid.uuid4().hex}"

        bedrock_request = {
            "anthropic_version": "bedrock-2023-05-31",
            "messages": processed_messages,
            "max_tokens": parsed_request.max_tokens,
            "temperature": parsed_request.temperature
        }

        streaming_response = bedrock_client.invoke_model_with_response_stream(
            modelId="anthropic.claude-3-5-sonnet-20240620-v1:0",
            body=json.dumps(bedrock_request)
        )

        return StreamingResponse(
            generate_stream_events(streaming_response, message_id),
            media_type="text/event-stream"
        )

    except Exception as e:
        print("Error:", str(e))
        raise HTTPException(status_code=500, detail=str(e))

3. Run the Local Server

uvicorn claude_local_server:app --host 0.0.0.0 --port 8000 --reload

Your Claude API proxy is now running locally!

Step 3: Configure ClaudeMind in IntelliJ

1. Open IntelliJ Settings

  • Go to Preferences → Plugins → ClaudeMind.

2. Change Claude API URL

  • Default API URL: https://api.anthropic.com/v1/messages
  • Change to: http://localhost:8000/v1/messages

3. Set API Key

  • Use my-secret-api-key (or change it in the script)

Now, ClaudeMind will connect to AWS Bedrock instead of Anthropic!


Step 4: Verify the Setup

1. Open IntelliJ and use ClaudeMind in the IDE.

2. Run a prompt like:

"Can you review this Java method?"

3. Check ClaudeMind’s response to confirm it’s working with AWS Bedrock.


Benefits of This Setup

  • Privacy: Code never leaves your network.
  • Cost-Efficient: Pay for what you use in AWS Bedrock.
  • Enterprise-Friendly: Works in corporate settings with private infrastructure.
  • Performance: Low-latency responses from AWS.
  • Conversational AI: Enables AI coding agents for enhanced AI software engineering workflows.

Conclusion

By following this guide, you’ve:

  • Set up AWS Bedrock to use Claude 3.5 Sonnet.
  • Built a FastAPI proxy for ClaudeMind.
  • Configured ClaudeMind in IntelliJ to use AWS Bedrock.

Next Steps:

  • Host this on EC2 or Docker for team-wide access.

contact us

Get started now

Get a quote for your project.
logofooter
title_logo

USA

Edstem Technologies LLC
254 Chapman Rd, Ste 208 #14734
Newark, Delaware 19702 US

INDIA

Edstem Technologies Pvt Ltd
Office No-2B-1, Second Floor
Jyothirmaya, Infopark Phase II
Ernakulam, Kerala 682303
iso logo

© 2024 — Edstem All Rights Reserved

Privacy PolicyTerms of Use