<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Renzo Fernando LOYOLA VILCA CHOQUE</title>
    <description>The latest articles on Forem by Renzo Fernando LOYOLA VILCA CHOQUE (@renzo_fernandoloyolavil).</description>
    <link>https://forem.com/renzo_fernandoloyolavil</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3644593%2F4ed5bd1a-ec5d-46cc-85ce-f841031d5bb5.png</url>
      <title>Forem: Renzo Fernando LOYOLA VILCA CHOQUE</title>
      <link>https://forem.com/renzo_fernandoloyolavil</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/renzo_fernandoloyolavil"/>
    <language>en</language>
    <item>
      <title>Secure Your Python App Using Bandit as a SAST Tool</title>
      <dc:creator>Renzo Fernando LOYOLA VILCA CHOQUE</dc:creator>
      <pubDate>Sat, 06 Dec 2025 01:18:08 +0000</pubDate>
      <link>https://forem.com/renzo_fernandoloyolavil/secure-your-python-app-using-bandit-as-a-sast-tool-1ofm</link>
      <guid>https://forem.com/renzo_fernandoloyolavil/secure-your-python-app-using-bandit-as-a-sast-tool-1ofm</guid>
      <description>&lt;p&gt;Static Application Security Testing (SAST) tools help you detect vulnerabilities directly in your source code before the application is executed or deployed. In this article, you will see how to use Bandit, a Python‑focused SAST tool, to scan a Python application and improve its security posture.​&lt;/p&gt;

&lt;p&gt;What Is SAST and Why It Matters&lt;br&gt;
SAST refers to techniques and tools that analyze source code, bytecode or binaries to find security weaknesses without running the application. These tools search for patterns related to insecure practices such as injection, unsafe system calls, weak cryptography, or hardcoded secrets.​&lt;/p&gt;

&lt;p&gt;Running SAST early in the development lifecycle allows teams to detect and fix issues before they reach production, which reduces both risk and remediation cost. Integrating SAST into everyday workflows (IDE checks, pre‑commit hooks or CI/CD pipelines) transforms security from a late, manual step into a continuous, automated practice.​&lt;/p&gt;

&lt;p&gt;Meet Bandit: A Python Security Linter&lt;br&gt;
Bandit is an open source security linter designed to find common security issues in Python code. It parses Python files, builds an abstract syntax tree (AST), and runs a set of security tests to detect problems such as hardcoded passwords, use of unsafe functions like exec, insecure random generators, weak hashes, or risky XML and subprocess usage.​&lt;/p&gt;

&lt;p&gt;Because Bandit understands Python syntax and idioms, it can provide more precise findings than generic text‑based scanners for this language. It is distributed through PyPI, actively maintained by the PyCQA community, and can be easily integrated into local development workflows and CI/CD pipelines.​&lt;/p&gt;

&lt;p&gt;Setting Up Bandit in Your Project&lt;br&gt;
To use Bandit, you only need a working Python environment and pip. Many developers prefer to create a virtual environment so that security tools and project dependencies do not conflict.​&lt;/p&gt;

&lt;p&gt;Example setup steps (run in your terminal):&lt;/p&gt;

&lt;p&gt;Create and activate a virtual environment (optional).​&lt;/p&gt;

&lt;p&gt;Install Bandit with pip: pip install bandit.​&lt;/p&gt;

&lt;p&gt;Optionally, install extra features like TOML support, baseline management or SARIF output using extras such as bandit[toml], bandit[baseline] or bandit[sarif].​&lt;/p&gt;

&lt;p&gt;After installation, the bandit command becomes available in your shell so you can run it from any project directory.​&lt;/p&gt;

&lt;p&gt;Scanning a Python Application with Bandit&lt;br&gt;
Once Bandit is installed, you can scan either a single file or an entire project directory. The most common workflow is to navigate to the root of your Python project and run Bandit recursively.​&lt;/p&gt;

&lt;p&gt;Typical examples:&lt;/p&gt;

&lt;p&gt;Scan a single file: bandit app.py&lt;/p&gt;

&lt;p&gt;Scan a whole project recursively: bandit -r .&lt;/p&gt;

&lt;p&gt;When the scan finishes, Bandit prints a report showing each issue it found, along with fields like severity, confidence, file path, line number and a short description. You can also change the output format to JSON, XML, HTML, YAML and others, which is useful for storing results or integrating with dashboards.​&lt;/p&gt;

&lt;p&gt;Understanding Bandit’s Output&lt;br&gt;
Bandit assigns two key attributes to each finding: severity and confidence. Severity indicates how serious the potential vulnerability is (for example low, medium or high), while confidence reflects how certain Bandit is that the pattern represents a real security problem.​&lt;/p&gt;

&lt;p&gt;High‑severity, high‑confidence issues typically indicate dangerous patterns such as use of weak cryptographic functions, insecure temporary files, unsafe XML parsers or shell commands with untrusted input. Developers should review these findings in context, confirm whether they are valid issues, and then apply fixes such as input validation, parameterization, replacing weak algorithms or refactoring dangerous code.​&lt;/p&gt;

&lt;p&gt;Applying Bandit to a Sample Scenario&lt;br&gt;
Imagine a small Python web application that performs file operations, calls external commands and processes user input. Bandit can help identify if:&lt;/p&gt;

&lt;p&gt;Temporary files are created using insecure methods.​&lt;/p&gt;

&lt;p&gt;User input is passed directly into shell commands or SQL queries.​&lt;/p&gt;

&lt;p&gt;Insecure modules like telnetlib or weak hash functions like md5 are in use.​&lt;/p&gt;

&lt;p&gt;Running bandit -r . from the project root will reveal these patterns with line numbers and explanations, making it easier to refactor the application before deployment.​&lt;/p&gt;

&lt;p&gt;Integrating Bandit into CI/CD&lt;br&gt;
The real power of a SAST tool appears when it becomes part of your automated pipelines. With Bandit, you can add a CI job that installs dependencies, runs bandit -r ., and fails the pipeline if new high‑severity issues are introduced.​&lt;/p&gt;

&lt;p&gt;For example, in a GitHub Actions or GitLab CI pipeline, you can:&lt;/p&gt;

&lt;p&gt;Use a Python base image, install Bandit and run it as part of your test stage.​&lt;/p&gt;

&lt;p&gt;Configure Bandit to output JSON or SARIF and upload that report as a pipeline artifact or feed it into security dashboards.​&lt;/p&gt;

&lt;p&gt;Optionally, use a baseline file to compare current results against previous scans, so only new findings break the build.​&lt;/p&gt;

&lt;p&gt;This approach ensures every pull request is checked for security issues, not only for functionality or style.​&lt;/p&gt;

&lt;p&gt;Best Practices When Using Bandit&lt;br&gt;
To get the most value from Bandit, consider these practices:&lt;/p&gt;

&lt;p&gt;Run Bandit locally as part of a pre‑commit hook so that insecure patterns are caught before code is pushed.​&lt;/p&gt;

&lt;p&gt;Adjust severity and confidence thresholds to match your project’s risk tolerance, focusing on high‑impact issues first.​&lt;/p&gt;

&lt;p&gt;Regularly review and update the configuration (for example .bandit.yml) to skip false positives or define project‑specific rules.​&lt;/p&gt;

&lt;p&gt;Combine Bandit with other security practices such as dependency scanning, dynamic testing and manual code review.​&lt;/p&gt;

&lt;p&gt;Bandit is not a silver bullet, but it is a lightweight and effective way to bring security awareness into everyday Python development.​&lt;/p&gt;

&lt;p&gt;Limitations and Complementary Tools&lt;br&gt;
Bandit focuses on static analysis of Python source code, so it does not replace dynamic application security testing or runtime protection. It may also miss complex logic issues that require deeper understanding of business rules, which is why human review remains essential.​&lt;/p&gt;

&lt;p&gt;For a more complete security strategy, combine Bandit with tools that check open‑source dependencies, perform dynamic scans against running environments and monitor production systems. Even with these limitations, integrating Bandit as your SAST tool for Python significantly raises your application’s security baseline with relatively low effort&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Applying API testing frameworks: real-world code examples</title>
      <dc:creator>Renzo Fernando LOYOLA VILCA CHOQUE</dc:creator>
      <pubDate>Sat, 06 Dec 2025 00:53:35 +0000</pubDate>
      <link>https://forem.com/renzo_fernandoloyolavil/applying-api-testing-frameworks-real-world-code-examples-424n</link>
      <guid>https://forem.com/renzo_fernandoloyolavil/applying-api-testing-frameworks-real-world-code-examples-424n</guid>
      <description>&lt;p&gt;Applying API testing frameworks: real-world code examples&lt;br&gt;
Modern applications dependen de APIs para conectar frontends, servicios internos y terceros. Validar estas APIs de forma automática es clave para evitar regresiones y detectar errores antes de llegar a producción. En este artículo verás cómo aplicar marcos de prueba de API con ejemplos reales usando Postman (JavaScript) y Rest Assured (Java), y cómo integrarlos en un flujo de CI/CD.​&lt;/p&gt;

&lt;p&gt;Why API testing matters&lt;br&gt;
API testing permite validar lógica de negocio, contratos y reglas de seguridad sin necesidad de una interfaz gráfica. Cuando se integra en pipelines de CI/CD, ayuda a detectar fallos de manera temprana y a mantener lanzamientos frecuentes pero estables. Además, automatizar estas pruebas reduce el trabajo manual del QA y mejora la confianza en cada despliegue.​&lt;/p&gt;

&lt;p&gt;Choosing an API testing framework&lt;br&gt;
Existen múltiples herramientas para probar APIs: Postman, Rest Assured, Karate, JMeter, SoapUI, entre otras. Cada una ofrece ventajas según el lenguaje, el tipo de proyecto y el nivel de experiencia del equipo. En este artículo nos centraremos en dos opciones muy usadas en la industria: Postman para flujos rápidos y colaborativos, y Rest Assured para pruebas integradas en suites Java.​&lt;/p&gt;

&lt;p&gt;Postman: testing with JavaScript&lt;br&gt;
Postman es una herramienta muy popular para diseñar, documentar y probar APIs, tanto de forma manual como automatizada. Permite agrupar peticiones en Collections, usar entornos con variables, y añadir scripts en JavaScript para ejecutar aserciones sobre las respuestas.​&lt;/p&gt;

&lt;p&gt;Un flujo típico de prueba funcional en Postman incluye:&lt;/p&gt;

&lt;p&gt;Definir la petición (método, URL, headers, body).&lt;/p&gt;

&lt;p&gt;Añadir scripts en la pestaña “Tests” para validar el resultado.&lt;/p&gt;

&lt;p&gt;Ejecutar la Collection de manera local o en un pipeline CI/CD.&lt;/p&gt;

&lt;p&gt;Real-world example: validating a GET endpoint in Postman&lt;br&gt;
Supongamos una API de librería con el endpoint GET /books/{id} que devuelve los detalles de un libro. El objetivo de la prueba es validar que el servicio responde con código 200 y que el cuerpo incluye campos como id, title y author con datos válidos.​&lt;/p&gt;

&lt;p&gt;En Postman, la prueba podría incluir aserciones como:&lt;/p&gt;

&lt;p&gt;js&lt;br&gt;
pm.test("Status code is 200", function () {&lt;br&gt;
    pm.response.to.have.status(200);&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;pm.test("Response body has required fields", function () {&lt;br&gt;
    const json = pm.response.json();&lt;br&gt;
    pm.expect(json).to.have.property("id");&lt;br&gt;
    pm.expect(json).to.have.property("title");&lt;br&gt;
    pm.expect(json).to.have.property("author");&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;pm.test("Book id matches requested id", function () {&lt;br&gt;
    const json = pm.response.json();&lt;br&gt;
    const requestedId = pm.request.url.variables.get("id");&lt;br&gt;
    pm.expect(json.id.toString()).to.eql(requestedId);&lt;br&gt;
});&lt;br&gt;
Este tipo de script se ejecuta automáticamente después de cada llamada y te permite validar tanto el código de estado como la estructura del JSON.​&lt;/p&gt;

&lt;p&gt;Data-driven tests with Postman&lt;br&gt;
En escenarios reales, es habitual probar el mismo endpoint con distintos datos de entrada. Postman soporta pruebas orientadas a datos usando archivos CSV o JSON, donde cada fila representa un conjunto de variables para la ejecución.​&lt;/p&gt;

&lt;p&gt;Por ejemplo, un archivo CSV podría contener varios bookId y valores esperados, y la Collection Runner los iterará de manera automática. Esto permite cubrir casos positivos y negativos (IDs válidos, inexistentes o inválidos) sin duplicar manualmente las peticiones.​&lt;/p&gt;

&lt;p&gt;Rest Assured: Java-based API testing&lt;br&gt;
Rest Assured es un framework para pruebas de API en Java que simplifica el envío de peticiones HTTP y la validación de respuestas. Se integra bien con TestNG o JUnit, lo que facilita su uso dentro de suites automatizadas y pipelines de CI/CD.​&lt;/p&gt;

&lt;p&gt;Su enfoque fluido permite escribir pruebas legibles, y combinarlo con librerías como Hamcrest para aserciones expresivas sobre JSON y XML. Además, soporta múltiples métodos HTTP, autenticación, parámetros, logs y manejo de serialización/deserialización.​&lt;/p&gt;

&lt;p&gt;Real-world example: Rest Assured GET test&lt;br&gt;
Tomando el mismo escenario de GET /books/{id}, una prueba en Rest Assured podría validar el status code y campos clave de la respuesta JSON.​&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
import static io.restassured.RestAssured.&lt;em&gt;;&lt;br&gt;
import static org.hamcrest.Matchers.&lt;/em&gt;;&lt;br&gt;
import org.testng.annotations.Test;&lt;/p&gt;

&lt;p&gt;public class BookApiTest {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Test
public void getBookById_shouldReturnValidBook() {
    given()
        .baseUri("https://api.example.com")
        .basePath("/books/{id}")
        .pathParam("id", 1)
    .when()
        .get()
    .then()
        .statusCode(200)
        .body("id", equalTo(1))
        .body("title", notNullValue())
        .body("author", notNullValue());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
Este tipo de prueba se puede ejecutar junto con el resto del suite de tests de backend, formando parte del proceso de build.​&lt;/p&gt;

&lt;p&gt;Creating reusable components in Rest Assured&lt;br&gt;
En casos reales, resulta útil extraer configuraciones repetidas como baseUri, headers comunes o autenticación a una clase base. De esta forma, las pruebas se enfocan en el comportamiento, no en el detalle de configuración de cada endpoint.​&lt;/p&gt;

&lt;p&gt;Por ejemplo, se puede definir una clase BaseApiTest que configure Rest Assured en un método @BeforeClass y luego extenderla desde las clases que representan cada módulo de la API (books, users, orders, etc.).​&lt;/p&gt;

&lt;p&gt;Testing authenticated APIs&lt;br&gt;
Muchos servicios exponen endpoints protegidos mediante API keys, tokens Bearer u OAuth2. Tanto Postman como Rest Assured ofrecen soporte para este tipo de autenticación, ya sea configurando headers, usando helpers integrados o generando tokens previos a las pruebas.​&lt;/p&gt;

&lt;p&gt;En Rest Assured, por ejemplo, se puede añadir un header de autorización de forma global o en cada prueba:&lt;/p&gt;

&lt;p&gt;java&lt;br&gt;
given()&lt;br&gt;
    .baseUri("&lt;a href="https://api.example.com%22" rel="noopener noreferrer"&gt;https://api.example.com"&lt;/a&gt;)&lt;br&gt;
    .header("Authorization", "Bearer " + token)&lt;br&gt;
    .when()&lt;br&gt;
    .get("/books")&lt;br&gt;
    .then()&lt;br&gt;
    .statusCode(200);&lt;br&gt;
En Postman, puedes almacenar el token en una variable de entorno y referenciarlo en el header Authorization mediante {{token}}.​&lt;/p&gt;

&lt;p&gt;Integrating API tests into CI/CD&lt;br&gt;
El verdadero valor de estos marcos se ve cuando se integran en pipelines de CI/CD como GitHub Actions, Jenkins o GitLab CI. La idea es ejecutar suites de pruebas de API en cada push o antes de un despliegue para evitar que cambios en el código rompan contratos existentes.​&lt;/p&gt;

&lt;p&gt;Algunos enfoques habituales son:&lt;/p&gt;

&lt;p&gt;Ejecutar Collections de Postman mediante Newman en un job del pipeline.&lt;/p&gt;

&lt;p&gt;Ejecutar tests de Rest Assured con Maven/Gradle como parte del stage de test.&lt;/p&gt;

&lt;p&gt;Publicar reportes (HTML, JUnit) como artefactos del pipeline para su revisión.&lt;/p&gt;

&lt;p&gt;Example: running Postman tests in CI&lt;br&gt;
Newman, el CLI de Postman, permite ejecutar collections dentro de un flujo automatizado. Un paso típico en un pipeline podría incluir un comando como:​&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
newman run LibraryAPI.postman_collection.json \&lt;br&gt;
  -e staging.postman_environment.json \&lt;br&gt;
  --reporters cli,junit \&lt;br&gt;
  --reporter-junit-export newman-report.xml&lt;br&gt;
Ese reporte puede ser consumido por la plataforma de CI/CD para marcar el build como exitoso o fallido según los resultados de las pruebas.​&lt;/p&gt;

&lt;p&gt;Example: running Rest Assured in CI&lt;br&gt;
Para proyectos Java, lo más habitual es ejecutar los tests de Rest Assured junto con el resto de pruebas unitarias e integradas. En un pipeline que use Maven, bastaría con un job que ejecute mvn test y recoja los informes generados.​&lt;/p&gt;

&lt;p&gt;Combinado con herramientas de reporte como surefire-report o plugins de informes HTML, es posible ver en detalle qué endpoints fallaron, qué payload se envió y cuál fue la respuesta recibida.​&lt;/p&gt;

&lt;p&gt;Putting it all together&lt;br&gt;
Aplicar marcos de prueba de API en proyectos reales significa ir más allá de pruebas manuales puntuales y construir suites automatizadas que vivan junto al código. Usando Postman puedes cubrir rápidamente escenarios funcionales y colaborativos, mientras que Rest Assured te permite integrar pruebas de API directamente en tu base de código Java y pipeline de CI/CD.​&lt;/p&gt;

&lt;p&gt;Al combinar ambos enfoques, obtienes una cobertura robusta: validaciones funcionales, pruebas con datos, escenarios autenticados y ejecución continua en cada cambio. Esto se traduce en APIs más confiables, menos incidentes en producción y un ciclo de desarrollo más seguro y predecible&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Securing Infrastructure as Code with Checkov: A Practical SAST Approach</title>
      <dc:creator>Renzo Fernando LOYOLA VILCA CHOQUE</dc:creator>
      <pubDate>Sat, 06 Dec 2025 00:41:48 +0000</pubDate>
      <link>https://forem.com/renzo_fernandoloyolavil/securing-infrastructure-as-code-with-checkov-a-practical-sast-approach-58co</link>
      <guid>https://forem.com/renzo_fernandoloyolavil/securing-infrastructure-as-code-with-checkov-a-practical-sast-approach-58co</guid>
      <description>&lt;p&gt;Introduction&lt;br&gt;
Infrastructure as Code (IaC) has revolutionized how we manage and deploy cloud resources. However, with great power comes great responsibility. Security misconfigurations in IaC templates can lead to serious vulnerabilities in production environments. This is where Static Application Security Testing (SAST) tools like Checkov come into play.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore how to implement Checkov, a powerful open-source SAST tool, to scan and secure your Infrastructure as Code across multiple platforms including Terraform, CloudFormation, Kubernetes, and more.&lt;/p&gt;

&lt;p&gt;What is Checkov?&lt;br&gt;
Checkov is a static code analysis tool developed by Bridgecrew (now part of Palo Alto Networks) that scans infrastructure code for security and compliance misconfigurations. It supports:&lt;/p&gt;

&lt;p&gt;Terraform&lt;br&gt;
CloudFormation&lt;br&gt;
Kubernetes&lt;br&gt;
Helm&lt;br&gt;
ARM Templates&lt;br&gt;
Serverless Framework&lt;br&gt;
Docker&lt;br&gt;
And many more...&lt;br&gt;
Why Use SAST for Infrastructure as Code?&lt;br&gt;
Early Detection: Identify security issues before they reach production&lt;br&gt;
Compliance: Ensure adherence to industry standards (CIS, PCI-DSS, HIPAA)&lt;br&gt;
Cost Reduction: Fix issues early in the development cycle&lt;br&gt;
Automation: Integrate seamlessly into CI/CD pipelines&lt;br&gt;
Policy as Code: Define and enforce organizational security policies&lt;/p&gt;

&lt;p&gt;Getting Started with Checkov&lt;br&gt;
Installation&lt;br&gt;
Checkov can be installed using pip:&lt;/p&gt;

&lt;p&gt;pip install checkov&lt;br&gt;
Or using Docker:&lt;/p&gt;

&lt;p&gt;docker pull bridgecrew/checkov&lt;br&gt;
Basic Usage&lt;br&gt;
Scan a Terraform directory:&lt;/p&gt;

&lt;p&gt;checkov -d /path/to/terraform&lt;br&gt;
Scan a specific file:&lt;/p&gt;

&lt;p&gt;checkov -f main.tf&lt;br&gt;
Practical Example: Securing Terraform Code&lt;br&gt;
Let's examine a vulnerable Terraform configuration and how Checkov identifies the issues.&lt;/p&gt;

&lt;p&gt;Vulnerable Configuration&lt;/p&gt;

&lt;h1&gt;
  
  
  main.tf - INSECURE EXAMPLE
&lt;/h1&gt;

&lt;p&gt;resource "aws_s3_bucket" "data_bucket" {&lt;br&gt;
  bucket = "my-data-bucket"&lt;/p&gt;

&lt;p&gt;# Missing encryption&lt;br&gt;
  # Missing versioning&lt;br&gt;
  # Missing logging&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_security_group" "web_sg" {&lt;br&gt;
  name        = "web-security-group"&lt;br&gt;
  description = "Security group for web servers"&lt;/p&gt;

&lt;p&gt;ingress {&lt;br&gt;
    from_port   = 0&lt;br&gt;
    to_port     = 0&lt;br&gt;
    protocol    = "-1"&lt;br&gt;
    cidr_blocks = ["0.0.0.0/0"]  # Too permissive!&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_db_instance" "database" {&lt;br&gt;
  allocated_storage    = 20&lt;br&gt;
  engine              = "mysql"&lt;br&gt;
  instance_class      = "db.t3.micro"&lt;br&gt;
  username            = "admin"&lt;br&gt;
  password            = "hardcodedpassword123"  # Hardcoded password!&lt;br&gt;
  skip_final_snapshot = true&lt;/p&gt;

&lt;p&gt;# Missing encryption&lt;br&gt;
  # Publicly accessible by default&lt;br&gt;
}&lt;br&gt;
Running Checkov&lt;br&gt;
checkov -f main.tf --output json --output-file results.json&lt;br&gt;
Checkov Output&lt;br&gt;
Checkov will identify multiple security issues:&lt;/p&gt;

&lt;p&gt;Check: CKV_AWS_18: "Ensure the S3 bucket has access logging enabled"&lt;br&gt;
Check: CKV_AWS_19: "Ensure the S3 bucket has server-side encryption enabled"&lt;br&gt;
Check: CKV_AWS_21: "Ensure the S3 bucket has versioning enabled"&lt;br&gt;
Check: CKV_AWS_23: "Ensure Security Group does not allow ingress from 0.0.0.0/0 to port 22"&lt;br&gt;
Check: CKV_AWS_16: "Ensure RDS database is encrypted at rest"&lt;br&gt;
Check: CKV_AWS_41: "Ensure RDS instance has IAM authentication enabled"&lt;br&gt;
Secure Configuration&lt;br&gt;
Now let's fix these issues:&lt;/p&gt;

&lt;h1&gt;
  
  
  main.tf - SECURE VERSION
&lt;/h1&gt;

&lt;p&gt;resource "aws_s3_bucket" "data_bucket" {&lt;br&gt;
  bucket = "my-data-bucket"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_s3_bucket_versioning" "data_bucket_versioning" {&lt;br&gt;
  bucket = aws_s3_bucket.data_bucket.id&lt;br&gt;
  versioning_configuration {&lt;br&gt;
    status = "Enabled"&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_s3_bucket_server_side_encryption_configuration" "data_bucket_encryption" {&lt;br&gt;
  bucket = aws_s3_bucket.data_bucket.id&lt;/p&gt;

&lt;p&gt;rule {&lt;br&gt;
    apply_server_side_encryption_by_default {&lt;br&gt;
      sse_algorithm = "AES256"&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_s3_bucket_logging" "data_bucket_logging" {&lt;br&gt;
  bucket = aws_s3_bucket.data_bucket.id&lt;/p&gt;

&lt;p&gt;target_bucket = aws_s3_bucket.log_bucket.id&lt;br&gt;
  target_prefix = "log/"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_security_group" "web_sg" {&lt;br&gt;
  name        = "web-security-group"&lt;br&gt;
  description = "Security group for web servers"&lt;/p&gt;

&lt;p&gt;ingress {&lt;br&gt;
    from_port   = 443&lt;br&gt;
    to_port     = 443&lt;br&gt;
    protocol    = "tcp"&lt;br&gt;
    cidr_blocks = ["10.0.0.0/8"]  # Restricted to internal network&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;egress {&lt;br&gt;
    from_port   = 0&lt;br&gt;
    to_port     = 0&lt;br&gt;
    protocol    = "-1"&lt;br&gt;
    cidr_blocks = ["0.0.0.0/0"]&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;resource "aws_db_instance" "database" {&lt;br&gt;
  allocated_storage    = 20&lt;br&gt;
  engine              = "mysql"&lt;br&gt;
  instance_class      = "db.t3.micro"&lt;br&gt;
  username            = "admin"&lt;br&gt;
  password            = var.db_password  # Using variable instead&lt;br&gt;
  skip_final_snapshot = false&lt;/p&gt;

&lt;p&gt;storage_encrypted          = true&lt;br&gt;
  iam_database_authentication_enabled = true&lt;br&gt;
  publicly_accessible        = false&lt;/p&gt;

&lt;p&gt;backup_retention_period = 7&lt;br&gt;
  enabled_cloudwatch_logs_exports = ["error", "general", "slowquery"]&lt;br&gt;
}&lt;br&gt;
Integrating Checkov into CI/CD&lt;br&gt;
GitHub Actions Example&lt;br&gt;
name: IaC Security Scan&lt;/p&gt;

&lt;p&gt;on: [push, pull_request]&lt;/p&gt;

&lt;p&gt;jobs:&lt;br&gt;
  checkov:&lt;br&gt;
    runs-on: ubuntu-latest&lt;br&gt;
    steps:&lt;br&gt;
      - name: Checkout code&lt;br&gt;
        uses: actions/checkout@v3&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  - name: Set up Python
    uses: actions/setup-python@v4
    with:
      python-version: '3.9'

  - name: Install Checkov
    run: pip install checkov

  - name: Run Checkov
    run: |
      checkov -d . --output cli --output json --output-file checkov-report.json

  - name: Upload results
    uses: actions/upload-artifact@v3
    if: always()
    with:
      name: checkov-report
      path: checkov-report.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;GitLab CI Example&lt;br&gt;
checkov:&lt;br&gt;
  stage: test&lt;br&gt;
  image: bridgecrew/checkov:latest&lt;br&gt;
  script:&lt;br&gt;
    - checkov -d . --output cli --output junitxml --output-file checkov-report.xml&lt;br&gt;
  artifacts:&lt;br&gt;
    reports:&lt;br&gt;
      junit: checkov-report.xml&lt;br&gt;
Custom Policies&lt;br&gt;
Checkov allows you to create custom policies using Python:&lt;/p&gt;

&lt;p&gt;from checkov.common.models.enums import CheckResult, CheckCategories&lt;br&gt;
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck&lt;/p&gt;

&lt;p&gt;class S3BucketEncryption(BaseResourceCheck):&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self):&lt;br&gt;
        name = "Ensure S3 bucket is encrypted with KMS"&lt;br&gt;
        id = "CKV_AWS_CUSTOM_1"&lt;br&gt;
        supported_resources = ['aws_s3_bucket']&lt;br&gt;
        categories = [CheckCategories.ENCRYPTION]&lt;br&gt;
        super().&lt;strong&gt;init&lt;/strong&gt;(name=name, id=id, categories=categories, &lt;br&gt;
                         supported_resources=supported_resources)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def scan_resource_conf(self, conf):
    if 'server_side_encryption_configuration' in conf:
        encryption_config = conf['server_side_encryption_configuration'][0]
        if 'rule' in encryption_config:
            rule = encryption_config['rule'][0]
            if 'apply_server_side_encryption_by_default' in rule:
                encryption = rule['apply_server_side_encryption_by_default'][0]
                if encryption.get('sse_algorithm') == ['aws:kms']:
                    return CheckResult.PASSED
    return CheckResult.FAILED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;check = S3BucketEncryption()&lt;br&gt;
Best Practices&lt;br&gt;
Run Checkov Early: Integrate it into your development workflow&lt;br&gt;
Use Suppressions Wisely: Document why certain checks are suppressed&lt;br&gt;
Keep Checkov Updated: New checks are added regularly&lt;br&gt;
Set Baseline: Use --baseline to track improvements over time&lt;br&gt;
Combine with Other Tools: Use alongside dynamic testing and manual reviews&lt;br&gt;
Educate Your Team: Ensure developers understand the security implications&lt;br&gt;
Suppressing False Positives&lt;br&gt;
Sometimes you need to suppress legitimate findings:&lt;/p&gt;

&lt;p&gt;resource "aws_security_group" "special_case" {&lt;br&gt;
  name = "special-sg"&lt;/p&gt;

&lt;p&gt;#checkov:skip=CKV_AWS_23:This SG is for internal load balancer&lt;br&gt;
  ingress {&lt;br&gt;
    from_port   = 80&lt;br&gt;
    to_port     = 80&lt;br&gt;
    protocol    = "tcp"&lt;br&gt;
    cidr_blocks = ["0.0.0.0/0"]&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
Measuring Success&lt;br&gt;
Track these metrics to measure the effectiveness of Checkov:&lt;/p&gt;

&lt;p&gt;Vulnerability Detection Rate: Number of issues found per scan&lt;br&gt;
Fix Time: Time from detection to remediation&lt;br&gt;
False Positive Rate: Percentage of findings that are not actual issues&lt;br&gt;
Coverage: Percentage of infrastructure code being scanned&lt;br&gt;
Compliance Score: Pass rate against security benchmarks&lt;br&gt;
Conclusion&lt;br&gt;
Implementing SAST tools like Checkov is essential for maintaining secure infrastructure as code. By catching security issues early in the development cycle, you can:&lt;/p&gt;

&lt;p&gt;Reduce security risks in production&lt;br&gt;
Ensure compliance with industry standards&lt;br&gt;
Foster a security-first culture&lt;br&gt;
Save time and money on remediation&lt;br&gt;
Start small by integrating Checkov into one project, measure the results, and gradually expand coverage across your organization. Security is a journey, not a destination, and tools like Checkov are invaluable companions along the way.&lt;/p&gt;

&lt;p&gt;References&lt;br&gt;
Checkov Official Documentation&lt;br&gt;
OWASP Source Code Analysis Tools&lt;br&gt;
Terraform Security Best Practices&lt;br&gt;
CIS Benchmarks&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Dominando las Pruebas de API con Postman: Ejemplos del Mundo Real</title>
      <dc:creator>Renzo Fernando LOYOLA VILCA CHOQUE</dc:creator>
      <pubDate>Thu, 04 Dec 2025 13:04:09 +0000</pubDate>
      <link>https://forem.com/renzo_fernandoloyolavil/dominando-las-pruebas-de-api-con-postman-ejemplos-del-mundo-real-23ld</link>
      <guid>https://forem.com/renzo_fernandoloyolavil/dominando-las-pruebas-de-api-con-postman-ejemplos-del-mundo-real-23ld</guid>
      <description>&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;En el desarrollo de software moderno, las APIs (Interfaces de Programación de Aplicaciones) son la columna vertebral de la comunicación entre sistemas. Postman se ha consolidado como una de las herramientas más populares y poderosas para probar, documentar y automatizar APIs. En este artículo, exploraremos cómo aplicar Postman en escenarios del mundo real, con ejemplos prácticos que puedes implementar inmediatamente.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Por qué Postman?
&lt;/h2&gt;

&lt;p&gt;Postman no es solo un cliente HTTP; es una plataforma completa para el desarrollo de APIs que ofrece:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Interfaz intuitiva&lt;/strong&gt;: Ideal para principiantes y expertos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatización de pruebas&lt;/strong&gt;: Scripts JavaScript para validaciones complejas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Colecciones organizadas&lt;/strong&gt;: Agrupa solicitudes relacionadas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variables de entorno&lt;/strong&gt;: Facilita el cambio entre dev, staging y producción&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integración CI/CD&lt;/strong&gt;: Compatible con Newman para pipelines automatizados&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Colaboración en equipo&lt;/strong&gt;: Espacios de trabajo compartidos&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Caso de Uso 1: Prueba de API RESTful de E-commerce
&lt;/h2&gt;

&lt;p&gt;Imaginemos que estamos probando una API de una tienda en línea que gestiona productos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Escenario: Obtener lista de productos
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// GET https://api.tienda.com/v1/productos&lt;/span&gt;

&lt;span class="c1"&gt;// En la pestaña "Tests" de Postman:&lt;/span&gt;
&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;El código de estado es 200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;La respuesta es JSON&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;La respuesta contiene productos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jsonData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;an&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;array&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;above&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cada producto tiene campos requeridos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;productos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;productos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;producto&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;producto&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;producto&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nombre&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;producto&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;precio&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;producto&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stock&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Escenario: Crear un nuevo producto (POST)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// POST https://api.tienda.com/v1/productos&lt;/span&gt;
&lt;span class="c1"&gt;// Body (JSON):&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nombre&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Laptop Dell XPS 15&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;precio&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1299.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;categoria&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Electrónica&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stock&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Tests:&lt;/span&gt;
&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Producto creado exitosamente - 201&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;La respuesta contiene el ID del producto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jsonData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Guardar el ID para usar en solicitudes posteriores&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;producto_id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;El precio se guardó correctamente&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jsonData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;precio&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1299.99&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Caso de Uso 2: Autenticación y Autorización
&lt;/h2&gt;

&lt;p&gt;Las APIs del mundo real requieren autenticación. Veamos cómo manejar tokens JWT.&lt;/p&gt;

&lt;h3&gt;
  
  
  Paso 1: Login y captura de token
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// POST https://api.tienda.com/v1/auth/login&lt;/span&gt;
&lt;span class="c1"&gt;// Body:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;usuario@ejemplo.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Tests:&lt;/span&gt;
&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Login exitoso&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Token JWT recibido&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jsonData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Guardar el token en variable de entorno&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jwt_token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Guardar timestamp de expiración&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;token_expiry&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Paso 2: Usar el token en solicitudes protegidas
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// GET https://api.tienda.com/v1/usuario/perfil&lt;/span&gt;
&lt;span class="c1"&gt;// Headers: Authorization: Bearer {{jwt_token}}&lt;/span&gt;

&lt;span class="c1"&gt;// Pre-request Script para verificar token:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jwt_token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No hay token de autenticación. Ejecuta primero el login.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Tests:&lt;/span&gt;
&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Acceso autorizado al perfil&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Datos del usuario son correctos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nombre&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;usuario&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rol&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusiones
&lt;/h2&gt;

&lt;p&gt;Postman es mucho más que una herramienta para enviar solicitudes HTTP. Como hemos visto en estos ejemplos del mundo real:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Validación robusta&lt;/strong&gt;: Podemos verificar códigos de estado, estructura de datos y lógica de negocio&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flujos complejos&lt;/strong&gt;: Encadenamiento de solicitudes con variables dinámicas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatización&lt;/strong&gt;: Integración perfecta con pipelines CI/CD mediante Newman&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Colaboración&lt;/strong&gt;: Espacios de trabajo compartidos facilitan el trabajo en equipo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentación viva&lt;/strong&gt;: Las colecciones sirven como documentación ejecutable&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Recursos Adicionales
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learning.postman.com/" rel="noopener noreferrer"&gt;Documentación oficial de Postman&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learning.postman.com/docs/getting-started/introduction/" rel="noopener noreferrer"&gt;Postman Learning Center&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/postmanlabs/newman" rel="noopener noreferrer"&gt;Newman en GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Sobre el autor&lt;/strong&gt;: Este artículo forma parte del Trabajo de Investigación N° 02 sobre Comparación de Frameworks de Pruebas de API, desarrollado como parte del curso de Calidad y Pruebas de Software.&lt;/p&gt;

</description>
      <category>api</category>
      <category>testing</category>
      <category>postman</category>
      <category>automation</category>
    </item>
    <item>
      <title>Construyendo un Servidor MCP: Conectando Claude y VSCode a Herramientas Externas</title>
      <dc:creator>Renzo Fernando LOYOLA VILCA CHOQUE</dc:creator>
      <pubDate>Thu, 04 Dec 2025 01:16:02 +0000</pubDate>
      <link>https://forem.com/renzo_fernandoloyolavil/building-an-mcp-server-connecting-claude-and-vscode-to-external-tools-1g4c</link>
      <guid>https://forem.com/renzo_fernandoloyolavil/building-an-mcp-server-connecting-claude-and-vscode-to-external-tools-1g4c</guid>
      <description>&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;El Protocolo de Contexto de Modelo (MCP) es un protocolo abierto revolucionario desarrollado por Anthropic que permite a asistentes de IA como Claude conectarse con fuentes de datos externas y herramientas. En este artículo, te guiaré a través de la construcción de tu propio servidor MCP que puede ser utilizado con Claude Desktop, VSCode y otros clientes compatibles.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es MCP?
&lt;/h2&gt;

&lt;p&gt;MCP proporciona una forma estandarizada para que los asistentes de IA interactúen con sistemas externos. Piensa en él como un adaptador universal que permite a Claude:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Acceder a bases de datos y APIs&lt;/li&gt;
&lt;li&gt;Leer y escribir archivos&lt;/li&gt;
&lt;li&gt;Ejecutar comandos&lt;/li&gt;
&lt;li&gt;Interactuar con servicios web&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El protocolo define una arquitectura cliente-servidor donde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clientes MCP&lt;/strong&gt; (como Claude Desktop o VSCode) se conectan a servidores&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Servidores MCP&lt;/strong&gt; exponen capacidades específicas (recursos, herramientas y prompts)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La comunicación&lt;/strong&gt; ocurre a través de JSON-RPC 2.0 sobre stdio o HTTP&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Descripción General de la Arquitectura
&lt;/h2&gt;

&lt;p&gt;Un servidor MCP consta de tres componentes principales:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Recursos
&lt;/h3&gt;

&lt;p&gt;Los recursos son fuentes de datos que el servidor puede proporcionar a los clientes. Pueden ser:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Archivos de un sistema de archivos&lt;/li&gt;
&lt;li&gt;Registros de bases de datos&lt;/li&gt;
&lt;li&gt;Respuestas de APIs&lt;/li&gt;
&lt;li&gt;Flujos de datos en tiempo real&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Herramientas
&lt;/h3&gt;

&lt;p&gt;Las herramientas son funciones que el cliente puede invocar a través del servidor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ejecutar comandos del sistema&lt;/li&gt;
&lt;li&gt;Realizar cálculos&lt;/li&gt;
&lt;li&gt;Interactuar con APIs externas&lt;/li&gt;
&lt;li&gt;Manipular datos&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Prompts
&lt;/h3&gt;

&lt;p&gt;Los prompts son plantillas predefinidas que ayudan a estructurar las interacciones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Plantillas de consultas&lt;/li&gt;
&lt;li&gt;Patrones de comandos&lt;/li&gt;
&lt;li&gt;Instrucciones de flujo de trabajo&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Construyendo tu Primer Servidor MCP
&lt;/h2&gt;

&lt;p&gt;Construyamos un servidor MCP simple paso a paso. Para este ejemplo, usaré Python, pero los servidores MCP pueden construirse en cualquier lenguaje.&lt;/p&gt;

&lt;h3&gt;
  
  
  Requisitos Previos
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Estructura Básica del Servidor
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp.server&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp.types&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Resource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Tool&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my-mcp-server&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.list_resources&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_resources&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Resource&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;Resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;file:///example.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Archivo de Ejemplo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;mimeType&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text/plain&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nd"&gt;@app.read_resource&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;file:///example.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;¡Hola desde el Servidor MCP!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Recurso desconocido: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.list_tools&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_tools&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;saludar&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Saludar a alguien por su nombre&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;inputSchema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;properties&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nombre&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;string&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;required&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nombre&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nd"&gt;@app.call_tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;saludar&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;¡Hola, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;nombre&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Herramienta desconocida: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conectando a Claude Desktop
&lt;/h2&gt;

&lt;p&gt;Para usar tu servidor MCP con Claude Desktop, necesitas configurarlo en la configuración de Claude:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Abre la configuración de Claude Desktop&lt;/li&gt;
&lt;li&gt;Navega a la sección "Developer"&lt;/li&gt;
&lt;li&gt;Agrega la configuración de tu servidor:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mi-servidor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"ruta/a/tu/servidor.py"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Reinicia Claude Desktop&lt;/li&gt;
&lt;li&gt;Las herramientas y recursos de tu servidor ahora estarán disponibles para Claude&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conectando a VSCode
&lt;/h2&gt;

&lt;p&gt;Para la integración con VSCode, puedes usar la extensión MCP:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Instala la extensión MCP desde el marketplace&lt;/li&gt;
&lt;li&gt;Configura tu servidor en &lt;code&gt;.vscode/mcp.json&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"servers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mi-servidor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"ruta/a/tu/servidor.py"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Casos de Uso del Mundo Real
&lt;/h2&gt;

&lt;p&gt;Aquí hay algunas aplicaciones prácticas para servidores MCP:&lt;/p&gt;

&lt;h3&gt;
  
  
  Acceso a Bases de Datos
&lt;/h3&gt;

&lt;p&gt;Crea un servidor que permita a Claude consultar tus bases de datos de forma segura:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.list_tools&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_tools&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;consultar_bd&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ejecutar consultas SQL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Operaciones del Sistema de Archivos
&lt;/h3&gt;

&lt;p&gt;Construye un servidor que gestione archivos de proyecto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.list_resources&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_resources&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;file:///&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;archivo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;archivo&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listdir&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Integración con APIs
&lt;/h3&gt;

&lt;p&gt;Conecta Claude a APIs externas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.call_tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;obtener_datos&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;http_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mejores Prácticas
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Seguridad Primero&lt;/strong&gt;: Siempre valida las entradas y sanitiza las salidas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manejo de Errores&lt;/strong&gt;: Proporciona mensajes de error claros&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentación&lt;/strong&gt;: Documenta tus herramientas y recursos exhaustivamente&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rendimiento&lt;/strong&gt;: Usa async/await para operaciones de I/O&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pruebas&lt;/strong&gt;: Prueba tu servidor con diferentes clientes&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Repositorio de Ejemplo
&lt;/h2&gt;

&lt;p&gt;Puedes encontrar un ejemplo completo y funcional en mi repositorio de GitHub:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repositorio&lt;/strong&gt;: &lt;a href="https://github.com/renzoloyola/MCP-Server" rel="noopener noreferrer"&gt;https://github.com/renzoloyola/MCP-Server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Este repositorio incluye:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implementación básica del servidor MCP&lt;/li&gt;
&lt;li&gt;Ejemplos de configuración para Claude y VSCode&lt;/li&gt;
&lt;li&gt;Documentación e instrucciones de configuración&lt;/li&gt;
&lt;li&gt;Casos de uso de ejemplo&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Construir servidores MCP abre posibilidades infinitas para extender las capacidades de los asistentes de IA. Ya sea que te estés conectando a bases de datos, sistemas de archivos o APIs externas, MCP proporciona una forma estandarizada y poderosa de hacer que tus datos y herramientas sean accesibles para la IA.&lt;/p&gt;

&lt;p&gt;El Protocolo de Contexto de Modelo sigue evolucionando, y el ecosistema está creciendo rápidamente. Al crear tus propios servidores MCP, puedes personalizar Claude y otros clientes compatibles para que se ajusten a tus necesidades y flujos de trabajo específicos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recursos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;Documentación MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/anthropics/anthropic-quickstarts" rel="noopener noreferrer"&gt;GitHub de Anthropic MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/renzoloyola/MCP-Server" rel="noopener noreferrer"&gt;Mi Repositorio de Ejemplo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;¿Has construido un servidor MCP? ¡Comparte tu experiencia en los comentarios!&lt;/p&gt;

</description>
      <category>mcpclaudevscodeai</category>
    </item>
  </channel>
</rss>
