Playbook: Build an Intake App for a System Only Engineers Can Use
Your company has an internal system that non-engineers need to use but cannot access directly. Maybe it is a deployment pipeline, a feature flag service, a data warehouse, or a configuration management tool. The interface is a CLI or an API. Every request goes through engineering: "can you turn on this feature flag?" "can you export this dataset?" "what's the status of the deploy?" This playbook walks you through building tools for the safe operations and a sandcastle app that lets non-engineering teams do these things themselves.
What you will build
By the end of this playbook, you will have:
- Custom tools that wrap the safe operations of your internal system (read operations and guarded write operations)
- A sandcastle app with forms, validation, and status tracking where non-engineers submit requests and see results
- Built-in guardrails so non-engineers can only perform approved actions with validated inputs
- An approval workflow for high-risk operations where an engineer reviews before execution
- Persistent state that tracks every request, who made it, and what happened
What you need before you start
- An Assist workspace with an MCP server set up. If you have not created one yet, follow Creating an MCP server.
- Your AI client connected to the MCP server. See Connect your client.
- Access credentials for the internal system's API or CLI. You will need to know which operations are safe for self-service and which require approval.
- A list of the most common requests your team gets from non-engineers. If you do not have a formal list, think about the last ten tickets you handled -- those are your starting tools.
This playbook uses a feature flag service as the example, but the pattern works for any internal system: deployment pipelines, data exports, DNS management, environment provisioning, or anything else that lives behind a CLI or API.
Step 1: Classify operations by risk
Before building anything, sort the operations into three categories with your AI client:
"I want to build self-service tools for our feature flag service at https://flags.internal.company.com/api. Here are the operations teams ask us about most:
- Check if a flag is enabled (read)
- List all flags for a project (read)
- Enable a flag for a specific user segment (write - low risk)
- Create a new flag (write - medium risk)
- Enable a flag globally for all users (write - high risk)
- Delete a flag (write - high risk)
- Change flag rollout percentage (write - medium risk)
Can you help me categorize these into: self-service (no approval needed), approval-required, and engineer-only?"
The AI will help you draw the lines. Typically:
- Self-service: All read operations, plus low-risk writes like enabling a flag for a test segment
- Approval-required: Medium-risk writes like creating flags or changing rollout percentages
- Engineer-only: Destructive operations like deleting flags or enabling globally. These stay out of the tool set entirely.
This classification is critical. You are not giving non-engineers full access to the system -- you are exposing a curated set of safe operations with guardrails.
Step 2: Build the read tools
Start with tools that let people look things up without changing anything:
"Create a tool called 'get_flag_status' that takes a flag key and returns whether it's enabled, what segments it's targeting, the rollout percentage, who last modified it, and when."
"Create a tool called 'list_project_flags' that takes a project name and returns all flags with their status, target segments, and rollout percentages."
"Create a tool called 'get_flag_history' that takes a flag key and returns the last 20 changes with timestamp, who made the change, what changed, and the before/after values."
Test each one. These are the tools that non-engineers will use most -- answering the question "what is the current state?" without filing a ticket.
Step 3: Build the guarded write tools
Now build the write operations with validation and safety checks:
"Create a tool called 'enable_flag_for_segment' that takes a flag key and a segment name. Before making the change, it should:
- Verify the flag exists
- Verify the segment exists
- Check that the flag is not already enabled for this segment
- Check that the segment is not 'all_users' (that requires engineer approval)
- Make the change
- Return a confirmation with what changed
If any check fails, return a clear error message explaining why and what the user should do instead."
"Create a tool called 'request_new_flag' that takes a flag key, description, project, and default state. It should:
- Validate the flag key format (lowercase, hyphens only, max 50 chars)
- Check the flag key does not already exist
- Do NOT create the flag yet -- instead, store a request in pending state
- Return a confirmation that the request was submitted for engineer review"
"Create a tool called 'request_rollout_change' that takes a flag key and a new rollout percentage. It should:
- Verify the flag exists
- Verify the percentage is between 0 and 100
- Check the current percentage -- if the change is more than 25 percentage points, require approval
- If the change is small (25 points or less), apply it directly and return confirmation
- If the change is large, store a request in pending state for review"
The pattern here is important: small, safe changes happen immediately. Large or risky changes go into a queue. The guardrails are in the tool logic itself, not in the UI -- so they are enforced whether someone uses the app or calls the tool from their AI client.
Step 4: Build the intake app
Now build the sandcastle app that non-engineers will use:
"Build me a sandcastle app for managing feature flags. It should have these views:
Flag browser: A searchable list of all flags across projects. Each row shows the flag key, project, status (enabled/disabled), rollout percentage, target segments, and last modified. Clicking a flag opens its detail view.
Flag detail: Full information about a flag including current state, all targeted segments, rollout percentage, and a history timeline showing every change. Include an 'Enable for segment' button that opens a form with segment selection and confirmation.
Request form: A multi-step form for submitting requests:
- Select request type: 'New flag', 'Change rollout', 'Enable globally', 'Other'
- Fill in details based on type
- Review and submit
- Confirmation with request ID and status
My requests: A list of the user's submitted requests with status (pending/approved/rejected/completed), submitted date, and reviewer notes. Clicking a request shows full details.
Review queue (for engineers): Pending requests with approve/reject buttons, a notes field, and the ability to execute the approved change directly from the review screen."
Iterate on the UI:
"Add form validation to the request form. Flag keys must be lowercase with hyphens only. Rollout percentages must be numbers between 0 and 100. Show inline validation errors."
"On the flag detail page, add a visual rollout indicator -- a progress bar showing current percentage with color coding: green for 0-25%, yellow for 25-75%, red for 75-100%."
"In the review queue, show the full context for each request: current flag state, the requested change, who requested it, and when. Engineers should be able to approve and execute without leaving the app."
Step 5: Wire up the approval workflow
Connect the app's request system to the tools:
"When someone submits a request through the app, store it in a 'requests' collection with: request_id, type, requester, flag_key, details, status (pending), submitted_at, reviewed_by, reviewed_at, reviewer_notes."
"When an engineer approves a request in the review queue, execute the corresponding tool (create the flag, change the rollout, etc.) and update the request status to 'completed'. If the tool returns an error, update the status to 'failed' with the error message."
"When an engineer rejects a request, update the status to 'rejected' with their notes. The requester sees the rejection and reason in their 'My requests' view."
Step 6: Add notifications
Keep people informed without them needing to check the app:
"Create a tool that posts to Slack when:
- A new request is submitted (post to #engineering-requests with request details)
- A request is approved and executed (reply in thread with confirmation)
- A request is rejected (reply in thread with reason)
Also send a notification to the requester when their request status changes."
"Create a subagent that runs every hour during business hours. It checks for pending requests older than 4 hours and posts a reminder to #engineering-requests: 'X requests have been waiting for review for more than 4 hours.'"
The reminder agent prevents requests from sitting unreviewed. It runs in Assist whether anyone is online or not.
Step 7: Add self-service for safe operations
For operations that do not need approval, let non-engineers act directly through the app:
"Add an 'Enable for segment' button on the flag detail page. When clicked, show a dropdown of available segments (excluding 'all_users'). When the user selects a segment and confirms, call the enable_flag_for_segment tool directly. Show a success or error message inline."
"Add a 'Quick check' section to the flag browser header where someone can paste a flag key and immediately see its status without scrolling through the list."
These self-service actions go through the same guarded tools. The guardrails are in the tool, not the UI, so even if someone calls the tool from Claude Desktop instead of the app, the safety checks still apply.
Step 8: Share and extend
Share the app URL with product managers, QA engineers, and anyone who regularly asks about feature flags. Share the MCP server with team members who prefer to work conversationally.
A product manager can now check a flag status from ChatGPT:
"Is the new-checkout-flow flag enabled for the beta segment?"
Or submit a request:
"I need a new feature flag called holiday-promo-banner for the web project. It should default to disabled."
Both flows go through the same tools with the same guardrails. The app and the conversational interface are two windows into the same system.
Extend over time:
"Add a tool that compares flag states between staging and production environments. Show the differences in the app so QA can verify flags are configured correctly before a release."
"Add a 'stale flags' report that the agent runs weekly: find flags that have been at 100% rollout for more than 30 days with no changes. These are candidates for cleanup -- the flag can be removed from code."
"Add an audit log view that shows every tool execution: who ran it, what parameters, what result, and when. This is separate from flag history -- it tracks who used the tool system, not just what changed in the flag service."
What you built
You now have a complete self-service system for an internal tool that used to require engineering involvement:
- Read tools that let anyone check flag states and history without filing a ticket
- Guarded write tools that enforce safety rules at the tool level, not just the UI level
- An intake app where non-engineers browse flags, submit requests, and track status
- An approval workflow where engineers review and execute risky changes from a single queue
- Notifications and reminders that keep the process moving without manual follow-up
- Persistent state that tracks every request, approval, and execution for audit purposes
Engineering handles fewer tickets. Non-engineering teams get answers faster. Risky operations still go through review. Every action is tracked. The system works whether people use the app, their AI client, or both.