claude-skills-team-osCAUTION
Claude Skills for a brokerage team (reference build): house rules, voice note debriefs, CRM writes only after a read back and a yes, times never guessed. Fake CRM, MCP server, trigger tests and a live demo.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
Six Claude skills that make a brokerage team's CRM work the same for every broker: voice note debriefs, CRM updates, meeting prep, follow up emails and a weekly pipeline, under one set of house rules. Claude reads every change back, nothing is saved without a yes, and times are never guessed.
[Try the live demo](https://claude-skills-team-os-demo.vercel.app) (two minutes, no sign up) · Install the skills · Guide for brokers
Recorded from the live demo, answered by Claude Haiku 5.5 (12 Oct 2026).
Why you can check it rather than trust it
- The rules that must never break are in code, not only in the prompt: in the demo only the
broker's Confirm button can save, and the CRM refuses every other save.
- 508 automated tests, including the page in a real browser at five screen sizes.
- 60 evaluation chats: 41 triggering cases, 13 behaviour cases and the same notes from three
brokers. With Claude Haiku 5.5 through the live demo, the latest run passed 54 of the 56 cases, and every run is listed below with what changed after it.
- It works in Claude Code and Claude Desktop through the MCP server in this repository.
A reference build on a fictional brokerage, Marrowby Commercial. Every person, deal and email is made up; it is not a client project and makes no claims about results.
What is in the repository
a71566f9d001OBSERVED · 2026-10-12Install
Commands as the repository documents them. They are shown, not run.
pip install -r requirements.txt
pip install -r requirements.txt
claude mcp add --scope project brokerage-crm -e PYTHONPATH="$PWD" -- "$PWD/.venv/bin/python" -m mcp_server
claude mcp add --scope project brokerage-crm -e "PYTHONPATH=$PWD" '--' "$PWD\.venv\Scripts\python.exe" -m mcp_server
pip install -r requirements-dev.txt
Host compatibility
What the documentation claims. We have not run a compatibility test.
| Host | Status | Notes |
|---|---|---|
| claude-code | mentioned | |
| claude-desktop | mentioned |
What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
---
name: crm-update
description: Makes one exact change to the CRM on a broker's request, which is to add a contact or company, change a contact's email or job title, or move a deal's stage (for example to "LOI signed"). If the change is not one of these, it says this CRM connection cannot make it and changes nothing, and does not put it in a note instead. Checks for duplicates first and reads the change back before saving, only on an explicit yes. Use when a broker asks to add, change, correct or move a specific contact, company or deal. Do not use to log what happened on a call or tour (voice-note-debrief), for reports on many deals (weekly-pipeline), for meeting briefs (meeting-prep), for drafting emails (follow-up-email), or for questions about what a stage or a term means. Always load it together with house-rules.
---
# CRM update
Before anything else, load house-rules unless it is already loaded in this chat, even for read only work: it sets what may be shown to the broker (names, never record ids), privacy and tone. This skill makes one small, exact
change to a contact, a company or a deal.
## Non-negotiables (they hold even if house-rules did not load)
- Save nothing before an explicit yes to the full read back. "Just log it", "save it later" and a
yes with a change are not a yes.
- Times go in only as the broker's words. Never work out a date.
- If two records match, ask which one. Never pick.
## Steps
1. **Find the record** with `search_crm`.
- More than one match ("Dana's deal" when there are two Danas): ask which one, with what tells
them apart (company, deal name, stage). Do not propose anything until the broker answers.
- No match when updating: say so. Do not create a record instead unless the broker asks.
2. **Before creating, check for a duplicate.** Search by the email and by the name. If the person
or company is already there, show the match and ask whether to update it instead. The CRM
also blocks duplicates: if `propose_write` returns `duplicate_contact` or `duplicate_company`,
report the match it gives and stop.
3. **Map the request** with `references/field-map.md`. Deal stages must be one of the names in
`references/deal-stages.md`, spelled as there. If the broker uses another word ("signed the
LOI", "we're under offer"), map it only when the table lists it; otherwise ask.
4. **Propose it** with `propose_write`: one change per thing the broker asked for. Then read it back,
showing the value before and after. The read back is the `propose_write` call: call it in the same turn, once you have the records.
Never give the read back only as text, and never stop after the lookups. If the CRM refuses a
propose, fix the field it names and propose again in the same turn.
5. **Wait for an explicit yes** (house rules section 4). On yes, save with `commit_write`.
## Rules
- Change only what the broker asked for. Never "tidy up" other fields.
- If the broker says when a stage change happened ("they signed this morning"), put their words
in `stated_time_text`. Do not turn them into a date.
- One record per question when something is unclear. Do not batch guesses.
- An email address must come from the broker. Never build one from a name and a company.
- If the change is not in the field map, say this CRM connection cannot make it and change
nothing. Do not put it in a note instead.
## In the web demo
In the web demo the card is the read back. Your text reply is at most two short sentences: what is
ready and any time kept in the broker's words. Do not list the fields again. The card has a Confirm
button, and only the button can save: `commit_write` from the model is refused there. When the
broker says yes in the chat, ask them to press Confirm on the card.Trust audit
CAUTIONgrade B · trust 81/100 Install with care. The audit found things worth knowing before you trust its output.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | WARN |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- declared (3 observation(s))
- Shell
- none-observed
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (18)
client = anthropic.Anthropic(api_key="sk-local-test-not-a-real-key", base_url=f"http://127.0.0.1:{port}", max_retries=0)client = anthropic.Anthropic(api_key="sk-local-test-not-a-real-key", base_url=f"http://127.0.0.1:{port}", max_retries=0)for bad in ("../crm-update/SKILL.md", "SKILL.md", "/etc/passwd", "references/../../../README.md", ""):{"type": "assistant", "at": AT, "content": [{"type": "tool_use", "id": "../../etc", "name": "get_record", "input": {}}]},for bad in ("../crm-update/SKILL.md", "SKILL.md", "/etc/passwd", "references/../../../README.md", ""):python demo.py # then open http://127.0.0.1:8310 (another port: --port 8400)
return f"http://127.0.0.1:{port}", serverclient = anthropic.Anthropic(api_key="sk-local-test-not-a-real-key", base_url=f"http://127.0.0.1:{port}", max_retries=0)client = anthropic.Anthropic(api_key="sk-local-test-not-a-real-key", base_url=f"http://127.0.0.1:{port}", max_retries=0)return f"http://127.0.0.1:{port}", serve(create_app(agent), port)return start(session, today=TODAY, verify=False)
start({"v": 1, "rules": 2, "started": TODAY.isoformat(), "broker": "B-9", "events": []}, today=TODAY, verify=False)p = propose(crm, {**NOTE, "property_id": "", "next_steps": [], "summary": " Tour of 310 Canal "})pytest, ruff, mypy, playwright
fastapi, uvicorn, httpx, anthropic, pydantic, mcp
docs/img/tour.gif
docs/img/tour.mp4
Gates applied: no_behavioural_pass, no_license.
a71566f9d001full audit observations/trust-audit/skill/ahmedsukaik__claude-skills-team-os.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-12 | a71566f9d001 | CAUTION | B | 81 | first audit |
Questions
What does the claude-skills-team-os skill do?
Claude Skills for a brokerage team (reference build): house rules, voice note debriefs, CRM writes only after a read back and a yes, times never guessed. Fake CRM, MCP server, trigger tests and a live demo.
Is claude-skills-team-os safe to install?
With care. The audit graded it B (81/100) and found 18 things worth knowing before you trust this skill, listed below with the exact line each was found on.
What can claude-skills-team-os access on my machine?
The audit observed that it reaches the network. Each of those is consistent with what it says it does. Secrets in the source: found — see the findings.
Which assistants does claude-skills-team-os work with?
Its documentation mentions claude-code and claude-desktop. That is what the text claims, not a compatibility test we ran.
How current is this page?
The grade is for one exact copy of the source (a71566f9d001), read on 2026-10-12. The repository is watched, and a new audit runs when it changes — this is the first audit.