# Production guide — Give an assistant real business tools

Companion to [the full course](../appengine-build-an-ai-business-assistant.md). This package contains actual screenshots and verification records; it does not contain a finished video.

## Open with the result

Show the actual [Studio Test result](../../application-fixes/assets/ai-local/test-exact-email-live.png): one requested email, one matching customer, and **Tool result: search_customers · Completed**. Narration: “Give your assistant one useful job, then verify the record it found.” Explain that the result card comes from the executed tool. The model returned no additional prose in this run; do not voice an invented assistant answer.

## Record the current editor

The current interface is a single-page editor. Historical wizard captures in `assets/appengine-assistant` are research evidence, not the current sequence.

| Chapter | Screen and action | Explain while showing it |
| --- | --- | --- |
| Find the module | AI Assistant → Assistants → New Assistant | Orient viewers to Dashboard, Templates, Assistants, Available Tools, Phone & Voice and Activity Logs. |
| Define the job | Who it is: Name, Handle, Status, Who can see it, What it is for | Title is human-readable; handle identifies the assistant. Keep the training assistant inactive during setup. |
| Set behavior | How it behaves: personality and individual rules | Add the course's factual-lookup, no-messaging and no-booking-change rules. Rules do not replace tool restrictions. |
| Limit tools | What it can do → Only the ones I pick → customer search | Show exactly one enabled tool. Leave unrelated playbooks and mutating tools off. |
| Check automation | When it works; What starts it | Empty channel selection means every channel, not off. Keep automatic triggers empty. Inactive is the demonstrated off state. |
| Save and reopen | Save → Assistants → View | Show the saved inactive state, one tool and persisted instructions. View opens the editor. |
| Run a controlled test | Temporarily active → Save → Test it → task → Send | Use the viewer's own fictional customer email. Wait for the response without repeated sends. |
| Verify the match | Tool result card | Read the exact name and email. Distinguish a completed tool from model prose and from “No tools ran.” |
| Restore | Close drawer → Inactive → Save → reopen | Prove the saved state; closing the drawer is not deactivation. |
| Verify history | Activity Logs → Refresh | Show the separate ai_tool_call success entry. Execution success alone does not prove a tool ran. |

Use [the current editor captures](../../application-fixes/assets/ai-local/02-configured.png), [inactive reload](../../application-fixes/assets/ai-local/03-inactive-reloaded.png), [inactive guard](../../application-fixes/assets/ai-local/06-inactive-fixed.png), [successful exact-email result](../../application-fixes/assets/ai-local/test-exact-email-live.png) and [real activity feed](../../application-fixes/assets/ai-local/activities-exact-email-live.png). Zoom into the relevant control while retaining enough surrounding interface for orientation. All customer details in these examples are fictional.

## Explain the troubleshooting lesson

Three defects surfaced through actual usage: the provider request omitted tool definitions, exact-email text search returned unrelated same-domain customers, and the Test drawer hid successful tool-only results. These were fixed locally. Use the successful result for the main lesson; if explaining the repair, clearly label the [earlier no-tool activity capture](../../application-fixes/assets/ai-local/activities-model-no-tool-live.png) as a failed attempt. Never present its execution-success label as successful customer lookup.

The current non-streaming test returns the executed tool outcome without a second model completion. The result card accurately shows that distinction. The editor behind the captured drawer was opened while inactive; activation and restoration were checked through saved-record readback. For new footage, save the active state in the UI before opening the drawer, then film the final inactive readback separately.

## MCP is a separate chapter

Show initialize, tools/list, list_services and describe_service in order, then the authenticated booking read and refusal cases from the course. Use the actual registered service and its parameter signature. Omit the initial organization argument for either `orgId` or `orgid`; the repaired registry injects authenticated context. Both spellings were verified with live reads of the same booking. The CRM tool checkbox does not limit all MCP methods. Read HTTP status and the JSON-RPC tool error separately; HTTP200 alone is not success.

Label the older September18 booking reference as historical if using its capture. Prefer the current [MCP proof](../../application-fixes/assets/ai-local/09-mcp-proof.json) and controlled training booking for new filming. Do not expose tokens, passwords or provider keys.

## Remaining acceptance before claiming the complete story

The current customer-search run is verified. The separate model refusal/unchanged-booking exercise and authenticated ticket-tool acceptance are still open. Do not splice an invented refusal or support-ticket result into this sequence. Voice calls, message delivery, booking mutation, knowledge retrieval, Claude Desktop and automatic approval wiring are outside the demonstrated result.

Use a simple two-lane graphic for stored CRM assistant tools versus an external MCP client, joining only at the business records. Any diagram is explanatory; all application screens must be real captures. Keep narration and on-screen labels tied to the actions actually filmed.
