Sunday, June 8, 2025

Unlocking the facility of Mannequin Context Protocol (MCP) on AWS

Share


We’ve witnessed exceptional advances in mannequin capabilities as generative AI firms have invested in growing their choices. Language fashions akin to Anthropic’s Claude Opus 4 & Sonnet 4 and Amazon Nova on Amazon Bedrock can motive, write, and generate responses with growing sophistication. However at the same time as these fashions develop extra highly effective, they’ll solely work with the knowledge accessible to them.

Irrespective of how spectacular a mannequin may be, it’s confined to the info it was skilled on or what’s manually offered in its context window. It’s like having the world’s finest analyst locked in a room with incomplete information—good, however remoted out of your group’s most present and related info.

This isolation creates three crucial challenges for enterprises utilizing generative AI:

  1. Info silos lure worthwhile information behind customized APIs and proprietary interfaces
  2. Integration complexity requires constructing and sustaining bespoke connectors and glue code for each information supply or instrument offered to the language mannequin for each information supply
  3. Scalability bottlenecks seem as organizations try to attach extra fashions to extra methods and instruments

Sound acquainted? In case you’re an AI-focused developer, technical decision-maker, or answer architect working with Amazon Web Services (AWS) and language fashions, you’ve possible encountered these obstacles firsthand. Let’s discover how the Model Context Protocol (MCP) provides a path ahead.

What’s the MCP?

The MCP is an open commonplace that creates a common language for AI methods to speak with exterior information sources, instruments, and providers. Conceptually, MCP features as a common translator, enabling seamless dialogue between language fashions and the various methods the place your worthwhile info resides.

Developed by Anthropic and launched as an open supply challenge, MCP addresses a basic problem: learn how to present AI fashions with constant, safe entry to the knowledge they want, once they want it, no matter the place that info lives.

MCP deployment diagram showing client interaction with local and internet-based MCP servers

At its core, MCP implements a client-server structure:

  • MCP shoppers are AI purposes like Anthropic’s Claude Desktop or customized options constructed on Amazon Bedrock that want entry to exterior information
  • MCP servers present standardized entry to particular information sources, whether or not that’s a GitHub repository, Slack workspace, or AWS service
  • Communication circulate between shoppers and servers follows a well-defined protocol that may run domestically or remotely

This structure helps three important primitives that kind the muse of MCP:

  1. Instruments – Features that fashions can name to retrieve info or carry out actions
  2. Sources – Knowledge that may be included within the mannequin’s context akin to database information, photos, or file contents
  3. Prompts – Templates that information how fashions work together with particular instruments or assets

What makes MCP particularly highly effective is its means to work throughout each native and distant implementations. You may run MCP servers immediately in your growth machine for testing or deploy them as distributed providers throughout your AWS infrastructure for enterprise-scale purposes.

Fixing the M×N integration drawback

Earlier than diving deeper into the AWS particular implementation particulars, it’s value understanding the basic integration problem MCP solves.

Think about you’re constructing AI purposes that have to entry a number of information sources in your group. With out a standardized protocol, you face what we name the “M×N drawback”: for M completely different AI purposes connecting to N completely different information sources, it is advisable construct and preserve M×N customized integrations.

This creates an integration matrix that rapidly turns into unmanageable as your group provides extra AI purposes and information sources. Every new system requires a number of customized integrations, with growth groups duplicating efforts throughout initiatives. MCP transforms this M×N drawback into a less complicated M+N equation: with MCP, you construct M shoppers and N servers, requiring solely M+N implementations. These options to the MCP drawback are proven within the following diagram.

Visualization showing how MCP reduces integration complexity from 9 to 6 implementations

This strategy attracts inspiration from different profitable protocols that solved comparable challenges:

  • APIs standardized how net purposes work together with the backend
  • Language Server Protocol (LSP) standardizes how integrated development environments (IDEs) work together with language-specific instruments for coding

In the identical means that these protocols revolutionized their domains, MCP is poised to rework how AI purposes work together with the various panorama of knowledge sources in fashionable enterprises.

Why MCP issues for AWS customers

For AWS clients, MCP represents a very compelling alternative. AWS provides a whole lot of providers, every with its personal APIs and information codecs. By adopting MCP as a standardized protocol for AI interactions, you possibly can:

  1. Streamline integration between Amazon Bedrock language fashions and AWS information providers
  2. Use current AWS safety mechanisms akin to AWS Identity and Access Management (IAM) for constant entry management
  3. Construct composable, scalable AI options that align with AWS architectural finest practices

MCP and the AWS service panorama

What makes MCP significantly highly effective within the AWS context is the way it can interface with the broader AWS service panorama. Think about AI purposes that may seamlessly entry info from:

MCP servers act as constant interfaces to those various information sources, offering language fashions with a unified entry sample whatever the underlying AWS service structure. This alleviates the necessity for customized integration code for every service and permits AI methods to work together with your AWS assets in a means that respects your current safety boundaries and entry controls.

Within the remaining sections of this submit, we discover how MCP works with AWS providers, study particular implementation examples, and supply steerage for technical decision-makers contemplating undertake MCP of their organizations.

How MCP works with AWS providers, significantly Amazon Bedrock

Now that we’ve proven the basic worth proposition of MCP, we dive into the way it integrates with AWS providers, with a particular concentrate on Amazon Bedrock. This integration creates a robust basis for constructing context-aware AI purposes that may securely entry your group’s information and instruments.

Amazon Bedrock and language fashions

Amazon Bedrock represents the strategic dedication by AWS to make foundation models (FMs) accessible, safe, and enterprise-ready. It’s a completely managed service that gives a unified API throughout a number of main language fashions, together with:

  • Anthropic’s Claude
  • Meta’s Llama
  • Amazon Titan and Amazon Nova

What makes Amazon Bedrock significantly compelling for enterprise deployments is its integration with the broader AWS panorama. You may run FMs with the identical safety, compliance, and operational instruments you already use to your AWS workloads. This contains IAM for entry management and CloudWatch for monitoring.

On the coronary heart of the flexibility of Amazon Bedrock is the Converse API—the interface that permits multiturn conversations with language fashions. The Converse API contains built-in help for what AWS calls “instrument use,” permitting fashions to:

  1. Acknowledge once they want info outdoors their coaching information
  2. Request that info from exterior methods utilizing well-defined perform calls
  3. Incorporate the returned information into their responses

This instrument use functionality within the Amazon Bedrock Converse API dovetails completely with MCP’s design, making a pure integration level.

MCP and Amazon Bedrock integration structure

Integrating MCP with Amazon Bedrock entails making a bridge between the mannequin’s means to request info (by the Converse API) and MCP’s standardized protocol for accessing exterior methods.

Integration circulate walkthrough

That can assist you perceive how MCP and Amazon Bedrock work collectively in follow, we stroll by a typical interplay circulate, step-by-step:

  1. The person initiates a question by your utility interface:

"What have been our Q1 gross sales figures for the Northwest area?"

  1. Your utility forwards the question to Amazon Bedrock by the Converse API:
   # Initialize the Bedrock runtime consumer together with your AWS credentials
   bedrock = boto3.consumer(service_name="bedrock-runtime", region_name="us-east-1")
   
   # Outline the question from the person
   user_query = "What have been our Q1 gross sales figures for the Northwest area?"
   
   # available_tools accommodates instrument definitions that match MCP server capabilities
   # These shall be uncovered to the mannequin by the Converse API
   
   # Name the Converse API with the person's question and accessible instruments
   response = bedrock.converse(
       modelId="us.anthropic.claude-3-7-sonnet-20250219-v1:0",  # Specify which language mannequin to make use of
       messages=[{"role": "user", "content": [{"text": user_query}]}],  # Format the person's message
       toolConfig={"instruments": available_tools}  # Cross the instrument definitions to the mannequin
   )

  1. Amazon Bedrock processes the question and determines that it wants monetary information that isn’t in its coaching information
  2. Amazon Bedrock returns a toolUse message, requesting entry to a particular instrument:
   {
     "function": "assistant",  // Signifies this message is from the mannequin
     "content material": [{
       "toolUse": {  // The model is requesting to use a tool
         "toolUseId": "tu_01234567",  // Unique identifier for this tool use request
         "name": "query_sales_data",  // Name of the tool the model wants to use
         "input": {  // Parameters for the tool call
           "quarter": "Q1",  // The model extracted this parameter from the user query
           "region": "Northwest"  // Another parameter extracted from the user query
         }
       }
     }]
   }

  1. Your MCP consumer utility receives this toolUse message and interprets it into an MCP protocol
    instrument name
  2. The MCP consumer routes the request to the suitable MCP server (on this case, a server linked to your
    monetary database)
  3. The MCP server executes the instrument, retrieving the requested information out of your methods:
   # Name the instrument by the MCP protocol
   # session is the MCP consumer session established earlier
   consequence = await session.call_tool(
       "query_sales_data",  # The instrument title from the toolUse message
       {
           "quarter": "Q1",  # Cross by the parameters from the toolUse message
           "area": "Northwest"
       }
   )
   # The MCP server handles authentication, information entry, and consequence formatting
   # This abstracts away the complexity of accessing completely different information sources

  1. The instrument outcomes are returned by the MCP protocol to your consumer utility
  2. Your utility sends the outcomes again to Amazon Bedrock as a toolResult message:
   {
     "function": "person",  // That is despatched as if from the person, however accommodates instrument outcomes
     "content material": [{
       "toolResult": {  // Indicates this is a result from a tool
         "toolUseId": "tu_01234567",  // Must match the ID from the original toolUse
         "content": [{
           "json": {  // Results are formatted as JSON
             "total_sales": 12450000,  // Numerical data accessible to the model
             "growth": 0.12,  // Percentage growth for analysis
             "top_products": ["Product A", "Product B", "Product C"]  // Listing information
           }
         }]
       }
     }]
   }

  1. Amazon Bedrock generates a closing response incorporating the instrument outcomes:
“Primarily based on the info I've retrieved, our Q1 gross sales figures for the Northwest area have been $12.45 million, 
representing a 12% development in comparison with the earlier quarter. 
The highest-performing merchandise have been Product A, Product B, and Product C.”

  1. Your utility returns the ultimate response to the person

This complete course of, illustrated within the following diagram, occurs in seconds, giving customers the impression of a seamless dialog with an AI that has direct entry to their group’s information. Behind the scenes, MCP is dealing with the complicated work of securely routing requests to the proper instruments and information sources.

Streamlined sequence diagram showing core MCP message flow from user query to final response

Within the subsequent part, we discover a sensible implementation instance that reveals learn how to join an MCP server to Amazon Bedrock Data Bases, offering a blueprint to your personal implementations.

Sensible implementation instance: Amazon Bedrock Data Bases integration

As you would possibly recall from our earlier dialogue of strategic use circumstances, enterprise information bases characterize one of the vital worthwhile purposes of MCP on AWS. Now, we discover a concrete implementation of MCP that connects language fashions to Amazon Bedrock Data Bases. The code for the MCP server might be discovered within the AWS Labs MCP code repository and for the consumer in the identical AWS Labs MCP samples directory on GitHub. This instance brings to life the “common translator” idea we launched earlier, demonstrating how MCP can rework the way in which AI methods work together with enterprise information repositories.

Understanding the problem

Enterprise information bases comprise huge repositories of knowledge—from documentation and insurance policies to technical guides and product specs. Conventional search approaches are sometimes insufficient when customers ask pure language questions, failing to know context or determine probably the most related content material.

Amazon Bedrock Data Bases present vector search capabilities that enhance upon conventional key phrase search, however even this strategy has limitations:

  1. Handbook filter configuration requires predefined information of metadata constructions
  2. Question-result mismatch happens when customers don’t use the precise terminology within the information base
  3. Relevance challenges come up when comparable paperwork compete for consideration
  4. Context switching between looking out and reasoning disrupts person expertise

The MCP server we discover addresses these challenges by creating an clever layer between language fashions and information bases.

Structure overview

At a excessive stage, our MCP server for Amazon Bedrock Data Bases follows a clear, well-organized structure that builds upon the client-server sample we outlined beforehand. The server exposes two key interfaces to language fashions:

  1. A information bases useful resource that gives discovery capabilities for accessible information bases
  2. A question instrument that permits dynamic looking out throughout these information bases

Detailed MCP Bedrock architecture with intelligent query processing workflow and AWS service connections

Bear in mind the M×N integration drawback we mentioned earlier? This implementation supplies a tangible instance of how MCP solves it – making a standardized interface between a big language mannequin and your Amazon Bedrock Data Base repositories.

Data base discovery useful resource

The server begins with a useful resource that permits language fashions to find accessible information bases:

@mcp.useful resource(uri='useful resource://knowledgebases', title="KnowledgeBases", mime_type="utility/json")
async def knowledgebases_resource() -> str:
    """Listing all accessible Amazon Bedrock Data Bases and their information sources.
 
    This useful resource returns a mapping of data base IDs to their particulars, together with:
    - title: The human-readable title of the information base
    - data_sources: An inventory of knowledge sources inside the information base, every with:
      - id: The distinctive identifier of the info supply
      - title: The human-readable title of the info supply
 
    ## Instance response construction:
    ```json
    {
        "kb-12345": {
            "title": "Buyer Assist KB",
            "data_sources": [
                {"id": "ds-abc123", "name": "Technical Documentation"},
                {"id": "ds-def456", "name": "FAQs"}
            ]
        },
        "kb-67890": {
            "title": "Product Info KB",
            "data_sources": [
                {"id": "ds-ghi789", "name": "Product Specifications"}
            ]
        }
    }
    ```
 
    ## The right way to use this info:
    1. Extract the information base IDs (like "kb-12345") to be used with the QueryKnowledgeBases instrument
    2. Be aware the info supply IDs if you wish to filter queries to particular information sources
    3. Use the names to find out which information base and information supply(s) are most related to the person's question
    """
    return json.dumps(await discover_knowledge_bases(kb_agent_mgmt_client, kb_inclusion_tag_key)) 

This useful resource serves as each documentation and a discovery mechanism that language fashions can use to determine accessible information bases earlier than querying them.

Querying information bases with the MCP instrument

The core performance of this MCP server resides in its QueryKnowledgeBases instrument:

@mcp.instrument(title="QueryKnowledgeBases")
async def query_knowledge_bases_tool(
    question: str = Subject(
        ..., description='A pure language question to look the information base with'
    ),
    knowledge_base_id: str = Subject(
        ...,
        description='The information base ID to question. It should be a sound ID from the useful resource://knowledgebases MCP useful resource',
    ),
    number_of_results: int = Subject(
        10,
        description='The variety of outcomes to return. Use smaller values for centered outcomes and bigger values for broader protection.',
    ),
    reranking: bool = Subject(
        kb_reranking_enabled,
        description='Whether or not to rerank the outcomes. Helpful for bettering relevance and sorting. Will be globally configured with BEDROCK_KB_RERANKING_ENABLED surroundings variable.',
    ),
    reranking_model_name: Literal['COHERE', 'AMAZON'] = Subject(
        'AMAZON',
        description="The title of the reranking mannequin to make use of. Choices: 'COHERE', 'AMAZON'",
    ),
    data_source_ids: Elective[List[str]] = Subject(
        None,
        description='The information supply IDs to filter the information base by. It should be a listing of legitimate information supply IDs from the useful resource://knowledgebases MCP useful resource',
    ),
) -> str:
    """Question an Amazon Bedrock Data Base utilizing pure language.
 
    ## Utilization Necessities
    - You MUST first use the `useful resource://knowledgebases` useful resource to get legitimate information base IDs
    - You may question completely different information bases or make a number of queries to the identical information base
 
    ## Question Ideas
    - Use clear, particular pure language queries for finest outcomes
    - You should use this instrument MULTIPLE TIMES with completely different queries to collect complete info
    - Break complicated questions into a number of centered queries
    - Take into account querying for factual info and explanations individually
     """
## Further Implementation particulars …

What makes this instrument highly effective is its flexibility in querying information bases with pure language. It helps a number of key options:

  1. Configurable consequence sizes – Alter the variety of outcomes based mostly on whether or not you want centered or complete info
  2. Elective reranking – Enhance relevance utilizing language fashions (akin to reranking fashions from Amazon or Cohere)
  3. Knowledge supply filtering – Goal particular sections of the information base when wanted

Reranking is disabled by default on this implementation however might be rapidly enabled by surroundings variables or direct parameter configuration.

Enhanced relevance with reranking

A notable function of this implementation is the flexibility to rerank search outcomes utilizing language fashions accessible by Amazon Bedrock. This functionality permits the system to rescore search outcomes based mostly on deeper semantic understanding:

# Parse reranking enabled surroundings variable
kb_reranking_enabled_raw = os.getenv('BEDROCK_KB_RERANKING_ENABLED')
kb_reranking_enabled = False  # Default worth is now False (off)
if kb_reranking_enabled_raw isn't None:
    kb_reranking_enabled_raw = kb_reranking_enabled_raw.strip().decrease()
    if kb_reranking_enabled_raw in ('true', '1', 'sure', 'on'):
        kb_reranking_enabled = True

Reranking is especially worthwhile for queries the place semantic similarity won’t be sufficient to find out the
most related content material. For instance, when answering a particular query, probably the most related doc isn’t essentially
the one with probably the most key phrase matches, however the one which immediately addresses the query being requested.

Full interplay circulate

This part walks by a whole interplay circulate to indicate how all these elements work
collectively:

  1. The person asks a query to a language mannequin akin to Anthropic’s Claude by an utility:
   "What's our quarterly IT safety audit process?"

  1. The language mannequin acknowledges it must entry the information base and calls the MCP instrument:
{
  "toolUse": {
    "title": "QueryKnowledgeBases",
    "enter": {
      "question": "What's our quarterly IT safety audit process?",
      "knowledge_base_id": "kb-12345abcde",
      "reranking": true
    }
  }
} 

  1. The MCP server processes the request by querying the information base with the required parameters
  2. The MCP server returns formatted outcomes to the language mannequin, together with content material, location, and relevance scores:
Utilized metadata filters: division=IT, document_type=Process, class=Safety Audit, frequency=Quarterly
 
   Outcomes have been reranked to enhance relevance.
 
   End result 1 [Score: 0.92]:
   Supply: S3 - s3://company-docs/procedures/it/safety/quarterly-audit-procedure-v2.pdf
   Content material: The IT Safety Quarterly Audit Process outlines the steps for conducting systematic evaluations of the group's info safety controls. This doc supplies steerage on scope, methodology, reporting necessities, and remediation monitoring...
   Metadata:
     • division: IT
     • document_type: Process
     • class: Safety Audit
     • frequency: Quarterly
     • last_updated: 2024-11-15

  1. The language mannequin incorporates these outcomes into its response to the person:
   Primarily based on our IT Safety Quarterly Audit Process, the method entails 4 major phases:
 
   1. Planning: Outline scope, goals, and schedule for the audit
   2. Execution: Conduct the technical assessments and management evaluations
   3. Reporting: Doc findings, dangers, and suggestions
   4. Remediation: Monitor and confirm decision of recognized points
 
   The process was final up to date on November 15, 2024, and specifies that the Cybersecurity workforce leads the trouble with help from IT Operations.

This interplay, illustrated within the following diagram, demonstrates the seamless fusion of language mannequin capabilities with enterprise information, enabled by the MCP protocol. The person doesn’t have to specify complicated search parameters or know the construction of the information base—the combination layer handles these particulars robotically.

End-to-end sequence diagram of IT security audit query processing through Bedrock Claude and MCP Server with metadata analysis

Wanting forward: The MCP journey continues

As we’ve explored all through this submit, the Mannequin Context Protocol supplies a robust framework for connecting language fashions to your enterprise information and instruments on AWS. However that is only the start of the journey.

The MCP panorama is quickly evolving, with new capabilities and implementations rising frequently. In future posts on this collection, we’ll dive deeper into superior MCP architectures and use circumstances, with a specific concentrate on distant MCP implementation.

The introduction of the brand new Streamable HTTP transport layer represents a major development for MCP, enabling actually enterprise-scale deployments with options akin to:

  • Stateless server choices for simplified scaling
  • Session ID administration for request routing
  • Sturdy authentication and authorization mechanisms for safe entry management
  • Horizontal scaling throughout server nodes
  • Enhanced resilience and fault tolerance

These capabilities shall be important as organizations transfer from proof-of-concept implementations to production-grade MCP deployments that serve a number of groups and use circumstances.

We invite you to observe this weblog submit collection as we proceed to discover how MCP and AWS providers can work collectively to create extra highly effective, context-aware AI purposes to your group.

Conclusion

As language fashions proceed to rework how we work together with expertise, the flexibility to attach these fashions to enterprise information and methods turns into more and more crucial. The Mannequin Context Protocol (MCP) provides a standardized, safe, and scalable strategy to integration.

Via MCP, AWS clients can:

  • Set up a standardized protocol for AI-data connections
  • Cut back growth overhead and upkeep prices
  • Implement constant safety and governance insurance policies
  • Create extra highly effective, context-aware AI experiences

The Amazon Bedrock Data Bases implementation we explored demonstrates how MCP can rework easy retrieval into clever discovery, including worth far past what both part might ship independently.

Getting began

Prepared to start your MCP journey on AWS? Listed below are some assets that can assist you get began:

Studying assets:

Implementation steps:

  1. Determine a high-value use case the place AI wants entry to enterprise information
  2. Choose the suitable MCP servers to your information sources
  3. Arrange a growth surroundings with native MCP implementations
  4. Combine with Amazon Bedrock utilizing the patterns described on this submit
  5. Deploy to manufacturing with applicable safety and scaling concerns

Do not forget that MCP provides a “begin small, scale incrementally” strategy. You may start with a single server connecting to 1 information supply, then develop your implementation as you validate the worth and set up patterns to your group.

We encourage you to attempt the MCP with AWS providers right now. Begin with a easy implementation, maybe connecting a language mannequin to your documentation or code repositories, and expertise firsthand the facility of context-aware AI.

Share your experiences, challenges, and successes with the group. The open supply nature of MCP signifies that your contributions—whether or not code, use circumstances, or suggestions—may help form the way forward for this essential protocol.

In a world the place AI capabilities are advancing quickly, the distinction between good and nice implementations typically comes all the way down to context. With MCP and AWS, you’ve the instruments to ensure your AI methods have the proper context on the proper time, unlocking their full potential to your group.

This weblog submit is a part of a collection exploring the Mannequin Context Protocol (MCP) on AWS. In our subsequent installment, we’ll discover the world of agentic AI, demonstrating learn how to construct autonomous brokers utilizing the open-source Strands Agents SDK with MCP to create clever methods that may motive, plan, and execute complicated multi-step workflows. We’ll additionally discover superior implementation patterns, distant MCP architectures, and uncover further use circumstances for MCP.


Concerning the authors

Aditya Addepalli is a Supply Advisor at AWS, the place he works to guide, architect, and construct purposes immediately with clients. With a powerful ardour for Utilized AI, he builds bespoke options and contributes to the ecosystem whereas constantly preserving himself on the fringe of expertise. Exterior of labor, you will discover him assembly new folks, figuring out, taking part in video video games and basketball, or feeding his curiosity by private initiatives.

Elie Schoppik leads stay training at Anthropic as their Head of Technical Coaching. He has spent over a decade in technical training, working with a number of coding faculties and beginning one among his personal. With a background in consulting, training, and software program engineering, Elie brings a sensible strategy to instructing Software program Engineering and AI. He’s shared his insights at quite a lot of technical conferences in addition to universities together with MIT, Columbia, Wharton, and UC Berkeley.

Jawhny Cooke is a Senior Anthropic Specialist Options Architect for Generative AI at AWS. He focuses on integrating and deploying Anthropic fashions on AWS infrastructure. He companions with clients and AI suppliers to implement production-grade generative AI options by Amazon Bedrock, providing knowledgeable steerage on structure design and system implementation to maximise the potential of those superior fashions.

Kenton Blacutt is an AI Advisor inside the GenAI Innovation Heart. He works hands-on with clients serving to them resolve real-world enterprise issues with leading edge AWS applied sciences, particularly Amazon Q and Bedrock. In his free time, he likes to journey, experiment with new AI strategies, and run an occasional marathon.

Mani Khanuja is a Principal Generative AI Specialist Options Architect, writer of the e book Utilized Machine Studying and Excessive-Efficiency Computing on AWS, and a member of the Board of Administrators for Ladies in Manufacturing Training Basis Board. She leads machine studying initiatives in numerous domains akin to laptop imaginative and prescient, pure language processing, and generative AI. She speaks at inside and exterior conferences such AWS re:Invent, Ladies in Manufacturing West, YouTube webinars, and GHC 23. In her free time, she likes to go for lengthy runs alongside the seashore.

Nicolai van der Smagt is a Senior Specialist Options Architect for Generative AI at AWS, specializing in third-party mannequin integration and deployment. He collaborates with AWS’ greatest AI companions to carry their fashions to Amazon Bedrock, whereas serving to clients architect and implement production-ready generative AI options with these fashions.



Source link

Read more

Read More