diff --git a/app/actions.tsx b/app/actions.tsx
index bce44e40..f60d456c 100644
--- a/app/actions.tsx
+++ b/app/actions.tsx
@@ -6,13 +6,15 @@ import {
   getAIState,
   getMutableAIState
 } from 'ai/rsc'
-import { CoreMessage, ToolResultPart } from 'ai'
+import { CoreMessage, ToolResultPart, generateObject } from 'ai'
 import { nanoid } from 'nanoid'
+import { z } from 'zod'
 import type { FeatureCollection } from 'geojson'
 import { Spinner } from '@/components/ui/spinner'
 import { Section } from '@/components/section'
 import { FollowupPanel } from '@/components/followup-panel'
 import { inquire, researcher, taskManager, querySuggestor, resolutionSearch } from '@/lib/agents'
+import { getModel } from '@/lib/utils'
 // Removed import of useGeospatialToolMcp as it no longer exists and was incorrectly used here.
 // The geospatialTool (if used by agents like researcher) now manages its own MCP client.
 import { writer } from '@/lib/agents/writer'
@@ -26,13 +28,42 @@ import { GeoJsonLayer } from '@/components/map/geojson-layer'
 import { CopilotDisplay } from '@/components/copilot-display'
 import RetrieveSection from '@/components/retrieve-section'
 import { VideoSearchSection } from '@/components/video-search-section'
-import { MapQueryHandler } from '@/components/map/map-query-handler' // Add this import
+import { MapQueryHandler } from '@/components/map/map-query-handler'
+import { MapImageOverlay } from '@/components/map/map-image-overlay'
 
 // Define the type for related queries
 type RelatedQueries = {
   items: { query: string }[]
 }
 
+async function extractCoordinatesFromMapImage(imageDataUrl: string) {
+  'use server'
+  const result = await generateObject({
+    model: getModel(),
+    messages: [
+      {
+        role: 'user',
+        content: [
+          {
+            type: 'text',
+            text: 'Understand the image uploaded by the user, if its a map proceed to extract all the information that you can from the image. We have to place it in the system if it does not have coordinates place it at the center of mapbox if does, Extract the geographic coordinates from this map image. Look for latitude/longitude labels, coordinate grid lines, or scale information. Return the corner coordinates.'
+          },
+          { type: 'image', image: imageDataUrl }
+        ]
+      }
+    ],
+    schema: z.object({
+      topLeft: z.object({ lat: z.number(), lng: z.number() }),
+      topRight: z.object({ lat: z.number(), lng: z.number() }),
+      bottomRight: z.object({ lat: z.number(), lng: z.number() }),
+      bottomLeft: z.object({ lat: z.number(), lng: z.number() }),
+      confidence: z.number().describe('0-1 confidence score')
+    })
+  })
+
+  return result.object
+}
+
 // Removed mcp parameter from submit, as geospatialTool now handles its client.
 async function submit(formData?: FormData, skip?: boolean) {
   'use server'
@@ -238,6 +269,54 @@ async function submit(formData?: FormData, skip?: boolean) {
         image: dataUrl,
         mimeType: file.type
       })
+
+      try {
+        const coords = await extractCoordinatesFromMapImage(dataUrl)
+        if (coords.confidence > 0.7) {
+          const coordinates: [
+            [number, number],
+            [number, number],
+            [number, number],
+            [number, number]
+          ] = [
+            [coords.topLeft.lng, coords.topLeft.lat],
+            [coords.topRight.lng, coords.topRight.lat],
+            [coords.bottomRight.lng, coords.bottomRight.lat],
+            [coords.bottomLeft.lng, coords.bottomLeft.lat]
+          ]
+          aiState.update({
+            ...aiState.get(),
+            messages: [
+              ...aiState.get().messages,
+              {
+                id: nanoid(),
+                role: 'assistant',
+                content: JSON.stringify({ imageUrl: dataUrl, coordinates }),
+                type: 'image_overlay'
+              }
+            ]
+          })
+        } else {
+          console.warn('Low confidence in coordinate extraction')
+          throw new Error('Low confidence')
+        }
+      } catch (error) {
+        console.error('Failed to extract coordinates:', error)
+        const mapCenter = formData?.get('map_center') as string | undefined
+        const center = mapCenter ? JSON.parse(mapCenter) : [0, 0]
+        aiState.update({
+          ...aiState.get(),
+          messages: [
+            ...aiState.get().messages,
+            {
+              id: nanoid(),
+              role: 'assistant',
+              content: JSON.stringify({ imageUrl: dataUrl, center }),
+              type: 'image_overlay'
+            }
+          ]
+        })
+      }
     } else if (file.type === 'text/plain') {
       const textContent = Buffer.from(buffer).toString('utf-8')
       const existingTextPart = messageParts.find(p => p.type === 'text')
@@ -591,6 +670,41 @@ export const getUIStateFromAIState = (aiState: AIState): UIState => {
           const answer = createStreamableValue()
           answer.done(content)
           switch (type) {
+            case 'image_overlay': {
+              const data = JSON.parse(content as string)
+              let coordinates: [
+                [number, number],
+                [number, number],
+                [number, number],
+                [number, number]
+              ]
+
+              if (data.coordinates) {
+                // New format: direct coordinates
+                coordinates = data.coordinates
+              } else {
+                // Old format: fallback to center-based
+                const [lng, lat] = data.center
+                const halfSize = 0.5
+                coordinates = [
+                  [lng - halfSize, lat + halfSize],
+                  [lng + halfSize, lat + halfSize],
+                  [lng + halfSize, lat - halfSize],
+                  [lng - halfSize, lat - halfSize]
+                ]
+              }
+
+              return {
+                id,
+                component: (
+                  
+                )
+              }
+            }
             case 'response':
               return {
                 id,
diff --git a/components/chat-panel.tsx b/components/chat-panel.tsx
index b0bf2166..8531db15 100644
--- a/components/chat-panel.tsx
+++ b/components/chat-panel.tsx
@@ -3,7 +3,7 @@
 import { useEffect, useState, useRef, ChangeEvent, forwardRef, useImperativeHandle } from 'react'
 import type { AI, UIState } from '@/app/actions'
 import { useUIState, useActions } from 'ai/rsc'
-// Removed import of useGeospatialToolMcp as it's no longer used/available
+import { useMap } from './map/map-context'
 import { cn } from '@/lib/utils'
 import { UserMessage } from './user-message'
 import { Button } from './ui/button'
@@ -24,7 +24,7 @@ export interface ChatPanelRef {
 export const ChatPanel = forwardRef(({ messages, input, setInput }, ref) => {
   const [, setMessages] = useUIState()
   const { submit, clearChat } = useActions()
-  // Removed mcp instance as it's no longer passed to submit
+  const { map } = useMap()
   const [isMobile, setIsMobile] = useState(false)
   const [selectedFile, setSelectedFile] = useState(null)
   const inputRef = useRef(null)
@@ -99,6 +99,11 @@ export const ChatPanel = forwardRef(({ messages, i
       formData.append('file', selectedFile)
     }
 
+    if (map) {
+      const center = map.getCenter()
+      formData.append('map_center', JSON.stringify([center.lng, center.lat]))
+    }
+
     setInput('')
     clearAttachment()
 
diff --git a/components/map/map-image-overlay.tsx b/components/map/map-image-overlay.tsx
new file mode 100644
index 00000000..2b8c08e8
--- /dev/null
+++ b/components/map/map-image-overlay.tsx
@@ -0,0 +1,114 @@
+'use client'
+
+import { useMap } from '@/components/map/map-context'
+import { useEffect } from 'react'
+import { LngLatBounds } from 'mapbox-gl'
+
+interface MapImageOverlayProps {
+  id: string
+  imageUrl: string
+  coordinates: [
+    [number, number],
+    [number, number],
+    [number, number],
+    [number, number]
+  ]
+  beforeId?: string
+  opacity?: number
+}
+
+export function MapImageOverlay({
+  id,
+  imageUrl,
+  coordinates,
+  beforeId,
+  opacity = 0.85
+}: MapImageOverlayProps) {
+  const { map } = useMap()
+
+  useEffect(() => {
+    if (
+      !map ||
+      !imageUrl ||
+      !Array.isArray(coordinates) ||
+      coordinates.length < 4 ||
+      !coordinates.every(
+        c => Array.isArray(c) && c.length >= 2 && !isNaN(c[0]) && !isNaN(c[1])
+      )
+    ) {
+      return
+    }
+
+    const sourceId = `image-overlay-source-${id}`
+    const layerId = `image-overlay-layer-${id}`
+    let attached = false
+
+    const onMapLoad = () => {
+      if (!map.getSource(sourceId)) {
+        map.addSource(sourceId, {
+          type: 'image',
+          url: imageUrl,
+          coordinates: coordinates
+        })
+      }
+
+      if (!map.getLayer(layerId)) {
+        if (beforeId) {
+          map.addLayer(
+            {
+              id: layerId,
+              type: 'raster',
+              source: sourceId,
+              paint: {
+                'raster-opacity': opacity,
+                'raster-fade-duration': 0
+              }
+            },
+            beforeId
+          )
+        } else {
+          map.addLayer({
+            id: layerId,
+            type: 'raster',
+            source: sourceId,
+            paint: {
+              'raster-opacity': opacity,
+              'raster-fade-duration': 0
+            }
+          })
+        }
+      }
+
+      const bounds = coordinates.reduce(
+        (b, c) => b.extend(c),
+        new LngLatBounds(coordinates[0], coordinates[0])
+      )
+
+      map.fitBounds(bounds, {
+        padding: 20,
+        duration: 1000
+      })
+    }
+
+    if (map.isStyleLoaded()) {
+      onMapLoad()
+    } else {
+      attached = true
+      map.once('load', onMapLoad)
+    }
+
+    return () => {
+      if (attached) {
+        map.off('load', onMapLoad)
+      }
+      if (map.getLayer(layerId)) {
+        map.removeLayer(layerId)
+      }
+      if (map.getSource(sourceId)) {
+        map.removeSource(sourceId)
+      }
+    }
+  }, [map, id, imageUrl, coordinates, beforeId, opacity])
+
+  return null
+}
diff --git a/lib/agents/tools/index.tsx b/lib/agents/tools/index.tsx
index 4c08f373..f96afc8f 100644
--- a/lib/agents/tools/index.tsx
+++ b/lib/agents/tools/index.tsx
@@ -2,7 +2,7 @@ import { createStreamableUI } from 'ai/rsc'
 import { retrieveTool } from './retrieve'
 import { searchTool } from './search'
 import { videoSearchTool } from './video-search'
-import { geospatialTool } from './geospatial' // Removed useGeospatialToolMcp import
+import { geospatialTool } from './geospatial'
 
 export interface ToolProps {
   uiStream: ReturnType
@@ -21,10 +21,8 @@ export const getTools = ({ uiStream, fullResponse }: ToolProps) => {
       uiStream,
       fullResponse
     }),
-    // geospatialTool now only requires uiStream
     geospatialQueryTool: geospatialTool({
       uiStream
-      // mcp: mcp || null // Removed mcp argument
     })
   }
 
diff --git a/lib/types/index.ts b/lib/types/index.ts
index faf21d32..62a4552c 100644
--- a/lib/types/index.ts
+++ b/lib/types/index.ts
@@ -72,6 +72,7 @@ export type AIMessage = {
     | 'tool'
     | 'followup'
     | 'end'
-    | 'drawing_context' // Added custom type for drawing context messages
+    | 'drawing_context'
     | 'resolution_search_result'
+    | 'image_overlay'
 }
\ No newline at end of file
diff --git a/package.json b/package.json
index 88ab75c7..2e98b940 100644
--- a/package.json
+++ b/package.json
@@ -65,7 +65,6 @@
     "next-themes": "^0.3.0",
     "open-codex": "^0.1.30",
     "pg": "^8.16.2",
-    "QCX": ".",
     "radix-ui": "^1.3.4",
     "react": "^19.1.0",
     "react-dom": "^19.1.0",