Know when to borrow that ladder before you drive across town
# Tool Library Hours Tracker
## The Problem
You've loaded the kids in the car to borrow a pressure washer from the community tool library, only to find a handwritten "Closed for inventory" sign taped to the door. Tool lending libraries, makerspaces, and equipment co-ops are grassroots operations — their hours live on inconsistently-updated Facebook pages, Google listings that were accurate in 2019, and "call ahead" voicemails. Neighbors waste gas, time, and goodwill on wasted trips, while libraries struggle to communicate changes without a dedicated web presence.
## Who Uses It
**The Weekend Warrior**: Sarah needs a tile saw for Saturday's bathroom project. She wants to check if the tool library is open before driving 20 minutes across town, and know if there's a waitlist for popular power tools.
**The Tool Library Volunteer**: Marcus staffs the lending window twice a month. He needs to quickly post holiday closures, special Saturday hours during spring planting season, or "closed early — pipe burst" alerts without updating three different platforms.
**The Makerspace Member**: Devi belongs to a co-op with irregular evening hours. She wants push notifications when the laser cutter room reopens after maintenance, not another buried email thread.
**The Curious Neighbor**: James didn't know his city had a free tool library until he searched "where to borrow a ladder near me."
## Core Features
1. **Searchable Library Directory**: Users can browse tool libraries, makerspaces, and equipment co-ops by neighborhood or zip code, seeing each location's address, general description, and link to hours.
2. **Current Hours Display with Confidence Score**: Each library shows its reported hours with a "last verified" timestamp and verification count, so users know if they're looking at hours confirmed yesterday or posted 8 months ago.
3. **Community Hours Submissions**: Any user can submit updated hours for a library — regular weekly schedules, holiday exceptions, or temporary closures. Submissions include a source field ("I volunteer here" / "Called today" / "Saw on their Facebook").
4. **Verification Voting**: Neighbors can confirm or dispute submitted hours with a simple "Still accurate" or "This is wrong" button, building consensus without requiring moderators.
5. **Closure Alerts Feed**: A real-time feed shows recent changes — "Downtown Tool Library closed Dec 24-26" or "Eastside Makerspace adding Thursday evenings starting Jan 15" — so regulars can scan for updates affecting their go-to spots.
6. **Reopen Notifications**: Users can tap "Notify me when this opens" on a temporarily closed library and receive a browser notification or email when someone marks it as reopened.
7. **Quick Trip Check**: A prominent "Open right now?" display on each library page with clear YES/NO/MAYBE (unverified) status, including how many hours until closing.
## WellSpr.ing Integration Points
### MCP Tools (via POST to `https://wellspr.ing/mcp` using JSON-RPC 2.0)
**`get_businesses`**: Seed your directory by pulling community resources that may include tool libraries, makerspaces, and lending organizations already cataloged in WellSpr.ing. Filter for relevant categories and display as starting points for your local index.
```json
{
"jsonrpc": "2.0",
"method": "get_businesses",
"params": { "category": "community_resources" },
"id": 1
}
```
**`get_business_detail`**: When a user selects a library from search results, fetch complete details including any existing contact information, description, or hours data that may be on file.
**`submit_business`**: Allow users to add new tool libraries that aren't yet in the WellSpr.ing directory. When someone adds "Northside Tool Co-op" to your tracker, submit it upstream so the whole federation benefits.
```json
{
"jsonrpc": "2.0",
"method": "submit_business",
"params": {
"name": "Northside Tool Lending Library",
"category": "tool_library",
"address": "412 Oak Street",
"description": "Free tool lending for residents. Staffed by volunteers."
},
"id": 2
}
```
**`get_local_news`**: Surface relevant announcements that might mention tool library events, grand openings, or closures covered by local news sources.
**`ask_ody`**: Power a natural-language search feature: "Where can I borrow a chainsaw this weekend?" Let Ody interpret the query against your indexed libraries and hours.
**`get_adjacent_nodes`**: For users near city borders, show tool libraries in neighboring communities that might be closer than options in their own municipality.
**`reach_number`**: Display human contact paths for libraries — if someone needs to call ahead about a specialized tool, show them how to reach staff.
### REST Endpoints
**`GET https://wellspr.ing/api/geo/portals?area_code=NNN`**: Use geographic portals to scope your directory to specific regions and enable neighborhood-level filtering.
### Future Capabilities (Roadmap — Not Yet Live)
- **Equipment inventory integration**: A future covenant commerce layer could enable real-time "is the pressure washer checked out?" status, but this requires tooling not yet available. For now, link to each library's own inventory system if they have one.
- **Reservation coordination**: Cross-library hold requests would benefit from a federated identity layer currently in development.
## Data Model
### `libraries`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid | Primary key |
| wellspring_id | string | If synced from WellSpr.ing |
| name | string | "Downtown Tool Library" |
| address | string | Full street address |
| lat/lng | float | For proximity search |
| description | text | What they lend, membership requirements |
| contact_url | string | Website or Facebook page |
| created_at | timestamp | |
### `hours_submissions`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid | Primary key |
| library_id | uuid | FK to libraries |
| schedule_type | enum | 'regular', 'holiday', 'temporary_closure', 'special_event' |
| day_of_week | int | 0-6 for regular hours, null for exceptions |
| open_time | time | |
| close_time | time | |
| effective_date | date | For exceptions |
| end_date | date | Null if ongoing |
| source | string | "volunteer", "phone_call", "website", "facebook" |
| submitter_note | text | "Holiday hours per their Dec 10 FB post" |
| submitted_at | timestamp | |
### `verifications`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid | Primary key |
| hours_submission_id | uuid | FK to hours_submissions |
| is_accurate | boolean | true = confirmed, false = disputed |
| verified_at | timestamp | |
| verifier_note | text | Optional: "Called to confirm" |
### `reopen_watchers`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid | Primary key |
| library_id | uuid | FK to libraries |
| email | string | Or push subscription endpoint |
| created_at | timestamp | |
| notified_at | timestamp | Null until triggered |
### `alerts` (view/materialized)
| Field | Type | Notes |
|-------|------|-------|
| library_id | uuid | |
| alert_
◎
This is your project thread with Ody. Ask questions, share screenshots, talk through the build. Anyone with this link can join the conversation.
Paste screenshots or upload images/PDFs · Shift+Enter for new line