<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>AI &#8211; achraf ben alaya</title>
	<atom:link href="https://achrafbenalaya.com/category/ai/feed/" rel="self" type="application/rss+xml" />
	<link>https://achrafbenalaya.com</link>
	<description>Tech Blog By Achraf Ben Alaya</description>
	<lastBuildDate>Sun, 29 Mar 2026 13:37:29 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.5</generator>

<image>
	<url>/wp-content/uploads/2022/02/cropped-me-scaled-1-32x32.jpeg</url>
	<title>AI &#8211; achraf ben alaya</title>
	<link>https://achrafbenalaya.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">189072172</site>	<item>
		<title>GitHub Copilot Skills for Terraform: 5 On-Demand AI Assistants for Azure Container Apps</title>
		<link>https://achrafbenalaya.com/2026/03/29/github-copilot-skills-for-terraform-5-on-demand-ai-assistants-for-azure-container-apps/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=github-copilot-skills-for-terraform-5-on-demand-ai-assistants-for-azure-container-apps</link>
					<comments>https://achrafbenalaya.com/2026/03/29/github-copilot-skills-for-terraform-5-on-demand-ai-assistants-for-azure-container-apps/#respond</comments>
		
		<dc:creator><![CDATA[achraf]]></dc:creator>
		<pubDate>Sun, 29 Mar 2026 13:37:29 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[copilot]]></category>
		<category><![CDATA[azure]]></category>
		<guid isPermaLink="false">https://achrafbenalaya.com/?p=2489</guid>

					<description><![CDATA[Teaching Copilot to Know Your Stack: GitHub Copilot Skills for Azure Container Apps Part 4 In Part 3, we gave GitHub Copilot a project identity. Custom instructions told it about our Zero Trust rules. Path-specific instructions scoped guidance to the right files. Prompt files turned repetitive tasks into one-click workflows. Custom agents gave it specialized [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p><strong>Teaching Copilot to Know Your Stack: GitHub Copilot Skills for Azure Container Apps Part 4</strong></p>



<p>In Part 3, we gave GitHub Copilot a project identity. Custom instructions told it about our Zero Trust rules. Path-specific instructions scoped guidance to the right files. Prompt files turned repetitive tasks into one-click workflows. Custom agents gave it specialized personas with scoped tools.</p>



<p>But all of that is <em>always on</em>. Every Copilot conversation loads the custom instructions, whether you&#8217;re asking about networking or asking it to write a commit message. That&#8217;s fine when the instructions are small. It becomes a problem when your project grows  when you accumulate rules for security reviews, cost analysis, state management, scaling, and image lifecycle. You can&#8217;t fit everything into `copilot-instructions.md` without turning it into a sprawling document that confuses the model as much as it helps it.</p>



<p>Skills solve this. They&#8217;re the on-demand counterpart to always-on instructions. A skill is a folder with a `SKILL.md` file that Copilot loads <em>*only when your prompt is relevant to it</em>. Ask about drift? The drift detector skill loads. Ask about costs? The cost estimator loads. Ask about a new Container App resource? Copilot uses the base instructions and leaves the cost estimator alone.</p>



<p>This is Part 4, and it&#8217;s entirely about skills.</p>



<h2 class="wp-block-heading"><strong>What skills actually are</strong></h2>



<p>The mental model is straightforward. Custom instructions are rules you want Copilot to follow always  your naming conventions, your provider version, your security posture. Skills are specialized knowledge packages you want available on demand the deep expertise for a specific task that would clutter the always-on context if it were always loaded.</p>



<p>Mechanically, a skill is a directory under `.github/skills/` with a single required file: `SKILL.md`. That file has two parts: a YAML frontmatter block and a Markdown body.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
```
.github/
└── skills/
    └── my-skill-name/
        └── SKILL.md
```

The frontmatter defines the skill&#039;s identity:

```yaml
---
name: my-skill-name
description: &gt;
  One sentence summary.

  When to use this skill:
  - &quot;trigger phrase 1&quot;
  - &quot;trigger phrase 2&quot;
---
```

</pre></div>


<p>The <code>description</code> field is doing a lot of work here. Copilot reads it to decide whether this skill is relevant to your current prompt. The &#8220;when to use&#8221; section isn&#8217;t documentation for humans it&#8217;s signal for the model. Write it as a list of phrases someone would actually type when they need this skill. The more specific and realistic, the better the match.</p>



<p>The Markdown body is the skill&#8217;s actual content: instructions, workflows, code examples, lookup tables, templates. Whatever Copilot needs to execute the task well.</p>



<h2 class="wp-block-heading">Skills vs. the other tools in the toolbox</h2>



<p>After three parts covering custom instructions, path-specific instructions, prompt files, and agents, it&#8217;s worth being precise about where skills fit.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Tool</th><th>Location</th><th>When loaded</th><th>Best for</th></tr></thead><tbody><tr><td>Custom instructions</td><td><code>.github/copilot-instructions.md</code></td><td>Every conversation</td><td>Universal rules (naming, security, provider version)</td></tr><tr><td>Path-specific instructions</td><td><code>.github/instructions/*.instructions.md</code></td><td>When editing matching files</td><td>File-type-specific guidance</td></tr><tr><td>Prompt files</td><td><code>.github/prompts/*.prompt.md</code></td><td>When you select them manually</td><td>Repeatable multi-step tasks</td></tr><tr><td>Custom agents</td><td><code>.github/agents/*.agent.md</code></td><td>When you select the agent</td><td>Specialized personas with tool access</td></tr><tr><td><strong>Skills</strong></td><td><strong><code>.github/skills/*/SKILL.md</code></strong></td><td><strong>When prompt matches description</strong></td><td><strong>Deep expertise for specific tasks</strong></td></tr></tbody></table></figure>



<p>The key distinction from agents: agents are personas you <em>*select*</em>. Skills are knowledge packages that Copilot <em>*discovers*</em>. When you assign an issue to the coding agent with the implementation agent selected, that&#8217;s an explicit choice. When you ask &#8220;how much does this architecture cost?&#8221; and the cost estimator skill loads, that&#8217;s automatic.</p>



<h2 class="wp-block-heading"><strong>Building five skills for this project</strong></h2>



<p>Let&#8217;s build a complete skill library for the Azure Container Apps infrastructure we&#8217;ve been assembling across Parts 1, 2, and 3. Each skill addresses a real operational need.</p>



<h2 class="wp-block-heading"><strong>Skill 1  Terraform Drift Detector</strong> :</h2>



<p>Create `.github/skills/terraform-drift-detector/SKILL.md`: </p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
---
name: terraform-drift-detector
description: &gt;
  Detect, explain, and resolve Terraform state drift in this Azure Container Apps project.

  When to use this skill:
  - &quot;Why does my terraform plan show unexpected changes?&quot;
  - &quot;Something changed in Azure but I didn&#039;t touch the Terraform&quot;
  - &quot;Detect drift&quot;, &quot;check for drift&quot;, &quot;why is plan not clean?&quot;
  - &quot;Azure Portal changes not reflected in state&quot;
  - After manual changes via Azure CLI or Portal that weren&#039;t tracked in state
---

# Terraform Drift Detector

You are an expert in Terraform state management for Azure Container Apps infrastructure.
Your job is to detect, explain, and resolve drift between the Terraform state and actual Azure resources.

## What Is Drift

Drift happens when real Azure resources no longer match what Terraform&#039;s state file says they should be.
Common causes in this project:
- Manual changes via Azure Portal or CLI (e.g., scaling a Container App by hand)
- Azure auto-healing or auto-upgrading resources (e.g., Container App revision updates)
- Expiry or auto-rotation of identities
- Out-of-band certificate renewals on Application Gateway

## Detection Workflow

1. Read the current state using `#readFile` on `terraform.tfstate`
2. Run `terraform plan -detailed-exitcode`
   - Exit code 0 = no drift
   - Exit code 2 = drift found
3. Categorize each change by severity:
   - `external_enabled` flip on any Container App → 🔴 CRITICAL
   - `admin_enabled` change on ACR → 🔴 CRITICAL
   - Scaling values (min/max replicas) → 🟡 MEDIUM
   - Tag or label drifts → 🟢 LOW

## Reconciliation Rules

- NEVER auto-run `terraform apply` — show the plan first, ask for confirmation
- For CRITICAL: surface clearly, explain what probably happened, recommend remediation steps
- For LOW/MEDIUM: propose `terraform apply -target=&amp;lt;resource&gt;` with the specific address

## Output Format

Present findings as a Drift Report with Critical Changes and Safe-to-Reconcile sections.



</pre></div>


<p><strong>Why this skill matters.</strong> In a real team, someone will make a manual change in the Azure Portal  usually in an incident, under pressure. Terraform will then want to revert it. The worst case is a <code>terraform apply</code> that flips <code>external_enabled</code> from <code>true</code> to <code>false</code> on the frontend, taking it offline. The drift detector loads the right context to catch that before it happens.</p>



<h2 class="wp-block-heading">Skill 2 ACA Scaling Advisor</h2>



<p>Create `.github/skills/aca-scaling-advisor/SKILL.md`:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
---
name: aca-scaling-advisor
description: &gt;
  Design, review, and optimize scaling rules for Azure Container Apps in this project.

  When to use this skill:
  - &quot;Add scaling rules to my Container App&quot;
  - &quot;How should I scale the backend API?&quot;
  - &quot;My app is slow under load&quot;, &quot;optimize scaling&quot;, &quot;autoscale&quot;
  - &quot;Add KEDA scaler&quot;, &quot;HTTP scaling&quot;, &quot;queue-based scaling&quot;
  - &quot;min_replicas is too high&quot;, &quot;I&#039;m paying too much for idle containers&quot;
---

# ACA Scaling Advisor

You are an expert in Azure Container Apps autoscaling using KEDA.
Architecture context: frontend is external-facing via Application Gateway,
backend is internal-only. Both run on Consumption workload profile.

## Key Rules

**Frontend** — safe for `min_replicas = 0`. Application Gateway handles the queue.
Use HTTP scaler with `concurrentRequests = 100`.

**Backend** — keep `min_replicas = 1` unless the frontend uses async calls.
Scale-to-zero on a synchronously-called backend means the frontend sees cold start latency.
Use CPU scaler at 70% utilization.

## HTTP Scaling (Frontend)

\`\`\`hcl
template {
  min_replicas = 0
  max_replicas = 10

  custom_scale_rule {
    name             = &quot;http-scaler&quot;
    custom_rule_type = &quot;http&quot;
    metadata = {
      concurrentRequests = &quot;100&quot;
    }
  }
}
\`\`\`

## CPU Scaling (Backend)

\`\`\`hcl
template {
  min_replicas = 1
  max_replicas = 5

  custom_scale_rule {
    name             = &quot;cpu-scaler&quot;
    custom_rule_type = &quot;cpu&quot;
    metadata = {
      type  = &quot;Utilization&quot;
      value = &quot;70&quot;
    }
  }
}
\`\`\`

Always validate: no conflicting scale rules, `max_replicas` fits your cost ceiling,
and `min_replicas ≥ 1` on synchronously-called services.



</pre></div>


<p>The scaling advisor encodes the architectural constraints of this specific project. A generic Copilot response might suggest <code>min_replicas = 0</code> on the backend because it reduces costs. That&#8217;s correct in isolation. It&#8217;s wrong here because the frontend calls the backend synchronously a cold start becomes frontend latency. The skill carries that context.</p>



<h2 class="wp-block-heading">Skill 3 Azure Cost Estimator</h2>



<p>Create&nbsp;<code>.github/skills/azure-cost-estimator/SKILL.md</code>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
---
name: azure-cost-estimator
description: &gt;
  Estimate and break down monthly Azure costs for this Container Apps infrastructure.

  When to use this skill:
  - &quot;How much does this architecture cost?&quot;
  - &quot;Estimate my Azure bill&quot;, &quot;cost breakdown&quot;, &quot;cost estimate&quot;
  - &quot;Is the Application Gateway expensive?&quot;
  - &quot;I want to reduce costs&quot;, &quot;cheapest way to run this&quot;
  - &quot;What&#039;s the difference in cost between Consumption and Dedicated?&quot;
  - Before adding new resources — estimate the cost impact first
---

# Azure Cost Estimator

Pricing reference for West Europe (adjust by ~10-20% for other regions):

| Resource | Config | Est. Monthly Cost |
|---|---|---|
| Application Gateway | Standard_v2 | ~$185 |
| Container Registry | Standard SKU | ~$20 |
| Container Apps (per app) | 0.25 vCPU, 0.5GiB, 8h/day | ~$15 |
| Public IP | Standard | ~$4 |
| Private DNS Zone | 1 zone | ~$1 |
| Log Analytics | &amp;lt;5GB/day ingestion | ~$0 |

**Important:** Application Gateway accounts for ~75% of the bill at this scale.
It costs ~$185/month regardless of traffic volume.

When asked for an estimate:
1. Read `.tf` files to identify all provisioned resources
2. Ask for region if not West Europe
3. Present the cost table with actual resource configs from Terraform
4. Highlight the biggest cost driver
5. Suggest one or two project-specific optimizations
6. Always point to the Azure Pricing Calculator for accurate quotes


</pre></div>


<p>Every project eventually hits the &#8220;what&#8217;s this costing us?&#8221; question. Without the skill, Copilot would give a generic answer that doesn&#8217;t account for the Application Gateway&#8217;s flat cost, the specific SKUs we chose, or the Consumption billing model. The skill bakes those numbers in.</p>



<h2 class="wp-block-heading"><strong>Skill 4  Security Posture Reviewer</strong></h2>



<p>Create&nbsp;<code>.github/skills/security-posture-reviewer/SKILL.md</code>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
---
name: security-posture-reviewer
description: &gt;
  Review the Zero Trust security posture of this Azure Container Apps Terraform project.

  When to use this skill:
  - &quot;Review my security&quot;, &quot;security audit&quot;, &quot;security check&quot;
  - &quot;Is this Zero Trust?&quot;, &quot;what are my security gaps?&quot;
  - &quot;Check my NSG rules&quot;, &quot;are my secrets safe?&quot;
  - Before a production deployment or architecture review
  - After adding new resources — verify they follow the project&#039;s security rules
---

# Security Posture Reviewer

Review the project&#039;s Zero Trust compliance against this checklist.
Output ✅ or ❌ for each item after reading the Terraform files.

### Networking
- &#x5B; ] `internal_load_balancer_enabled = true` on Container App Environment
- &#x5B; ] ACA subnet CIDR is minimum `/23`
- &#x5B; ] NSG includes `GatewayManager` and `AzureLoadBalancer` inbound rules on AppGW subnet
- &#x5B; ] No `0.0.0.0/0` allow-all inbound rules (except those required by Azure platform)
- &#x5B; ] Private DNS zone linked to VNet with `registration_enabled = false`

### Container Apps
- &#x5B; ] Backend uses `external_enabled = false` (not just an NSG rule)
- &#x5B; ] No plaintext secrets in environment variables

### Container Registry
- &#x5B; ] `admin_enabled = false`
- &#x5B; ] SKU is Standard or Premium

### Identity and Credentials
- &#x5B; ] System-assigned Managed Identity enabled on both Container Apps
- &#x5B; ] `AcrPull` role assigned for each Container App&#039;s principal_id
- &#x5B; ] GitHub Actions uses workload identity federation (not service principal secrets)
- &#x5B; ] `terraform.tfstate` is NOT committed to the repository

## Common Gaps to Flag

**State file in repo**  contains resource IDs and output values. Add to `.gitignore` and use Azure Storage backend.

**Missing WAF policy**  Standard_v2 supports WAF but it&#039;s not enabled by default. Without it, no OWASP rule set protects the frontend from injection attacks.

**Log Analytics retention at default 30 days**  insufficient for incident response. Set `retention_in_days = 90`.
</pre></div>


<p>This skill is the automated version of the senior engineer&#8217;s pre-deployment checklist. It doesn&#8217;t just know generic security best practices  it knows <em>this project&#8217;s</em> security model and can check it against the actual Terraform files.</p>



<h2 class="wp-block-heading">Skill 5  ACR Image Manager</h2>



<p>Create&nbsp;<code>.github/skills/acr-image-manager/SKILL.md</code>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
---
name: acr-image-manager
description: &gt;
  Manage container images in Azure Container Registry — tagging strategy, image promotion,
  cleanup, and updating Container App image references in Terraform.

  When to use this skill:
  - &quot;Tag my image for production&quot;, &quot;promote image from staging to prod&quot;
  - &quot;Clean up old images in ACR&quot;, &quot;delete untagged manifests&quot;
  - &quot;Update the Container App to use image version X&quot;
  - &quot;How should I tag my Docker images?&quot;, &quot;image versioning strategy&quot;
  - &quot;Purge images older than 30 days&quot;, &quot;reduce ACR storage costs&quot;
---

# ACR Image Manager

ACR was created with `admin_enabled = false`. All operations use RBAC, not admin credentials.
Always authenticate with `az acr login --name &lt;acr_name&gt;` using the user&#039;s Azure CLI identity.

## Tagging Strategy

Use semantic versioning with a build reference. Never rely on `latest` alone for production.

\`\`\`
&lt;acr_login_server&gt;/&lt;service&gt;:&lt;semver&gt;-&lt;short_sha&gt;
\`\`\`

Examples:
- `acrab3k2m.azurecr.io/frontend:1.2.0-a3f9c1e`  ← immutable, for rollback
- `acrab3k2m.azurecr.io/frontend:latest`           ← mutable, for convenience

## Image Promotion (Staging → Production)

Use `az acr import` to copy between registries without pulling locally:

\`\`\`bash
az acr import \
  --name &lt;prod_acr_name&gt; \
  --source &lt;staging_acr_login_server&gt;/backend:1.2.0-a3f9c1e \
  --image backend:prod-1.2.0 \
  --registry &lt;staging_acr_resource_id&gt;
\`\`\`

## Updating Container App Image in Terraform

After promoting, update the `image` field in `aca.tf`:

\`\`\`hcl
image = &quot;${azurerm_container_registry.acr.login_server}/backend:1.2.0-a3f9c1e&quot;
\`\`\`

Then run `terraform plan` — only the image tag should change. Azure Container Apps creates a new revision automatically.

## Cleanup

Always dry-run before executing:

\`\`\`bash
az acr run \
  --registry &lt;acr_name&gt; \
  --cmd &quot;acr purge --filter &#039;backend:.*&#039; --untagged --ago 30d --dry-run&quot; \
  /dev/null
\`\`\`

Remove `--dry-run` once the output looks right.

</pre></div>


<p>The image management skill is particularly useful after the GitHub Actions CI/CD pipeline from Part 3 starts pushing images. Without it, Copilot doesn&#8217;t know whether to suggest <code>az acr</code> commands, direct Docker commands, or Terraform changes. The skill normalizes that: use RBAC auth, use the ACR import command for promotion, update the specific <code>image</code> field in <code>aca.tf</code>.</p>



<h2 class="wp-block-heading"><strong>How Copilot discovers and loads skills</strong></h2>



<p>You don&#8217;t invoke skills manually. When you type a prompt in Copilot Chat (or an issue body that gets routed to the coding agent), Copilot reads the&nbsp;<code>description</code>&nbsp;field of every skill in&nbsp;<code>.github/skills/</code>&nbsp;and decides which ones are relevant. If the match is strong, the&nbsp;<code>SKILL.md</code>&nbsp;content is injected into the context for that conversation.</p>



<p>This means the&nbsp;<code>description</code>&nbsp;field is actually the most important part of the file. Write it as if you&#8217;re writing the queries that should trigger it. The more concrete and realistic, the better.</p>



<p>A few things that improve match quality:</p>



<p><strong>Be specific about trigger phrases.</strong>&nbsp;&#8220;Detect drift&#8221;, &#8220;check for drift&#8221;, and &#8220;why is plan not clean?&#8221; are all things a real engineer would type. Generic phrases like &#8220;help with infrastructure&#8221; are too broad — they&#8217;d match every skill and load them all.</p>



<p><strong>Include anti-examples if needed.</strong>&nbsp;If two skills might get confused (say, cost estimator and scaling advisor both relate to &#8220;spending less money&#8221;), mention what each one&nbsp;<em>doesn&#8217;t</em>&nbsp;cover in the description.</p>



<p><strong>Keep the body focused.</strong>&nbsp;A skill loaded into context costs tokens. If the body is bloated with tangential information, the model&#8217;s attention dilutes. Each skill should do one thing well.</p>



<h2 class="wp-block-heading">Your repo structure after Part 4</h2>



<p></p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
.github/
├── copilot-instructions.md            # Always-on: naming, provider, Zero Trust rules
├── agents/
│   ├── terraform-aca-implement.agent.md  # Specialist: writes and validates Terraform
│   └── terraform-aca-planning.agent.md   # Specialist: designs changes, creates plans
├── instructions/
│   ├── networking.instructions.md     # File-scoped: vnet.tf, nsg.tf, dns.tf
│   └── containers.instructions.md    # File-scoped: aca.tf, acr.tf
├── prompts/
│   ├── new-container-app.prompt.md   # One-click: scaffold a new Container App
│   └── terraform-review.prompt.md   # One-click: security review checklist
├── skills/
│   ├── terraform-drift-detector/
│   │   └── SKILL.md                 # On-demand: detect and resolve state drift
│   ├── aca-scaling-advisor/
│   │   └── SKILL.md                 # On-demand: design KEDA scaling rules
│   ├── azure-cost-estimator/
│   │   └── SKILL.md                 # On-demand: monthly cost breakdown
│   ├── security-posture-reviewer/
│   │   └── SKILL.md                 # On-demand: Zero Trust compliance check
│   └── acr-image-manager/
│       └── SKILL.md                 # On-demand: image tagging, promotion, cleanup
└── workflows/
    └── terraform.yml                # CI/CD: plan on PR, apply on merge
</pre></div>


<p>Each layer serves a different purpose. Always-on instructions keep every AI interaction aligned with your project&#8217;s conventions. Path-specific instructions add depth when editing specific file types. Prompt files make repetitive tasks one-click. Agents give you specialized personas. Skills provide deep expertise exactly when  and only when  you need it.</p>



<h2 class="wp-block-heading">Where to find more skills</h2>



<p>GitHub maintains the&nbsp;<a href="https://github.com/github/awesome-copilot/tree/main/skills">github/awesome-copilot</a>&nbsp;repository with 247+ community-contributed skills. For Azure infrastructure work specifically, look at&nbsp;<code>azure-architecture-autopilot</code>&nbsp;(design and deploy Azure resources from natural language) and&nbsp;<code>create-specification</code>&nbsp;(generate structured spec files optimized for AI consumption). These are production-grade starting points — fork them, trim what you don&#8217;t need, add your project&#8217;s specific context.</p>



<p>One thing worth knowing: skills in&nbsp;<code>awesome-copilot</code>&nbsp;are organized by domain rather than by project. They&#8217;re designed to be generally useful, not specifically aware of your infrastructure. The value you get from writing your own is exactly that specificity — the drift detector that knows the difference between a MEDIUM and CRITICAL change for&nbsp;<em>this</em>&nbsp;architecture, the scaling advisor that knows&nbsp;<em>this</em>&nbsp;backend is called synchronously, the cost estimator that already has&nbsp;<em>these</em>&nbsp;SKUs and region prices loaded.</p>



<h2 class="wp-block-heading">The full picture</h2>



<p>Three parts built an infrastructure platform. Part 4 built the AI layer on top of it.</p>



<p>Start with what&#8217;s always relevant: custom instructions for project-wide rules that apply to every conversation. Add path-specific instructions for file types that have specialized concerns. Create prompt files for the tasks your team runs repeatedly. Build agents for the workflows that need specialized personas and specific tool access. Then write skills for the deep expertise that&#8217;s only needed sometimes  state drift, scaling design, cost analysis, security review, image lifecycle.</p>



<p>None of these are about making Copilot smarter in the abstract. They&#8217;re about making it useful <em>for your specific project</em>, in the way that a colleague who&#8217;s worked on the codebase for six months is useful  not because they know more general programming knowledge than a new hire, but because they know what matters here.</p>



<p><em>This is Part 4 of a series on building production-ready microservices on Azure Container Apps with Terraform and GitHub Copilot.&nbsp;<a href="https://achrafbenalaya.com/2025/12/23/from-manual-terraform-to-ai-assisted-devops-building-an-azure-container-platform-part-1/">Part</a>1&nbsp;covers the secure networking baseline.&nbsp;<a href="https://achrafbenalaya.com/2026/03/01/building-a-microservices-architecture-on-azure-container-apps-with-terraform-part-2/">Part 2</a>&nbsp;covers ACR, internal backend, and frontend-backend wiring.&nbsp;<a href="https://achrafbenalaya.com/2026/03/08/from-terraform-to-autopilot-ai-assisted-automation-for-azure-container-apps-part-3/">Part 3</a>&nbsp;covers AI-assisted automation, Managed Identities, and CI/CD.</em></p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://achrafbenalaya.com/2026/03/29/github-copilot-skills-for-terraform-5-on-demand-ai-assistants-for-azure-container-apps/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2489</post-id>	</item>
		<item>
		<title>Build and Host an Expense Tracking MCP Server with Azure Functions</title>
		<link>https://achrafbenalaya.com/2025/11/02/build-and-host-an-expense-tracking-mcp-server-with-azure-functions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=build-and-host-an-expense-tracking-mcp-server-with-azure-functions</link>
					<comments>https://achrafbenalaya.com/2025/11/02/build-and-host-an-expense-tracking-mcp-server-with-azure-functions/#respond</comments>
		
		<dc:creator><![CDATA[achraf]]></dc:creator>
		<pubDate>Sun, 02 Nov 2025 19:05:11 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Cloud]]></category>
		<guid isPermaLink="false">https://achrafbenalaya.com/?p=2292</guid>

					<description><![CDATA[It’s been a while since I started talking about the Model Context Protocol (MCP) how it works, how to integrate it, and how much it can simplify your workflow. I’ve been experimenting with MCP clients, exploring agent mode, even creating custom modes, and sharing everything I learn along the way. The more I dive into [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>It’s been a while since I started talking about the <strong>Model Context Protocol (MCP)</strong> how it works, how to integrate it, and how much it can simplify your workflow. I’ve been experimenting with MCP clients, exploring agent mode, even creating custom modes, and sharing everything I learn along the way. The more I dive into MCP, the more fascinated I become, and I love showing others just how powerful it is.</p>



<p>Up until now, I’ve mainly been using existing MCP servers. But at some point the real question arrives:<br><strong>How do you build your own MCP server? Where do you host it? And how do you actually use it in real projects?</strong></p>



<p>That’s exactly what led me here. I wanted to create my first MCP server from scratch. While exploring different approaches, I came across several sample repositories in <strong>Azure-samples</strong>. Since I’m a long-time <strong>C# developer</strong>, my first instinct was to build a server using <strong>Azure Functions + C#</strong>  totally in my comfort zone.</p>



<p>But this time, I made a promise to myself: <strong>step outside the comfort zone.</strong><br>And after watching many presentations by the amazing <strong>Pamela Fox</strong>, I said  why not Python for this first example?</p>



<p>So in this blog post, we’re going to build a <strong>simple expense-tracker MCP server using Python</strong>, deploy it as an <strong>Azure Function</strong>, and test it using <strong>MCP Inspector</strong> and <strong>VS Code’s MCP extension</strong>.</p>



<p>You&#8217;ll find a clear, step-by-step guide including:</p>



<p><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Cloning the repo : <a href="https://github.com/achrafbenalaya/expensetrackermcpserver">https://github.com/achrafbenalaya/expensetrackermcpserver</a><br><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Writing the server logic<br><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Creating &amp; deploying the Azure Function<br><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Testing it locally and in VS Code with MCP Inspector</p>



<p>If you enjoy this walkthrough, feel free to share it  and if you&#8217;d like to support my content, you can buy me a coffee here: <strong>buymeacoffee.com/ben2code <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2615.png" alt="☕" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" /></strong><br></p>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Prerequisites to follow along</h3>



<p>To build and test this project, make sure you have:</p>



<ul class="wp-block-list">
<li><strong>VS Code</strong></li>



<li><strong>MCP Inspector</strong></li>



<li><strong>Python</strong></li>



<li><strong>Browser</strong></li>



<li><strong>Docker</strong> <em>(optional  I’ll show how to run without it)</em></li>



<li><strong>Azure account with permissions to create Azure Functions</strong></li>



<li>And of course… <strong>an internet connection <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f604.png" alt="😄" class="wp-smiley" style="height: 1em; max-height: 1em;" /></strong></li>
</ul>



<p>Alright  let’s jump right in.</p>



<p>When you walk into a car showroom, you don’t start by asking about the engine specs, compression ratio, or fuel injection system. First, you want to <strong>see the car</strong>. You look at the design, step inside, feel the seats, maybe even take it for a quick test drive. <em>Only after that</em> do you start digging into the technical details.</p>



<p>We’re going to take the exact same approach here.</p>



<p>Before diving into code, architecture, Azure Functions, or deployment pipelines, let me <strong>show you the final result</strong>  what the MCP server can actually do once it&#8217;s up and running.<br><br></p>



<p class="has-medium-font-size"><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f6e0.png" alt="🛠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Tool #1: <code>get_expenses</code></p>



<p>This first tool simply retrieves your saved expenses a clean, structured way to read your stored data through MCP. Think of it like opening your car&#8217;s dashboard to see your mileage and trip history before we start checking the engine.</p>



<p>Let’s take a look at how it works in action <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f447.png" alt="👇" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br></p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img fetchpriority="high" decoding="async" width="763" height="673" src="/wp-content/uploads/2025/11/image.png" alt="" class="wp-image-2295" style="width:764px;height:auto" srcset="/wp-content/uploads/2025/11/image.png 763w, /wp-content/uploads/2025/11/image-300x265.png 300w, /wp-content/uploads/2025/11/image-750x662.png 750w" sizes="(max-width: 763px) 100vw, 763px" /></figure></div>


<p>Simply here i was asking for my expenses for the month of October for the year 2025 </p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="754" height="520" src="/wp-content/uploads/2025/11/image-2.png" alt="" class="wp-image-2297" srcset="/wp-content/uploads/2025/11/image-2.png 754w, /wp-content/uploads/2025/11/image-2-300x207.png 300w, /wp-content/uploads/2025/11/image-2-750x517.png 750w" sizes="(max-width: 754px) 100vw, 754px" /></figure></div>


<p></p>



<p class="has-medium-font-size"><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f6e0.png" alt="🛠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Tool #2: <code>get_budget</code></p>



<p>The second tool gives us visibility into our <strong>monthly budget</strong>.</p>



<p>For the demo, I’ve set the default budget to <strong>$1000 per month</strong>. Later, we’ll make this more flexible by storing the budget in an environment variable which means you’ll be able to adjust it per month, per environment, or even per user without touching the code.Think of this tool like checking the car’s fuel range before a road trip you need to know how far you can go before running out <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f604.png" alt="😄" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>This command simply returns your current budget value, so you always have a clear reference point before adding or reviewing expenses.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="886" height="660" src="/wp-content/uploads/2025/11/image-4.png" alt="" class="wp-image-2299" srcset="/wp-content/uploads/2025/11/image-4.png 886w, /wp-content/uploads/2025/11/image-4-300x223.png 300w, /wp-content/uploads/2025/11/image-4-768x572.png 768w, /wp-content/uploads/2025/11/image-4-750x559.png 750w" sizes="(max-width: 886px) 100vw, 886px" /></figure></div>


<p></p>



<h3 class="wp-block-heading has-medium-font-size"><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f6e0.png" alt="🛠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Tool #3: <code>get_spending_summary</code></h3>



<p>This tool gives you a <strong>summary of your spending over a specific time range</strong>.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="891" height="559" src="/wp-content/uploads/2025/11/image-6.png" alt="" class="wp-image-2301" srcset="/wp-content/uploads/2025/11/image-6.png 891w, /wp-content/uploads/2025/11/image-6-300x188.png 300w, /wp-content/uploads/2025/11/image-6-768x482.png 768w, /wp-content/uploads/2025/11/image-6-750x471.png 750w" sizes="(max-width: 891px) 100vw, 891px" /></figure></div>


<p></p>



<p class="has-medium-font-size"><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f6e0.png" alt="🛠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Tool #4: <code>add_expense</code></p>



<p>Now that we can read our budget and existing data, it&#8217;s time for the fun part <strong>adding new expenses</strong>.</p>



<p>This tool allows you to record a new expense with all the important details: category, amount, description, and date.<br></p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="886" height="571" src="/wp-content/uploads/2025/11/image-8.png" alt="" class="wp-image-2303" srcset="/wp-content/uploads/2025/11/image-8.png 886w, /wp-content/uploads/2025/11/image-8-300x193.png 300w, /wp-content/uploads/2025/11/image-8-768x495.png 768w, /wp-content/uploads/2025/11/image-8-750x483.png 750w" sizes="(max-width: 886px) 100vw, 886px" /></figure></div>


<p>Let&#8217;s check if the record is added : <br><br></p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="886" height="335" src="/wp-content/uploads/2025/11/image-10.png" alt="" class="wp-image-2305" srcset="/wp-content/uploads/2025/11/image-10.png 886w, /wp-content/uploads/2025/11/image-10-300x113.png 300w, /wp-content/uploads/2025/11/image-10-768x290.png 768w, /wp-content/uploads/2025/11/image-10-750x284.png 750w" sizes="(max-width: 886px) 100vw, 886px" /></figure></div>


<p>But wait  where is all this data actually stored?<br>Behind the scenes, everything is saved in an <strong>Azure Storage account</strong>, inside a <strong>Blob</strong> as a CSV file. Simple, lightweight, and easy to query.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1023" height="849" src="/wp-content/uploads/2025/11/image-12.png" alt="" class="wp-image-2307" srcset="/wp-content/uploads/2025/11/image-12.png 1023w, /wp-content/uploads/2025/11/image-12-300x249.png 300w, /wp-content/uploads/2025/11/image-12-768x637.png 768w, /wp-content/uploads/2025/11/image-12-750x622.png 750w" sizes="(max-width: 1023px) 100vw, 1023px" /></figure></div>


<p></p>



<p class="has-medium-font-size"><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f9f1.png" alt="🧱" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Project Overview  How We Built This MCP Server</p>



<p>Now that you&#8217;ve seen the final result, let’s open the hood and see how everything works under the engine. In this section, we&#8217;ll walk through:</p>



<ul class="wp-block-list">
<li>Where the project skeleton came from</li>



<li>What was modified and why</li>



<li>How the MCP server was implemented in Python</li>



<li>How we deployed it to Azure Functions</li>



<li>The configuration (environment variables, Storage, Blob, etc.)</li>



<li>How we tested locally and in the cloud</li>



<li>Tools used along the way (MCP Inspector, VS Code, Claude Desktop, etc.)</li>
</ul>



<p>Let&#8217;s break it down step-by-step <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f447.png" alt="👇" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br></p>



<h3 class="wp-block-heading has-medium-font-size">1&#x20e3; Pulling the Base Template (Source Repo)</h3>



<p>I started by cloning the official Model Context Protocol example repository from <strong>Azure-Samples</strong>, which provides a clean starting point for building MCP servers.</p>



<p>It gave me a Python-based skeleton so I could focus on extending the logic instead of building everything from scratch.<br><br>repo url  =====&gt; <a href="https://github.com/Azure-Samples/remote-mcp-functions-python">Azure-Samples/remote-mcp-functions-python</a></p>



<p>Full functionel repo ===> https://github.com/achrafbenalaya/expensetrackermcpserver</p>



<pre class="wp-block-code"><code>git clone https://github.com/Azure-Samples/remote-mcp-functions-python.git
</code></pre>



<h3 class="wp-block-heading has-medium-font-size">2&#x20e3; Understanding the Starter Code &amp; Modifying It</h3>



<p>From the base template, I:</p>



<ul class="wp-block-list">
<li>Reviewed the MCP handler logic</li>



<li>Created new MCP tools (get_budget, get_expenses, add_expense, get_spending_summary)</li>



<li>Integrated Azure Blob Storage as the backend</li>



<li>Added CSV read/write operations</li>



<li>Structured responses to match MCP protocol expectations<br><br></li>
</ul>



<p>Basically , I built a lightweight expense-tracking service in Python backed by Azure Blob Storage  no pandas required. It handles both CSV and XLSX formats, includes reliable date and amount parsing, supports dynamic monthly budgets via environment variables, and provides simple rule-based expense categorization. Each capability is implemented as small, testable functions and exposed as MCP tools (<code>get_expenses</code>, <code>add_expense</code>, <code>get_budget_status</code>, <code>get_spending_summary</code>, <code>categorize_expense</code>).</p>



<p>I’ll first explain, in plain steps, how the existing &#8220;get all expenses&#8221; tool was added (what the method does and why). Then I’ll show a minimal example of adding a new simple &#8220;hello world&#8221; tool — both the class method and a small HTTP wrapper you can drop into an Azure Functions HTTP trigger or run locally.</p>



<h2 class="wp-block-heading">How the &#8220;get all expenses&#8221; tool was added  short, concrete steps</h2>



<p>What we added: a public method&nbsp;<code>get_expenses(month: str, category: Optional[str] = None) -&gt; List[Dict]</code>&nbsp;on&nbsp;<code>ExpenseTracker</code>.</p>



<p>Why: expose a small, testable API that lists expenses for a given month (and optional category) in a JSON-serializable format so it can be used by MCP tools, HTTP endpoints, or scripts.</p>



<p>Implementation summary :</p>



<ul class="wp-block-list">
<li>Input normalization:
<ul class="wp-block-list">
<li><code>_parse_yyyymm(month)</code>&nbsp;accepts &#8220;YYYY-MM&#8221; or &#8220;YYYYMM&#8221; and normalizes to &#8220;YYYY-MM&#8221;. This makes the interface robust to common formats.</li>
</ul>
</li>



<li>Read source of truth:
<ul class="wp-block-list">
<li>Calls&nbsp;<code>self._download_rows()</code>&nbsp;which fetches the blob (XLSX or CSV) from the configured container and returns rows as dicts. If the blob is missing,&nbsp;<code>_download_rows()</code>&nbsp;returns an empty list.</li>
</ul>
</li>



<li>Iterate and filter:
<ul class="wp-block-list">
<li>For each row, read the&nbsp;<code>Date</code>&nbsp;field. The code accepts:
<ul class="wp-block-list">
<li>Excel date objects (openpyxl returns&nbsp;<code>datetime</code>/<code>date</code>),</li>



<li><code>datetime</code>&nbsp;objects,</li>



<li>or ISO date strings &#8220;YYYY-MM-DD&#8221;.</li>
</ul>
</li>



<li>Convert/normalize to a&nbsp;<code>date</code>, build&nbsp;<code>row_month = "YYYY-MM"</code>&nbsp;and compare with the requested month.</li>



<li>If&nbsp;<code>category</code>&nbsp;is supplied, compare case-insensitively and skip non-matching rows.</li>
</ul>
</li>



<li>Normalize fields:
<ul class="wp-block-list">
<li>Ensure&nbsp;<code>Amount</code>&nbsp;is cast to&nbsp;<code>float()</code>&nbsp;(on failure fallback to 0.0).</li>



<li>Ensure&nbsp;<code>Category</code>&nbsp;and&nbsp;<code>Description</code>&nbsp;are strings.</li>
</ul>
</li>



<li>Return shape:
<ul class="wp-block-list">
<li>A list of dicts like:
<ul class="wp-block-list">
<li>{ &#8220;Date&#8221;: &#8220;YYYY-MM-DD&#8221;, &#8220;Amount&#8221;: float, &#8220;Category&#8221;: str, &#8220;Description&#8221;: str }</li>
</ul>
</li>



<li>This JSON-friendly shape is easy to serialize as an HTTP response or an MCP tool return.</li>
</ul>
</li>
</ul>



<p>Error/edge behavior:</p>



<ul class="wp-block-list">
<li>If month format invalid →&nbsp;<code>_parse_yyyymm</code>&nbsp;raises ValueError.</li>



<li>If no blob exists → returns [] (safe).</li>



<li>Bad amount strings → amount becomes 0.0 for listing (but&nbsp;<code>add_expense</code>&nbsp;raises ValueError for invalid amounts).</li>
</ul>



<p>How it becomes a “tool” (exposure options)</p>



<ul class="wp-block-list">
<li>Direct use in scripts: instantiate&nbsp;<code>ExpenseTracker()</code>&nbsp;and call&nbsp;<code>get_expenses("2025-12")</code>.</li>



<li>Wrap as HTTP endpoints (Azure Functions) where the function handler instantiates&nbsp;<code>ExpenseTracker()</code>&nbsp;and returns the list as JSON.</li>



<li>Register it as an MCP tool wrapper (the repository already contains tooling that triggers these methods)  the method contract is intentionally simple (primitive types + JSON-serializable results).<br><br>example below the get_expenses function </li>
</ul>



<pre class="wp-block-code"><code>def get_expenses(self, month: str, category: Optional&#91;str] = None) -&gt; List&#91;Dict&#91;str, Any]]:
    month = _parse_yyyymm(month)
    rows = self._download_rows()
    result = &#91;]
    for r in rows:
        d = r.get("Date")
        if not d:
            continue
        if isinstance(d, datetime):
            ddate = d.date()
        elif isinstance(d, date):
            ddate = d
        else:
            try:
                ddate = datetime.strptime(str(d), "%Y-%m-%d").date()
            except Exception:
                continue
        row_month = f"{ddate.year:04d}-{ddate.month:02d}"
        if row_month != month:
            continue
        cat = r.get("Category") or ""
        if category and str(cat).strip().lower() != category.strip().lower():
            continue
        amount = r.get("Amount", 0.0)
        try:
            amount = float(amount)
        except Exception:
            amount = 0.0
        result.append({
            "Date": ddate.isoformat(),
            "Amount": amount,
            "Category": str(cat),
            "Description": str(r.get("Description", "")),
        })
    return result</code></pre>



<p class="has-medium-font-size">Where the tool is declared ?</p>



<p>in this part we define the new tool and we call the function</p>



<pre class="wp-block-code"><code>@app.generic_trigger(
    arg_name="context",
    type="mcpToolTrigger",
    toolName="get_expenses",
    description="Retrieve expenses filtered by month and optional category.",
    toolProperties=tool_properties_get_expenses_json,
)
def get_expenses(context) -&gt; str:
    ...</code></pre>



<h2 class="wp-block-heading">Input the tool expects</h2>



<p>The function receives a single&nbsp;<code>context</code>&nbsp;parameter which is a JSON string (the trigger payload). The function parses it like this:</p>



<p>content = json.loads(context)<br>month = content.get(&#8220;arguments&#8221;, {}).get(&#8220;month&#8221;)<br>category = content.get(&#8220;arguments&#8221;, {}).get(&#8220;category&#8221;)</p>



<p>So the caller should send a JSON payload shaped like:</p>



<pre class="wp-block-code"><code>{
  "arguments": {
    "month": "2025-12",
    "category": "IT"            // optional
  }
}</code></pre>



<p class="has-medium-font-size">wrapper function : </p>



<ol class="wp-block-list">
<li>Parse&nbsp;<code>context</code>&nbsp;JSON and extract&nbsp;<code>month</code>&nbsp;and optional&nbsp;<code>category</code>.</li>



<li>Validate required&nbsp;<code>month</code>&nbsp;argument. If missing, return a JSON error object.</li>



<li>Call the underlying tool method:
<ul class="wp-block-list">
<li>Uses&nbsp;<code>_get_tracker()</code>&nbsp;to get a singleton&nbsp;<code>ExpenseTracker</code>&nbsp;instance.</li>



<li>Calls&nbsp;<code>_get_tracker().get_expenses(month=month, category=category)</code>.</li>
</ul>
</li>



<li>Wrap the result in a uniform response object and return it as JSON string:</li>
</ol>



<pre class="wp-block-code"><code>return json.dumps({
    "ok": True,
    "month": month,
    "category": category or "all",
    "count": len(result) if isinstance(result, list) else 0,
    "result": result
})</code></pre>



<h2 class="wp-block-heading has-medium-font-size">Sequence  : </h2>



<p>Client (MCP caller / script)<br>-&gt; sends JSON&nbsp;<code>context</code>&nbsp;to MCP trigger<br>-&gt;&nbsp;<code>function_app.get_expenses(context)</code>&nbsp;wrapper<br>-&gt; parses JSON, validates&nbsp;<code>month</code><br>-&gt; calls&nbsp;<code>_get_tracker().get_expenses(month, category)</code><br>-&gt;&nbsp;<code>ExpenseTracker.get_expenses(...)</code><br>-&gt;&nbsp;<code>_download_rows()</code>&nbsp;reads blob (XLSX/CSV) &lt;&#8211; Azure Blob Storage<br>&lt;- rows<br>&lt;- filtered/normalized result<br>&lt;- wrapper returns JSON string { ok, month, count, result }</p>



<p>In the repo you will find readme file that will explain full code , so no worries.</p>



<p class="has-medium-font-size">3&#x20e3; Adding Environment Variables</p>



<p>To keep settings flexible and secure, I added environment variables for:<br></p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Variable</th><th>Purpose</th></tr></thead><tbody><tr><td><code>AZURE_STORAGE_CONNECTION_STRING</code></td><td>Connect to Storage account</td></tr><tr><td><code>EXPENSES_CONTAINER_SAS_URL</code></td><td>Where expenses CSV lives : container Saas Access</td></tr><tr><td><code>EXPENSES_BLOB_NAME</code></td><td>CSV filename</td></tr><tr><td><code>EXPENSES_BLOB_SAS_URL</code></td><td>Blob Saas Access</td></tr></tbody></table></figure>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="332" src="/wp-content/uploads/2025/11/image-14-1024x332.png" alt="" class="wp-image-2326" srcset="/wp-content/uploads/2025/11/image-14-1024x332.png 1024w, /wp-content/uploads/2025/11/image-14-300x97.png 300w, /wp-content/uploads/2025/11/image-14-768x249.png 768w, /wp-content/uploads/2025/11/image-14-1536x497.png 1536w, /wp-content/uploads/2025/11/image-14-750x243.png 750w, /wp-content/uploads/2025/11/image-14-1140x369.png 1140w, /wp-content/uploads/2025/11/image-14.png 1726w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>


<p class="has-medium-font-size">4&#x20e3; Local Development &amp; Testing</p>



<p>To test everything locally, I used:</p>



<p><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> VS Code : to code and run the azure function =&gt; <a href="https://code.visualstudio.com/?wt.mc_id=MVP_328341">Download here</a> <br><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Python : because we are using python for this demo<br><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Azure Functions Core Tools : <a href="https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local?wt.mc_id=MVP_328341"> Azure Functions Core Tools lets you develop and test your functions on your local computer</a><br><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> MCP Inspector (to simulate LLM connection) : <a href="https://modelcontextprotocol.io/docs/tools/inspector">MCP Inspector</a> will be used later for testing .<br>     it can be launched via the cmd :  npx @modelcontextprotocol/inspector<br><br>      Once you run it you can browse :  http://127.0.0.1:6274/#resources to see the mcp inspector home page and you can connect to your function app by inserting this link to <br>      http://localhost:7071/runtime/webhooks/mcp/sse to the URL and set <br>     </p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="428" src="/wp-content/uploads/2025/11/image-18-1024x428.png" alt="" class="wp-image-2334" srcset="/wp-content/uploads/2025/11/image-18-1024x428.png 1024w, /wp-content/uploads/2025/11/image-18-300x125.png 300w, /wp-content/uploads/2025/11/image-18-768x321.png 768w, /wp-content/uploads/2025/11/image-18-1536x641.png 1536w, /wp-content/uploads/2025/11/image-18-750x313.png 750w, /wp-content/uploads/2025/11/image-18-1140x476.png 1140w, /wp-content/uploads/2025/11/image-18.png 1892w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>


<p>You can choose any tool and test it from the List Tools : <br></p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="376" src="/wp-content/uploads/2025/11/image-19-1024x376.png" alt="" class="wp-image-2336" srcset="/wp-content/uploads/2025/11/image-19-1024x376.png 1024w, /wp-content/uploads/2025/11/image-19-300x110.png 300w, /wp-content/uploads/2025/11/image-19-768x282.png 768w, /wp-content/uploads/2025/11/image-19-1536x564.png 1536w, /wp-content/uploads/2025/11/image-19-750x275.png 750w, /wp-content/uploads/2025/11/image-19-1140x419.png 1140w, /wp-content/uploads/2025/11/image-19.png 1893w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>


<p><br><br><br><img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> An storage emulator : An storage emulator is needed when developing azure function app in VScode :      <a href="https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite?wt.mc_id=MVP_328341">Azurite emulator for local Azure Storage development</a><br>     You can run the Azurite in VS Code&nbsp; : C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\Extensions\Microsoft\Azure Storage Emulator&gt; .\azurite.exe<br>     or Using Docker : docker run -p 10000:10000 -p 10001:10001 -p 10002:10002  mcr.microsoft.com/azure-storage/azurite<br></p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="167" src="/wp-content/uploads/2025/11/image-15-1024x167.png" alt="" class="wp-image-2330" srcset="/wp-content/uploads/2025/11/image-15-1024x167.png 1024w, /wp-content/uploads/2025/11/image-15-300x49.png 300w, /wp-content/uploads/2025/11/image-15-768x125.png 768w, /wp-content/uploads/2025/11/image-15-1536x250.png 1536w, /wp-content/uploads/2025/11/image-15-750x122.png 750w, /wp-content/uploads/2025/11/image-15-1140x185.png 1140w, /wp-content/uploads/2025/11/image-15.png 1684w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>


<p class="has-text-align-center"><br></p>



<p class="has-medium-font-size">5&#x20e3; Deploying to Azure Functions</p>



<p>Once everything worked locally:</p>



<ul class="wp-block-list">
<li>Created an Azure Function App</li>



<li>Pushed the code via VS Code deployment</li>



<li>Added same environment variables in Azure portal</li>



<li>Uploaded/created the blob file for storage</li>
</ul>



<p>The simplest way to deploy an azure function via vs code is to click on it and select :  Deploy to function app  (As I&#8217;m writing this article, I&#8217;m also planning to prepare a Terraform version of this Azure Function to streamline and automate the deployment process.)<br></p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="610" src="/wp-content/uploads/2025/11/image-21-1024x610.png" alt="" class="wp-image-2339" srcset="/wp-content/uploads/2025/11/image-21-1024x610.png 1024w, /wp-content/uploads/2025/11/image-21-300x179.png 300w, /wp-content/uploads/2025/11/image-21-768x458.png 768w, /wp-content/uploads/2025/11/image-21-1536x915.png 1536w, /wp-content/uploads/2025/11/image-21-750x447.png 750w, /wp-content/uploads/2025/11/image-21-1140x679.png 1140w, /wp-content/uploads/2025/11/image-21.png 1752w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>

<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="553" src="/wp-content/uploads/2025/11/image-23-1024x553.png" alt="" class="wp-image-2341" srcset="/wp-content/uploads/2025/11/image-23-1024x553.png 1024w, /wp-content/uploads/2025/11/image-23-300x162.png 300w, /wp-content/uploads/2025/11/image-23-768x415.png 768w, /wp-content/uploads/2025/11/image-23-1536x830.png 1536w, /wp-content/uploads/2025/11/image-23-750x405.png 750w, /wp-content/uploads/2025/11/image-23-1140x616.png 1140w, /wp-content/uploads/2025/11/image-23.png 1538w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>


<p>Once the app is deployed , you can see the tools by clicking on functions from the portal : <br></p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="592" src="/wp-content/uploads/2025/11/image-25-1024x592.png" alt="" class="wp-image-2343" srcset="/wp-content/uploads/2025/11/image-25-1024x592.png 1024w, /wp-content/uploads/2025/11/image-25-300x173.png 300w, /wp-content/uploads/2025/11/image-25-768x444.png 768w, /wp-content/uploads/2025/11/image-25-1536x888.png 1536w, /wp-content/uploads/2025/11/image-25-750x434.png 750w, /wp-content/uploads/2025/11/image-25-1140x659.png 1140w, /wp-content/uploads/2025/11/image-25.png 1557w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>


<p>Now before we go and test on MCP inspector or vs code we need to copy the system keys to use (not the best practice for now ,but its for the demo) .<br>where to find it ? simply go to App Keys and copy the mcp_extension key and save it .<br></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="584" src="/wp-content/uploads/2025/11/image-26-1024x584.png" alt="" class="wp-image-2346" srcset="/wp-content/uploads/2025/11/image-26-1024x584.png 1024w, /wp-content/uploads/2025/11/image-26-300x171.png 300w, /wp-content/uploads/2025/11/image-26-768x438.png 768w, /wp-content/uploads/2025/11/image-26-1536x876.png 1536w, /wp-content/uploads/2025/11/image-26-750x428.png 750w, /wp-content/uploads/2025/11/image-26-1140x650.png 1140w, /wp-content/uploads/2025/11/image-26.png 1580w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>If you&#8217;re familiar with the Model Context Protocol and how servers work with it, you know that we need an <code>mcp.json</code> file to define the MCP servers we plan to use.<br></p>



<pre class="wp-block-code"><code>{
    "inputs": &#91;
        {
            "type": "promptString",
            "id": "functions-mcp-extension-system-key",
            "description": "Azure Functions MCP Extension System Key",
            "password": true
        },
        {
            "type": "promptString",
            "id": "functionapp-name",
            "description": "Azure Functions App Name"
        }
    ],
    "servers": {
        "remote-mcp-function": {
            "type": "sse",
            "url": "https://${input:functionapp-name}.azurewebsites.net/runtime/webhooks/mcp/sse",
            "headers": {
                "x-functions-key": "${input:functions-mcp-extension-system-key}"
            }
        },
        "local-mcp-function": {
            "type": "sse",
            "url": "http://0.0.0.0:7071/runtime/webhooks/mcp/sse"
        }
    }
}</code></pre>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="899" height="191" src="/wp-content/uploads/2025/11/image-28.png" alt="" class="wp-image-2348" srcset="/wp-content/uploads/2025/11/image-28.png 899w, /wp-content/uploads/2025/11/image-28-300x64.png 300w, /wp-content/uploads/2025/11/image-28-768x163.png 768w, /wp-content/uploads/2025/11/image-28-750x159.png 750w" sizes="(max-width: 899px) 100vw, 899px" /></figure></div>


<p>You can add a new server always by using the CTRL+shift +P <br></p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="760" height="171" src="/wp-content/uploads/2025/11/image-30.png" alt="" class="wp-image-2350" srcset="/wp-content/uploads/2025/11/image-30.png 760w, /wp-content/uploads/2025/11/image-30-300x68.png 300w, /wp-content/uploads/2025/11/image-30-750x169.png 750w" sizes="(max-width: 760px) 100vw, 760px" /></figure></div>


<p class="has-medium-font-size"><br>Storage account : </p>



<p class="has-small-font-size">I have uploaded a simple csvp file to a storage account on azure and i genrated SAS token for the blob and for the container of the blob<br></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="581" src="/wp-content/uploads/2025/11/image-31-1024x581.png" alt="" class="wp-image-2352" srcset="/wp-content/uploads/2025/11/image-31-1024x581.png 1024w, /wp-content/uploads/2025/11/image-31-300x170.png 300w, /wp-content/uploads/2025/11/image-31-768x436.png 768w, /wp-content/uploads/2025/11/image-31-750x425.png 750w, /wp-content/uploads/2025/11/image-31.png 1033w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="has-small-font-size"><br></p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="364" src="/wp-content/uploads/2025/11/image-33-1024x364.png" alt="" class="wp-image-2354" srcset="/wp-content/uploads/2025/11/image-33-1024x364.png 1024w, /wp-content/uploads/2025/11/image-33-300x107.png 300w, /wp-content/uploads/2025/11/image-33-768x273.png 768w, /wp-content/uploads/2025/11/image-33-750x266.png 750w, /wp-content/uploads/2025/11/image-33-1140x405.png 1140w, /wp-content/uploads/2025/11/image-33.png 1225w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>


<p class="has-small-font-size"></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="760" src="/wp-content/uploads/2025/11/image-34-1024x760.png" alt="" class="wp-image-2355" srcset="/wp-content/uploads/2025/11/image-34-1024x760.png 1024w, /wp-content/uploads/2025/11/image-34-300x223.png 300w, /wp-content/uploads/2025/11/image-34-768x570.png 768w, /wp-content/uploads/2025/11/image-34-750x557.png 750w, /wp-content/uploads/2025/11/image-34-1140x846.png 1140w, /wp-content/uploads/2025/11/image-34.png 1249w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="has-small-font-size"><br></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="751" src="/wp-content/uploads/2025/11/image-35-1024x751.png" alt="" class="wp-image-2357" srcset="/wp-content/uploads/2025/11/image-35-1024x751.png 1024w, /wp-content/uploads/2025/11/image-35-300x220.png 300w, /wp-content/uploads/2025/11/image-35-768x564.png 768w, /wp-content/uploads/2025/11/image-35-750x550.png 750w, /wp-content/uploads/2025/11/image-35-1140x837.png 1140w, /wp-content/uploads/2025/11/image-35.png 1240w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="has-small-font-size"><br><br>Generate two sas and save them because we will use them later</p>



<p class="has-medium-font-size"><br><br>6&#x20e3; Testing our MCP server</p>



<p>First lets run the MCP server in VS Code : </p>



<pre class="wp-block-code"><code>cd src
pip install -r requirements.txt
func start

</code></pre>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="605" src="/wp-content/uploads/2025/11/image-37-1024x605.png" alt="" class="wp-image-2360" srcset="/wp-content/uploads/2025/11/image-37-1024x605.png 1024w, /wp-content/uploads/2025/11/image-37-300x177.png 300w, /wp-content/uploads/2025/11/image-37-768x454.png 768w, /wp-content/uploads/2025/11/image-37-750x443.png 750w, /wp-content/uploads/2025/11/image-37-1140x674.png 1140w, /wp-content/uploads/2025/11/image-37.png 1315w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>


<p>you make sure you already have the mcp inspector runing and also the  <a href="https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite?wt.mc_id=MVP_328341">Azurite emulator for local Azure Storage development</a> and now open the mcp inspector page and paste that url on the url tab : <br></p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="542" src="/wp-content/uploads/2025/11/image-41-1024x542.png" alt="" class="wp-image-2365" srcset="/wp-content/uploads/2025/11/image-41-1024x542.png 1024w, /wp-content/uploads/2025/11/image-41-300x159.png 300w, /wp-content/uploads/2025/11/image-41-768x406.png 768w, /wp-content/uploads/2025/11/image-41-1536x813.png 1536w, /wp-content/uploads/2025/11/image-41-750x397.png 750w, /wp-content/uploads/2025/11/image-41-1140x603.png 1140w, /wp-content/uploads/2025/11/image-41.png 1882w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>


<p>Testing the online server : <br><br>Now that we&#8217;ve tested the local server and added our MCP server to the <code>mcp.json</code> file, there&#8217;s one final step before we test it. We need to add the environment variables — using the values we copied earlier — to the <code>local.settings.json</code> file</p>



<pre class="wp-block-code"><code>{
    "IsEncrypted": false,
    "Values": {
      "FUNCTIONS_WORKER_RUNTIME": "python",
      "AzureWebJobsStorage": "UseDevelopmentStorage=true",
      "EXPENSES_CONTAINER_SAS_URL": "EXPENSES_CONTAINER_SAS_URL",
      "EXPENSES_BLOB_NAME": "expenses.sample.csv",
      "EXPENSES_BLOB_SAS_URL": "EXPENSES_BLOB_SAS_URL"
    }
  }</code></pre>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="445" src="/wp-content/uploads/2025/11/image-43-1024x445.png" alt="" class="wp-image-2369" srcset="/wp-content/uploads/2025/11/image-43-1024x445.png 1024w, /wp-content/uploads/2025/11/image-43-300x130.png 300w, /wp-content/uploads/2025/11/image-43-768x334.png 768w, /wp-content/uploads/2025/11/image-43-1536x667.png 1536w, /wp-content/uploads/2025/11/image-43-750x326.png 750w, /wp-content/uploads/2025/11/image-43-1140x495.png 1140w, /wp-content/uploads/2025/11/image-43.png 1561w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>


<p>To test the setup, copy the Azure Function URL and append <code>/runtime/webhooks/mcp/sse</code> to it.<br>Then, go to <strong>Authentication</strong>, select the app key, and use it to authenticate the request.<br>Make sure to set the header name to <code>x-functions-key</code>.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="490" src="/wp-content/uploads/2025/11/image-44-1024x490.png" alt="" class="wp-image-2370" srcset="/wp-content/uploads/2025/11/image-44-1024x490.png 1024w, /wp-content/uploads/2025/11/image-44-300x144.png 300w, /wp-content/uploads/2025/11/image-44-768x368.png 768w, /wp-content/uploads/2025/11/image-44-1536x735.png 1536w, /wp-content/uploads/2025/11/image-44-750x359.png 750w, /wp-content/uploads/2025/11/image-44-1140x546.png 1140w, /wp-content/uploads/2025/11/image-44.png 1876w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p></p>



<p class="has-medium-font-size">Testing our MCP server with GitHub Copilot </p>



<p>Testing an MCP server with GitHub Copilot means configuring the server in your development environment so Copilot Chat can leverage it for richer context and enhanced capabilities.<br>we have already added the configuration in the mcp.json we should see the server running by now and we have Agent mode selected .<br></p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="323" src="/wp-content/uploads/2025/11/image-45-1024x323.png" alt="" class="wp-image-2373" srcset="/wp-content/uploads/2025/11/image-45-1024x323.png 1024w, /wp-content/uploads/2025/11/image-45-300x95.png 300w, /wp-content/uploads/2025/11/image-45-768x243.png 768w, /wp-content/uploads/2025/11/image-45-750x237.png 750w, /wp-content/uploads/2025/11/image-45-1140x360.png 1140w, /wp-content/uploads/2025/11/image-45.png 1491w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>

<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="831" height="651" src="/wp-content/uploads/2025/11/image-47.png" alt="" class="wp-image-2375" srcset="/wp-content/uploads/2025/11/image-47.png 831w, /wp-content/uploads/2025/11/image-47-300x235.png 300w, /wp-content/uploads/2025/11/image-47-768x602.png 768w, /wp-content/uploads/2025/11/image-47-750x588.png 750w" sizes="(max-width: 831px) 100vw, 831px" /></figure></div>


<p>Lets try another tool  , lets add some expenses : <br></p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="873" height="431" src="/wp-content/uploads/2025/11/image-49.png" alt="" class="wp-image-2378" srcset="/wp-content/uploads/2025/11/image-49.png 873w, /wp-content/uploads/2025/11/image-49-300x148.png 300w, /wp-content/uploads/2025/11/image-49-768x379.png 768w, /wp-content/uploads/2025/11/image-49-750x370.png 750w" sizes="(max-width: 873px) 100vw, 873px" /></figure></div>


<p class="has-medium-font-size"><br>Testing our MCP server with Claude Desktop : </p>



<p class="has-small-font-size">first we need to edit the claude_desktop_config.json under the &nbsp;C:\Users\&lt;username&gt;\AppData\Roaming\Claude<br></p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="586" src="/wp-content/uploads/2025/11/image-55-1024x586.png" alt="" class="wp-image-2386" srcset="/wp-content/uploads/2025/11/image-55-1024x586.png 1024w, /wp-content/uploads/2025/11/image-55-300x172.png 300w, /wp-content/uploads/2025/11/image-55-768x440.png 768w, /wp-content/uploads/2025/11/image-55-750x429.png 750w, /wp-content/uploads/2025/11/image-55-1140x652.png 1140w, /wp-content/uploads/2025/11/image-55.png 1508w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>


<p>We need to add to the file the config below </p>



<pre class="wp-block-code"><code>{
  "mcpServers": {
    "my‑mcp": {
      "command": "npx",
      "args": &#91;
        "mcp-remote",
        "http://localhost:7071/runtime/webhooks/mcp/sse"
      ]
    }
  }
}
</code></pre>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="895" height="620" src="/wp-content/uploads/2025/11/image-53.png" alt="" class="wp-image-2384" srcset="/wp-content/uploads/2025/11/image-53.png 895w, /wp-content/uploads/2025/11/image-53-300x208.png 300w, /wp-content/uploads/2025/11/image-53-768x532.png 768w, /wp-content/uploads/2025/11/image-53-750x520.png 750w" sizes="(max-width: 895px) 100vw, 895px" /></figure></div>


<p>we can see our local server up and running ,its time to test</p>



<p></p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="623" src="/wp-content/uploads/2025/11/image-51-1024x623.png" alt="" class="wp-image-2382" srcset="/wp-content/uploads/2025/11/image-51-1024x623.png 1024w, /wp-content/uploads/2025/11/image-51-300x182.png 300w, /wp-content/uploads/2025/11/image-51-768x467.png 768w, /wp-content/uploads/2025/11/image-51-750x456.png 750w, /wp-content/uploads/2025/11/image-51-1140x693.png 1140w, /wp-content/uploads/2025/11/image-51.png 1380w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>

<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="706" src="/wp-content/uploads/2025/11/image-57-1024x706.png" alt="" class="wp-image-2388" srcset="/wp-content/uploads/2025/11/image-57-1024x706.png 1024w, /wp-content/uploads/2025/11/image-57-300x207.png 300w, /wp-content/uploads/2025/11/image-57-768x530.png 768w, /wp-content/uploads/2025/11/image-57-750x517.png 750w, /wp-content/uploads/2025/11/image-57.png 1086w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>


<h2 class="wp-block-heading">Conclusion</h2>



<p>In this guide, we walked through how to create an MCP server using <strong>Azure Functions</strong> and <strong>Python</strong>, and tested it with tools like <strong>MCP Inspector</strong>, <strong>VS Code</strong>, and <strong>Claude Desktop</strong>. By following these steps, you now have a fully functional server environment ready for further experimentation and development.</p>



<p>In our next blog post, we’ll explore how to achieve the same setup using <strong>C#</strong>, giving you an alternative approach and expanding your toolkit for building MCP servers in Azure. Stay tuned!</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://achrafbenalaya.com/2025/11/02/build-and-host-an-expense-tracking-mcp-server-with-azure-functions/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2292</post-id>	</item>
		<item>
		<title>Model Context Protocol (MCP): The Future of AI Integration</title>
		<link>https://achrafbenalaya.com/2025/04/21/model-context-protocol-mcp-the-future-of-ai-integration/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=model-context-protocol-mcp-the-future-of-ai-integration</link>
					<comments>https://achrafbenalaya.com/2025/04/21/model-context-protocol-mcp-the-future-of-ai-integration/#respond</comments>
		
		<dc:creator><![CDATA[achraf]]></dc:creator>
		<pubDate>Mon, 21 Apr 2025 12:03:04 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[mcp]]></category>
		<guid isPermaLink="false">https://achrafbenalaya.com/?p=2207</guid>

					<description><![CDATA[For the last couple of weeks, I&#8217;ve been seeing MCP servers and clients shared everywhere by different people. With all this buzz, I decided it was time to explore what MCP is, what it can be used for, and whether it represents a revolution in AI. This is my first blog post on the topic, [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>For the last couple of weeks, I&#8217;ve been seeing MCP servers and clients shared everywhere by different people. With all this buzz, I decided it was time to explore what MCP is, what it can be used for, and whether it represents a revolution in AI. This is my first blog post on the topic, and I plan to continue writing about it because I believe we&#8217;re entering a new era of AI integration.</p>



<h3 class="wp-block-heading">What is MCP (Model Context Protocol)?</h3>



<p>The Model Context Protocol (MCP) is an open protocol developed by Anthropic that enables large language models (LLMs) to integrate with external data sources and tools in a standardized way. It creates a framework that allows AI tools to communicate with each other seamlessly.</p>



<p>In simpler terms, instead of building custom adapters every time we want an AI tool to perform a specific function—like reading a Figma design or managing a database—MCP lets us plug that tool in directly, provided our main AI interface understands the protocol.</p>



<p>MCP defines how AI models can:</p>



<ul class="wp-block-list">
<li>Call external tools</li>



<li>Fetch data</li>



<li>Interact with various services</li>



<li>Access context in a manner that&#8217;s generalizable across different integrations<br><br></li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="561" src="/wp-content/uploads/2025/04/Untitled-2025-02-21-0925-1024x561.png" alt="" class="wp-image-2211" srcset="/wp-content/uploads/2025/04/Untitled-2025-02-21-0925-1024x561.png 1024w, /wp-content/uploads/2025/04/Untitled-2025-02-21-0925-300x164.png 300w, /wp-content/uploads/2025/04/Untitled-2025-02-21-0925-768x421.png 768w, /wp-content/uploads/2025/04/Untitled-2025-02-21-0925-1536x842.png 1536w, /wp-content/uploads/2025/04/Untitled-2025-02-21-0925-2048x1122.png 2048w, /wp-content/uploads/2025/04/Untitled-2025-02-21-0925-750x411.png 750w, /wp-content/uploads/2025/04/Untitled-2025-02-21-0925-1140x625.png 1140w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Why Use MCP?</h2>



<p>Consider the traditional approach when you want your AI model to connect to your resources. You would need to:</p>



<ol class="wp-block-list">
<li>Ask your developers to create custom connectors or extensions</li>



<li>Create web APIs</li>



<li>Handle authentication</li>



<li>Develop additional functionality as needs arise</li>
</ol>



<p>MCP eliminates this complexity by providing a standardized way for AI models to interact with external tools and data sources.</p>



<h2 class="wp-block-heading">Real-World Example: Updating My Microsoft Acronyms Project</h2>



<p>To demonstrate MCP&#8217;s capabilities, I tested it on a small project I created two years ago: <a href="https://himhelloworld.com/">Microsoft Acronyms</a>. Since I&#8217;ve been busy with work, family, and other projects, I hadn&#8217;t updated it with the latest acronyms.</p>



<h3 class="wp-block-heading">Traditional Process (Without MCP)</h3>



<p>Without MCP, updating the site would require me to:</p>



<ol class="wp-block-list">
<li>Go to GitHub and examine the project structure</li>



<li>Search the internet for new Microsoft acronyms</li>



<li>Compare them against what&#8217;s already on my website</li>



<li>Consult an AI model like GPT about the newest acronyms</li>



<li>Pull the project</li>



<li>Create a branch</li>



<li>Update the file</li>



<li>Push changes</li>



<li>Create a pull request</li>
</ol>



<h3 class="wp-block-heading">With MCP</h3>



<p>Using MCP and a GitHub MCP server, I simply asked in one prompt: &#8220;Can you create a new pull request on my repo: MicrosoftAcronyms001 and also update the data.tsx file with more and newer Microsoft Acronyms?&#8221;</p>



<p>That&#8217;s it! A new PR was created with updated content, no manual intervention required.<br><br></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="500" src="/wp-content/uploads/2025/04/vscode-1024x500.png" alt="" class="wp-image-2213" srcset="/wp-content/uploads/2025/04/vscode-1024x500.png 1024w, /wp-content/uploads/2025/04/vscode-300x146.png 300w, /wp-content/uploads/2025/04/vscode-768x375.png 768w, /wp-content/uploads/2025/04/vscode-1536x750.png 1536w, /wp-content/uploads/2025/04/vscode-2048x1000.png 2048w, /wp-content/uploads/2025/04/vscode-750x366.png 750w, /wp-content/uploads/2025/04/vscode-1140x556.png 1140w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Setting Up the GitHub MCP Server</h2>



<p>If you want to try this yourself, here&#8217;s how to set up the GitHub MCP server:</p>



<ol class="wp-block-list">
<li>First, download the GitHub MCP Server from: <a href="https://github.com/github/github-mcp-server">https://github.com/github/github-mcp-server</a></li>



<li>In Visual Studio Code, go to Settings and activate the MCP server option.</li>



<li>Edit the settings.json file to add your server(s). You&#8217;ll need to replace <code>${input:github_token}</code> with a Personal Access Token (PAT) generated from your GitHub account:</li>
</ol>



<pre class="wp-block-code"><code>{
  "mcp": {
    "inputs": &#91;
      {
        "type": "promptString",
        "id": "github_token",
        "description": "GitHub Personal Access Token",
        "password": true
      }
    ],
    "servers": {
      "github": {
        "command": "docker",
        "args": &#91;
          "run",
          "-i",
          "--rm",
          "-e",
          "GITHUB_PERSONAL_ACCESS_TOKEN",
          "ghcr.io/github/github-mcp-server"
        ],
        "env": {
          "GITHUB_PERSONAL_ACCESS_TOKEN": "${input:github_token}"
        }
      }
    }
  }
}</code></pre>



<ol class="wp-block-list">
<li>Click &#8220;Run&#8221; and Docker will launch the server locally. (If you prefer not to use Docker, check the official repository for alternative configuration options.) </li>



<li>Once the server is running, go to Agent mode in Visual Studio Code and check the tool buttons for available servers &#8211; you should see your MCP server listed. </li>



<li>Now you can ask Copilot (with Agent mode and the MCP server for GitHub) to perform tasks like creating pull requests or updating files.</li>
</ol>



<p><strong>Important Note:</strong> Make sure your PAT has the correct permissions. When I first tried this, I had only given read permissions, which prevented the MCP from creating the pull request.</p>



<div class="wp-block-cover"><span aria-hidden="true" class="wp-block-cover__background has-background-dim"></span><img loading="lazy" decoding="async" width="1024" height="734" class="wp-block-cover__image-background wp-image-2215" alt="" src="/wp-content/uploads/2025/04/p-1024x734.png" style="object-position:72% 31%" data-object-fit="cover" data-object-position="72% 31%" srcset="/wp-content/uploads/2025/04/p-1024x734.png 1024w, /wp-content/uploads/2025/04/p-300x215.png 300w, /wp-content/uploads/2025/04/p-768x551.png 768w, /wp-content/uploads/2025/04/p-1536x1101.png 1536w, /wp-content/uploads/2025/04/p-120x86.png 120w, /wp-content/uploads/2025/04/p-350x250.png 350w, /wp-content/uploads/2025/04/p-750x538.png 750w, /wp-content/uploads/2025/04/p-1140x817.png 1140w, /wp-content/uploads/2025/04/p.png 1907w" sizes="(max-width: 1024px) 100vw, 1024px" /><div class="wp-block-cover__inner-container is-layout-flow wp-block-cover-is-layout-flow">
<p class="has-text-align-center">MCP SERVER running</p>
</div></div>



<p>Now since the server is running , we click on the button select tools , and we scroll down we can see any MCP server that we have added .</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="1018" src="/wp-content/uploads/2025/04/git-1024x1018.png" alt="available servers " class="wp-image-2216" title="available servers " srcset="/wp-content/uploads/2025/04/git-1024x1018.png 1024w, /wp-content/uploads/2025/04/git-300x298.png 300w, /wp-content/uploads/2025/04/git-150x150.png 150w, /wp-content/uploads/2025/04/git-768x764.png 768w, /wp-content/uploads/2025/04/git-75x75.png 75w, /wp-content/uploads/2025/04/git-750x746.png 750w, /wp-content/uploads/2025/04/git-1140x1133.png 1140w, /wp-content/uploads/2025/04/git.png 1384w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>now after I asked the Model that i have used here : Claude 3.7 , as you can see it&#8221;s asked me to use the mcp server I provided  , and started to use it&#8217;s sub models to aces my repo , get the file content that i need it to be updated it and create new branch.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="834" height="1024" src="/wp-content/uploads/2025/04/data-834x1024.png" alt="" class="wp-image-2218" srcset="/wp-content/uploads/2025/04/data-834x1024.png 834w, /wp-content/uploads/2025/04/data-244x300.png 244w, /wp-content/uploads/2025/04/data-768x943.png 768w, /wp-content/uploads/2025/04/data-750x921.png 750w, /wp-content/uploads/2025/04/data.png 977w" sizes="(max-width: 834px) 100vw, 834px" /></figure>



<p><br><br>Results :  As you can see , I have a PR created and that have updated the file with some Acronyms , the pipeline worked fine and the file contain new content</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="628" src="/wp-content/uploads/2025/04/pr-1024x628.png" alt="" class="wp-image-2220" srcset="/wp-content/uploads/2025/04/pr-1024x628.png 1024w, /wp-content/uploads/2025/04/pr-300x184.png 300w, /wp-content/uploads/2025/04/pr-768x471.png 768w, /wp-content/uploads/2025/04/pr-1536x942.png 1536w, /wp-content/uploads/2025/04/pr-750x460.png 750w, /wp-content/uploads/2025/04/pr-1140x699.png 1140w, /wp-content/uploads/2025/04/pr.png 1806w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>And now I asked to merge the Pull request too : <br></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="527" src="/wp-content/uploads/2025/04/image-1024x527.png" alt="" class="wp-image-2224" srcset="/wp-content/uploads/2025/04/image-1024x527.png 1024w, /wp-content/uploads/2025/04/image-300x154.png 300w, /wp-content/uploads/2025/04/image-768x395.png 768w, /wp-content/uploads/2025/04/image-1536x790.png 1536w, /wp-content/uploads/2025/04/image-2048x1054.png 2048w, /wp-content/uploads/2025/04/image-750x386.png 750w, /wp-content/uploads/2025/04/image-1140x587.png 1140w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>After the merge , i went to my website to test the new acronyms if its exist and the result as you can see , it works .</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="412" src="/wp-content/uploads/2025/04/image-1-1024x412.png" alt="" class="wp-image-2225" srcset="/wp-content/uploads/2025/04/image-1-1024x412.png 1024w, /wp-content/uploads/2025/04/image-1-300x121.png 300w, /wp-content/uploads/2025/04/image-1-768x309.png 768w, /wp-content/uploads/2025/04/image-1-1536x618.png 1536w, /wp-content/uploads/2025/04/image-1-750x302.png 750w, /wp-content/uploads/2025/04/image-1-1140x459.png 1140w, /wp-content/uploads/2025/04/image-1.png 1872w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p><br><br></p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>MCP represents a significant advancement in how we integrate AI models with external tools and data. By providing a standardized protocol for these interactions, it eliminates the need for custom development work and makes AI integration much more accessible.</p>



<p>Isn&#8217;t it amazing that all of this can be accomplished without developing any connectors or manual intervention? I believe MCP is just the beginning of a new era in AI integration, and I look forward to exploring its capabilities further in future posts.<br><br>List of available Servers &amp; Clients :  https://github.com/modelcontextprotocol/servers?tab=readme-ov-file</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://achrafbenalaya.com/2025/04/21/model-context-protocol-mcp-the-future-of-ai-integration/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2207</post-id>	</item>
		<item>
		<title>Understanding Generative AI and RAG Benefits</title>
		<link>https://achrafbenalaya.com/2025/01/12/understanding-generative-ai-and-rag-benefits/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=understanding-generative-ai-and-rag-benefits</link>
		
		<dc:creator><![CDATA[achraf]]></dc:creator>
		<pubDate>Sun, 12 Jan 2025 19:56:29 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Home]]></category>
		<guid isPermaLink="false">https://achrafbenalaya.com/?p=2084</guid>

					<description><![CDATA[What is Generative AI? 🤖 Think of it as a Super-Smart Creative Assistant Real-Life Example 🎯 Just like how a chef can create new recipes from ingredients, Gen AI creates new content from what it has learned! How Does Gen AI Work? 🎓 Three Simple Steps: Common Gen AI Tools You Might Know 🛠️ But [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">What is Generative AI? <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f916.png" alt="🤖" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<h3 class="wp-block-heading" id="bh-G0aRrEW4MEzjD39PsIUjy">Think of it as a Super-Smart Creative Assistant</h3>



<ul id="bh-E_gvnOVzf6bv7WKitvKvJ" class="wp-block-list">
<li>It&#8217;s like having a helper that can:<br>
<ul class="wp-block-list">
<li>Write stories and emails</li>



<li>Create images from descriptions</li>



<li>Answer questions</li>



<li>Complete your sentences</li>



<li>Help with coding<br></li>
</ul>
</li>
</ul>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="963" data-id="2088" src="/wp-content/uploads/2025/01/Understanding-Generative-AI-and-RAG-visual-selection-1024x963.png" alt="" class="wp-image-2088" srcset="/wp-content/uploads/2025/01/Understanding-Generative-AI-and-RAG-visual-selection-1024x963.png 1024w, /wp-content/uploads/2025/01/Understanding-Generative-AI-and-RAG-visual-selection-300x282.png 300w, /wp-content/uploads/2025/01/Understanding-Generative-AI-and-RAG-visual-selection-768x722.png 768w, /wp-content/uploads/2025/01/Understanding-Generative-AI-and-RAG-visual-selection-1536x1445.png 1536w, /wp-content/uploads/2025/01/Understanding-Generative-AI-and-RAG-visual-selection-750x705.png 750w, /wp-content/uploads/2025/01/Understanding-Generative-AI-and-RAG-visual-selection-1140x1072.png 1140w, /wp-content/uploads/2025/01/Understanding-Generative-AI-and-RAG-visual-selection.png 1935w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</figure>



<h3 class="wp-block-heading">Real-Life Example <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> </h3>



<p>Just like how a chef can create new recipes from ingredients, Gen AI creates new content from what it has learned!</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1503" height="898" data-id="2092" src="/wp-content/uploads/2025/01/2-1024x612.png" alt="" class="wp-image-2092" srcset="/wp-content/uploads/2025/01/2-1024x612.png 1024w, /wp-content/uploads/2025/01/2-300x179.png 300w, /wp-content/uploads/2025/01/2-768x459.png 768w, /wp-content/uploads/2025/01/2-750x448.png 750w, /wp-content/uploads/2025/01/2-1140x681.png 1140w, /wp-content/uploads/2025/01/2.png 1503w" sizes="(max-width: 1503px) 100vw, 1503px" /></figure>
</figure>



<h2 class="wp-block-heading">How Does Gen AI Work? <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f393.png" alt="🎓" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<h3 class="wp-block-heading" id="bh-_AUmnx-XYY91E4B8dAByT">Three Simple Steps:</h3>



<ol id="bh-cNFAsI9XRmeXbvaeyuXOI" class="wp-block-list">
<li>Learning Phase <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f4da.png" alt="📚" class="wp-smiley" style="height: 1em; max-height: 1em;" />
<ul class="wp-block-list">
<li>Reads tons of information (like reading millions of books)</li>



<li>Learns patterns (like learning a language)<br></li>
</ul>
</li>



<li>Understanding Phase <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f9e0.png" alt="🧠" class="wp-smiley" style="height: 1em; max-height: 1em;" />
<ul class="wp-block-list">
<li>Recognizes what you&#8217;re asking</li>



<li>Processes your request<br></li>
</ul>
</li>



<li>Creation Phase <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2728.png" alt="✨" class="wp-smiley" style="height: 1em; max-height: 1em;" />
<ul class="wp-block-list">
<li>Creates new content based on what it learned</li>



<li>Tries to be helpful and relevant</li>
</ul>
</li>
</ol>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="920" height="1024" src="/wp-content/uploads/2025/01/3-920x1024.png" alt="" class="wp-image-2094" srcset="/wp-content/uploads/2025/01/3-920x1024.png 920w, /wp-content/uploads/2025/01/3-270x300.png 270w, /wp-content/uploads/2025/01/3-768x855.png 768w, /wp-content/uploads/2025/01/3-750x835.png 750w, /wp-content/uploads/2025/01/3-1140x1269.png 1140w, /wp-content/uploads/2025/01/3.png 1273w" sizes="(max-width: 920px) 100vw, 920px" /></figure>



<h2 class="wp-block-heading">Common Gen AI Tools You Might Know <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f6e0.png" alt="🛠" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<ul id="bh-mQ3PDQWZnJRguuPqVIDtC" class="wp-block-list">
<li>ChatGPT: Your friendly chat buddy</li>



<li>DALL-E: The digital artist</li>



<li>GitHub Copilot: Your coding assistant</li>



<li>Midjourney: The image creator</li>



<li>Claude: The helpful analyst</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="520" src="/wp-content/uploads/2025/01/4-1024x520.png" alt="" class="wp-image-2095" srcset="/wp-content/uploads/2025/01/4-1024x520.png 1024w, /wp-content/uploads/2025/01/4-300x152.png 300w, /wp-content/uploads/2025/01/4-768x390.png 768w, /wp-content/uploads/2025/01/4-1536x780.png 1536w, /wp-content/uploads/2025/01/4-2048x1041.png 2048w, /wp-content/uploads/2025/01/4-750x381.png 750w, /wp-content/uploads/2025/01/4-1140x579.png 1140w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">But Wait, There&#8217;s a Catch! <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<h3 class="wp-block-heading" id="bh-0x1DEW-EPpr5XdUHSfRj0">Limitations of Basic Gen AI:</h3>



<ul id="bh-8pId3tsY-x0JivvM28EXg" class="wp-block-list">
<li>Sometimes makes things up</li>



<li>Can be outdated</li>



<li>Might mix up facts</li>



<li>Doesn&#8217;t know about your specific needs</li>
</ul>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="691" data-id="2097" src="/wp-content/uploads/2025/01/5-1024x691.png" alt="" class="wp-image-2097" srcset="/wp-content/uploads/2025/01/5-1024x691.png 1024w, /wp-content/uploads/2025/01/5-300x202.png 300w, /wp-content/uploads/2025/01/5-768x518.png 768w, /wp-content/uploads/2025/01/5-750x506.png 750w, /wp-content/uploads/2025/01/5-1140x769.png 1140w, /wp-content/uploads/2025/01/5.png 1460w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</figure>



<p id="bh-4J6dfkT-xnEYY5bEiDfgO"></p>



<h1 class="wp-block-heading alignwide" id="bh-EtJHIEr14et28irEF_JXr">This is where RAG comes in to save the day! <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f9b8-200d-2642-fe0f.png" alt="🦸‍♂️" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h1>



<h3 class="wp-block-heading" id="bh-1Le3h5dwOiYNfBAKwcrHU">(Retrieval-Augmented Generation)</h3>



<p id="bh-PmnCXKhotbpQNmwL3vfD7">Think of RAG as Gen AI with a Personal Library! </p>



<h3 class="wp-block-heading" id="bh-0lA8opU67UN3QBTudnFYZ">Simple Example:</h3>



<ul id="bh-Gt1hrlceysNuIlCecPJmi" class="wp-block-list">
<li>Regular Gen AI is like asking a friend who read lots of books</li>



<li>RAG is like asking a friend who can also check your personal notes</li>
</ul>



<h2 class="wp-block-heading">How Does RAG Work? <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f50d.png" alt="🔍" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<h3 class="wp-block-heading" id="bh-ZNptr88DhOW15hV4Wbw5o">Three Easy Steps:</h3>



<ol id="bh-lSEPIAsXOnYSYExBeYqti" class="wp-block-list">
<li>Retrieval <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f4c2.png" alt="📂" class="wp-smiley" style="height: 1em; max-height: 1em;" />
<ul class="wp-block-list">
<li>Searches through your specific documents</li>



<li>Finds relevant information</li>
</ul>
</li>



<li>Augmentation <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/2795.png" alt="➕" class="wp-smiley" style="height: 1em; max-height: 1em;" />
<ul class="wp-block-list">
<li>Adds this information to what it already knows</li>
</ul>
</li>



<li>Generation <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/270d.png" alt="✍" class="wp-smiley" style="height: 1em; max-height: 1em;" />
<ul class="wp-block-list">
<li>Creates responses using both sources</li>
</ul>
</li>
</ol>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="911" src="/wp-content/uploads/2025/01/6-1024x911.png" alt="" class="wp-image-2100" srcset="/wp-content/uploads/2025/01/6-1024x911.png 1024w, /wp-content/uploads/2025/01/6-300x267.png 300w, /wp-content/uploads/2025/01/6-768x683.png 768w, /wp-content/uploads/2025/01/6-1536x1366.png 1536w, /wp-content/uploads/2025/01/6-750x667.png 750w, /wp-content/uploads/2025/01/6-1140x1014.png 1140w, /wp-content/uploads/2025/01/6.png 1561w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">RAG in Real Life <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f31f.png" alt="🌟" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<h3 class="wp-block-heading" id="bh-mP82ngI1BAwA4nakox5yi">Example Scenarios:</h3>



<h4 class="wp-block-heading" id="bh-1ctLAr50BCtb5r6mRRyUQ">Customer Service Bot</h4>



<ul id="bh-9VGS921FwEFwHFs1dXQvr" class="wp-block-list">
<li>WITHOUT RAG: Gives general answers</li>



<li>WITH RAG: Knows your company&#8217;s specific policies</li>
</ul>



<h4 class="wp-block-heading" id="bh-7lLz_PXDWXY2Jn8k93gyx">Technical Support</h4>



<ul id="bh-4QdZ_Vj_OSLXMBLzlq-PD" class="wp-block-list">
<li>WITHOUT RAG: Provides generic solutions</li>



<li>WITH RAG: Uses your product&#8217;s actual documentation</li>
</ul>



<h2 class="wp-block-heading">Benefits of RAG <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f381.png" alt="🎁" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<ol id="bh-wWbgoeQcKB-92VquI5en5" class="wp-block-list">
<li>More Accurate <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" />
<ul class="wp-block-list">
<li>Uses your specific information</li>



<li>Reduces made-up answers<br></li>
</ul>
</li>



<li>Always Updated <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f4c5.png" alt="📅" class="wp-smiley" style="height: 1em; max-height: 1em;" />
<ul class="wp-block-list">
<li>Can access new information</li>



<li>Stays current with your needs<br></li>
</ul>
</li>



<li>Customized Help <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f3a8.png" alt="🎨" class="wp-smiley" style="height: 1em; max-height: 1em;" />
<ul class="wp-block-list">
<li>Knows your context</li>



<li>Gives relevant answers</li>
</ul>
</li>
</ol>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1011" height="1024" src="/wp-content/uploads/2025/01/7-1011x1024.png" alt="" class="wp-image-2103" srcset="/wp-content/uploads/2025/01/7-1011x1024.png 1011w, /wp-content/uploads/2025/01/7-296x300.png 296w, /wp-content/uploads/2025/01/7-768x778.png 768w, /wp-content/uploads/2025/01/7-75x75.png 75w, /wp-content/uploads/2025/01/7-750x759.png 750w, /wp-content/uploads/2025/01/7-1140x1154.png 1140w, /wp-content/uploads/2025/01/7.png 1431w" sizes="(max-width: 1011px) 100vw, 1011px" /></figure>



<h2 class="wp-block-heading">Real-World Applications <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f30d.png" alt="🌍" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<h3 class="wp-block-heading" id="bh-wm-B9q-Hxx5MfPjJU0UqP">Where RAG Shines:</h3>



<ol id="bh-oW_vB160UA-bFVSIe8qcO" class="wp-block-list">
<li>Business <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f4bc.png" alt="💼" class="wp-smiley" style="height: 1em; max-height: 1em;" />
<ul class="wp-block-list">
<li>Customer support</li>



<li>Internal documentation</li>



<li>Employee training<br></li>
</ul>
</li>



<li>Education <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f4da.png" alt="📚" class="wp-smiley" style="height: 1em; max-height: 1em;" />
<ul class="wp-block-list">
<li>Personalized tutoring</li>



<li>Course material assistance</li>



<li>Research help<br></li>
</ul>
</li>



<li>Healthcare <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f3e5.png" alt="🏥" class="wp-smiley" style="height: 1em; max-height: 1em;" />
<ul class="wp-block-list">
<li>Medical record assistance</li>



<li>Treatment information</li>



<li>Patient care guidelines</li>
</ul>
</li>
</ol>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="831" src="/wp-content/uploads/2025/01/8-1024x831.png" alt="" class="wp-image-2104" srcset="/wp-content/uploads/2025/01/8-1024x831.png 1024w, /wp-content/uploads/2025/01/8-300x244.png 300w, /wp-content/uploads/2025/01/8-768x624.png 768w, /wp-content/uploads/2025/01/8-750x609.png 750w, /wp-content/uploads/2025/01/8-1140x926.png 1140w, /wp-content/uploads/2025/01/8.png 1532w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Simple RAG Example in Action <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f3ac.png" alt="🎬" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<h3 class="wp-block-heading" id="bh-ui6ennct7lZh0qw5AcLKJ">Scenario: Company Help Desk</h3>



<h4 class="wp-block-heading" id="bh-9X4OGdRCsfdwGYxjAWQGS">Question: &#8220;What&#8217;s our vacation policy?&#8221;</h4>



<h4 class="wp-block-heading" id="bh-U_rngJI7EBtwNNEQQkywc">Regular Gen AI Response:</h4>



<p id="bh-EZ61JjUEC_x1tnWT9sKsB">&#8220;Generally, companies offer 2-3 weeks vacation&#8230;&#8221;</p>



<h4 class="wp-block-heading" id="bh-oAdxiWS2gKWWxwqxNjxrI">RAG-Enhanced Response:</h4>



<p id="bh-aeRWQpEx2nWkjjp4vg9ll">&#8220;According to our company handbook, full-time employees get 25 days plus 5 wellness days&#8230;&#8221;</p>



<h2 class="wp-block-heading">Tips for Using Gen AI with RAG <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<ol id="bh-q6w-R3Te2Z2djTAed-Kgr" class="wp-block-list">
<li>Be Specific
<ul class="wp-block-list">
<li>Clear questions get better answers<br></li>
</ul>
</li>



<li>Verify Important Info
<ul class="wp-block-list">
<li>Double-check critical details<br></li>
</ul>
</li>



<li>Start Simple
<ul class="wp-block-list">
<li>Begin with basic questions</li>



<li>Gradually ask more complex ones</li>
</ul>
</li>
</ol>



<h2 class="wp-block-heading" id="bh-Ko5VZWzJHMIbTE-1F-Re_">The Future is Bright! <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f305.png" alt="🌅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<p>With RAG combined with Gen AI today , the future is bright , we will have better ,faster and occurred answers .</p>



<h3 class="wp-block-heading" id="bh-TKCMTiusisWjibbcfeXko">What&#8217;s Coming Next:</h3>



<ul id="bh-mh9LYdm4iwPzPrAfIfPNq" class="wp-block-list">
<li>Better accuracy</li>



<li>Faster responses</li>



<li>More personalization</li>



<li>Easier integration</li>
</ul>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="722" height="374" src="/wp-content/uploads/2025/01/animation.gif" alt="" class="wp-image-2107"/></figure>



<p>Remember: Gen AI + RAG = Smarter Assistance! <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p><br></p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="710" height="446" src="/wp-content/uploads/2025/01/11.gif" alt="" class="wp-image-2108"/></figure>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2084</post-id>	</item>
	</channel>
</rss>
