material-tracker
Track material orders, deliveries, and inventory on construction sites. Monitor lead times, delivery status, and stock levels.
Install / Use
npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill material-trackerInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
OperationsSupported Platforms
Our assessment of material-tracker
material-tracker scores 91/100 on our quality scale, 309th of 762 Operations skills we index (top 41%).
Its SKILL.md is 13 KB long, well organised into 15 sections with 5 code examples: a thorough specification that gives an agent plenty to work with.
It has 333 GitHub stars, a meaningful sign that others use it.
Maintenance, license and trust
- The repository was last updated about 2 months ago, so material-tracker is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
material-tracker compared with similar skills
All 4 of these similar skills score higher than material-tracker; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| material-tracker (this skill)by datadrivenconstruction | 91 | 333 | 56d ago | SKILL.md |
| Agent-Reachby Panniantong | 100 | 98.3k | 2d ago | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 75.5k | today | CLAUDE.md |
| Scraplingby D4Vinci | 100 | 88.2k | today | MCP Server |
| crawl4aiby unclecode | 100 | 85.7k | 2d ago | MCP Server |
Frequently asked questions
- How do I install material-tracker?
- Run
npx skills add datadrivenconstruction/DDC_Skills_for_AI_Agents_in_Construction --skill material-tracker. The install tabs above show the steps for each supported agent. - Which AI agents does material-tracker work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is material-tracker safe to use?
- It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is material-tracker still maintained?
- The repository was last updated about 2 months ago, so material-tracker is actively maintained.
Skill content
View source on GitHubname: "material-tracker" description: "Track material orders, deliveries, and inventory on construction sites. Monitor lead times, delivery status, and stock levels." homepage: "https://datadrivenconstruction.io" metadata: {"openclaw": {"emoji": "🛒", "os": ["darwin", "linux", "win32"], "homepage": "https://datadrivenconstruction.io", "requires": {"bins": ["python3"]}}}
Material Tracker
Business Case
Problem Statement
Material management challenges:
- Tracking multiple orders
- Coordinating deliveries
- Avoiding stockouts
- Managing lead times
Solution
Comprehensive material tracking system to monitor orders, deliveries, inventory, and alert on potential issues.
Technical Implementation
import pandas as pd
from typing import Dict, Any, List, Optional
from dataclasses import dataclass, field
from datetime import date, timedelta
from enum import Enum
class OrderStatus(Enum):
DRAFT = "draft"
SUBMITTED = "submitted"
CONFIRMED = "confirmed"
IN_PRODUCTION = "in_production"
SHIPPED = "shipped"
DELIVERED = "delivered"
PARTIAL = "partial"
CANCELLED = "cancelled"
class PriorityLevel(Enum):
CRITICAL = "critical"
HIGH = "high"
NORMAL = "normal"
LOW = "low"
@dataclass
class MaterialOrder:
order_id: str
material_code: str
material_name: str
supplier: str
quantity: float
unit: str
unit_cost: float
total_cost: float
order_date: date
required_date: date
expected_delivery: date
actual_delivery: Optional[date]
status: OrderStatus
priority: PriorityLevel
delivered_qty: float = 0
notes: str = ""
@dataclass
class InventoryItem:
material_code: str
material_name: str
current_stock: float
unit: str
min_stock: float
max_stock: float
reorder_point: float
location: str
last_updated: date
@dataclass
class Delivery:
delivery_id: str
order_id: str
delivery_date: date
quantity: float
received_by: str
condition: str # good, damaged, partial
notes: str = ""
class MaterialTracker:
"""Track construction materials."""
def __init__(self, project_name: str):
self.project_name = project_name
self.orders: Dict[str, MaterialOrder] = {}
self.inventory: Dict[str, InventoryItem] = {}
self.deliveries: List[Delivery] = []
def create_order(self,
order_id: str,
material_code: str,
material_name: str,
supplier: str,
quantity: float,
unit: str,
unit_cost: float,
required_date: date,
lead_time_days: int = 14,
priority: PriorityLevel = PriorityLevel.NORMAL) -> MaterialOrder:
"""Create new material order."""
order = MaterialOrder(
order_id=order_id,
material_code=material_code,
material_name=material_name,
supplier=supplier,
quantity=quantity,
unit=unit,
unit_cost=unit_cost,
total_cost=round(quantity * unit_cost, 2),
order_date=date.today(),
required_date=required_date,
expected_delivery=date.today() + timedelta(days=lead_time_days),
actual_delivery=None,
status=OrderStatus.DRAFT,
priority=priority
)
self.orders[order_id] = order
return order
def update_order_status(self, order_id: str, status: OrderStatus):
"""Update order status."""
if order_id in self.orders:
self.orders[order_id].status = status
def record_delivery(self,
order_id: str,
quantity: float,
received_by: str,
condition: str = "good",
notes: str = "") -> Optional[Delivery]:
"""Record material delivery."""
if order_id not in self.orders:
return None
order = self.orders[order_id]
delivery = Delivery(
delivery_id=f"DEL-{len(self.deliveries)+1:04d}",
order_id=order_id,
delivery_date=date.today(),
quantity=quantity,
received_by=received_by,
condition=condition,
notes=notes
)
self.deliveries.append(delivery)
# Update order
order.delivered_qty += quantity
order.actual_delivery = date.today()
if order.delivered_qty >= order.quantity:
order.status = OrderStatus.DELIVERED
else:
order.status = OrderStatus.PARTIAL
# Update inventory
if order.material_code in self.inventory:
self.inventory[order.material_code].current_stock += quantity
self.inventory[order.material_code].last_updated = date.today()
return delivery
def add_inventory_item(self,
material_code: str,
material_name: str,
current_stock: float,
unit: str,
min_stock: float,
max_stock: float,
location: str):
"""Add item to inventory tracking."""
reorder_point = min_stock + (max_stock - min_stock) * 0.3
self.inventory[material_code] = InventoryItem(
material_code=material_code,
material_name=material_name,
current_stock=current_stock,
unit=unit,
min_stock=min_stock,
max_stock=max_stock,
reorder_point=reorder_point,
location=location,
last_updated=date.today()
)
def consume_material(self,
material_code: str,
quantity: float,
activity: str = "") -> bool:
"""Record material consumption."""
if material_code not in self.inventory:
return False
item = self.inventory[material_code]
if item.current_stock < quantity:
return False
item.current_stock -= quantity
item.last_updated = date.today()
return True
def get_pending_orders(self) -> List[MaterialOrder]:
"""Get all pending orders."""
return [
o for o in self.orders.values()
if o.status not in [OrderStatus.DELIVERED, OrderStatus.CANCELLED]
]
def get_late_orders(self) -> List[Dict[str, Any]]:
"""Get orders that are late or at risk."""
late = []
today = date.today()
for order in self.orders.values():
if order.status in [OrderStatus.DELIVERED, OrderStatus.CANCELLED]:
continue
days_late = (today - order.expected_delivery).days
if days_late > 0 or (order.required_date - today).days < 3:
late.append({
'order_id': order.order_id,
'material': order.material_name,
'supplier': order.supplier,
'required_date': order.required_date,
'expected_delivery': order.expected_delivery,
'days_late': max(0, days_late),
'days_until_required': (order.required_date - today).days,
'status': order.status.value,
'priority': order.priority.value
})
return sorted(late, key=lambda x: x['days_until_required'])
def get_low_stock_items(self) -> List[Dict[str, Any]]:
"""Get items at or below reorder point."""
low_stock = []
for item in self.inventory.values():
if item.current_stock <= item.reorder_point:
low_stock.append({
'material_code': item.material_code,
'material_name': item.material_name,
'current_stock': item.current_stock,
'reorder_point': item.reorder_point,
'min_stock': item.min_stock,
'unit': item.unit,
'location': item.location,
'urgency': 'CRITICAL' if item.current_stock <= item.min_stock else 'REORDER'
})
return sorted(low_stock, key=lambda x: x['current_stock'])
def get_delivery_schedule(self, days_ahead: int = 14) -> pd.DataFrame:
"""Get expected deliveries for coming days."""
today = date.today()
end_date = today + timedelta(days=days_ahead)
scheduled = []
for order in self.orders.values():
if order.status in [OrderStatus.DELIVERED, OrderStatus.CANCELLED]:
continue
if today <= order.expected_delivery <= end_date:
scheduled.append({
'Date': order.expected_delivery,
'Order ID': order.order_id,
'Material': order.material_name,
'Quantity': order.quantity,
'Unit': order.unit,
'Supplier': order.supplier,
'Priority': order.priority.value
})
return pd.DataFrame(scheduled).sort_values('Date') if scheduled else pd.DataFrame()
def calculate_material_cost_summary(self) -> Dict[str, Any]:
"""Calculate material cost summary."""
total_ordered = sum(o.total_cost for o in self.orders.values())
total_delivered = sum(
o.delivered_qty * o.unit_cost
for o in self.orders.values()
)
total_pending = total_ordered - total_delivered
by_supplier = {}
for order in self.orders.values():
if order.supplier not in by_supplier:
by_supplier[order.supplier] = 0
by_supplier[order.supplier] += order.total_cost
return {
'total_ordered': round(total_ordered, 2),
'total_delivered': round(total_delivered, 2),
'total_pending': round(total_pending, 2),
'order_count': len(self.orders),
'by_supplier': by_supplier
}
def export_to_excel(self, output_path: str) -> str:
"""Export material tracking to Excel."""
with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
# Orders
orders_df = pd.DataFrame([
{
'Order ID': o.order_id,
'Material': o.material_name,
'Supplier': o.supplier,
'Quantity': o.quantity,
'Unit': o.unit,
'Unit Cost': o.unit_cost,
'Total Cost': o.total_cost,
'Order Date': o.order_date,
'Required': o.required_date,
'Expected': o.expected_delivery,
'Status': o.status.value,
'Delivered': o.delivered_qty
}
for o in self.orders.values()
])
orders_df.to_excel(writer, sheet_name='Orders', index=False)
# Inventory
if self.inventory:
inv_df = pd.DataFrame([
{
'Code': i.material_code,
'Name': i.material_name,
'Stock': i.current_stock,
'Unit': i.unit,
'Min': i.min_stock,
'Max': i.max_stock,
'Reorder Point': i.reorder_point,
'Location': i.location
}
for i in self.inventory.values()
])
inv_df.to_excel(writer, sheet_name='Inventory', index=False)
# Late orders
late = self.get_late_orders()
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
98.3kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
headroom
75.5kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
Scrapling
88.2k🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
crawl4ai
85.7kOpen-source web crawler and scraper for LLMs and AI agents: any website into clean, LLM-ready Markdown. Run it yourself, or use Crawl4AI Cloud with one key.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
