Client Intake.
Start with a complete brief.
Create a versioned intake template, save supplied answers, identify missing information and prepare a Markdown project handoff. All seven tools operate on records inside the authenticated Doozle workspace.
Completeness checks are deterministic. The service does not invent answers, email clients, crawl websites, connect a CRM or submit work to an external provider. A clarification request is a draft; a project brief is a saved handoff record.
Machine-readable product schemas include the HTTP input contracts for product 11. The authenticated MCP tools/list response is authoritative for the tools and argument wrappers available to your credential.
Connect to your workspace
Request an invitation from support@doozle.io. An operator provisions an expiring, revocable key for your named workspace account. Do not place a key in a URL, public document, prompt transcript or frontend source.
- MCP endpoint
https://doozle-connectors-preview.matheus-mello-developer.workers.dev/mcp/11
- Authorization on every request
Authorization: Bearer <INVITATION_KEY>
- Requested access
product:11:readandproduct:11:writefor an owner or member account. Read-only credentials discover only read tools. Updating an existing intake also requires read access.
The server derives the tenant, account and scopes from verified credentials. Request input cannot select a different tenant or grant access to another product. An optional X-Workspace-ID header can only select an existing authorized membership; it cannot create one. Recipient-only reviewer accounts cannot create or edit intakes.
Use a server-side MCP client capable of sending a Bearer header. This is an invitation-key integration, not an OAuth authorization flow. Send no Origin header from a server client; if present, it must match this deployment's origin. Cross-origin browser access is not enabled.
Transport
- Streamable HTTP over
POST, with stateless JSON responses. - Tested protocol target:
2025-11-25, using the pinned TypeScript MCP SDK1.30.1. The newer2026-07-28protocol is not implemented by this adapter. - Use the client's normal initialize, tools/list and tools/call lifecycle. After negotiation, send the selected
MCP-Protocol-Versionheader. - Send
Content-Type: application/jsonandAccept: application/json, text/event-stream. Responses use JSON; no standalone server-event stream is offered. - No durable MCP session, session-resume feature or session ID is issued.
GETandDELETEon this MCP endpoint return405.
Seven tool contracts
The inputs below are the product arguments. For an MCP write, put those arguments inside input and add a sibling idempotencyKey. MCP reads receive the product arguments directly. For the HTTP API, always send the product arguments as the JSON body; writes additionally require an Idempotency-Key header.
1. Create an intake
create_client_intake · write
project_name: required text, 1–180 characters after trimming.fields: 1–30 objects. Each has a uniquekey, alabel(1–180 trimmed characters), and a required booleanrequired.- Field keys match
^[a-z][a-z0-9_]{0,40}$. The namesconstructor,prototypeand__proto__are unavailable. - An optional
requiredWhenobject containsfieldandequals, each 1–180 trimmed characters. It must refer to an existing key in this template. The named response must exactly matchequalsfor the condition to apply.
Returns a record with id, version: 1, timestamps and data. Its data contains the frozen fields, an empty responses object, state: "draft" and templateVersion: 1. Use the saved-intake list and full-record tool below to reopen work after reconnecting. A permitted owner can also retrieve version history through the separate export endpoint.
2. Save supplied answers
save_intake_responses · write
intake_id: the ID returned when the intake was created.expected_version: the current positive integer record version.responses: an object mapping template keys to strings of at most 4,000 characters each. Unknown keys are rejected.submit: optional boolean, defaultfalse.
responses object. Omitted answers are removed. submit: true changes the state to submitted; it does not certify completeness. Run the completeness tool before describing a brief as complete.Returns the updated record with its incremented version. The template stays unchanged.
3. Check completeness
get_intake_completeness · read
Input: { "intake_id": "<SAVED_INTAKE_ID>" }
Returns intake_id, current version, boolean complete, state and a missing array. Each missing item contains field, label and rule. A field is required when its required flag is true or its conditional rule matches. Blank answers and the phrase I don't know yet (ignoring surrounding whitespace and letter case) remain unresolved.
4. Draft clarification questions
draft_clarification_request · read
Input: { "intake_id": "<SAVED_INTAKE_ID>" }
Returns a draft string with one question per missing answer and sent: false. If nothing is missing, the draft is empty. This tool has no email-sending capability.
5. Save a project handoff
export_project_brief · write
Input: {
"intake_id": "<SAVED_INTAKE_ID>",
"expected_version": 2
}
Creates a separate handoff record containing sourceId, sourceVersion, an unresolved array and markdown. It snapshots the selected intake version. Missing answers remain visible as [Not supplied]; unresolved fields do not prevent the draft handoff from being saved. The intake itself is not changed.
6. List saved intakes
list_client_intakes · read
Input: { "limit": 10 }
Optional limit is an integer from 1 to 25 (default 10). Pass the returned nextCursor as cursor for the next page. Returns records containing IDs, versions, timestamps, project names, states, completeness flags and missing-answer counts. Answer values and template fields are excluded. Results belong only to the authenticated workspace; deleted intakes and handoff records are excluded.
7. Reopen a saved intake
get_client_intake · read
Input: { "intake_id": "<SAVED_INTAKE_ID>" }
Returns the full current record, frozen template and supplied answers, plus completeness: { complete, missing } calculated from that same version. Use this record's version for a later save; retain all answers you intend to keep. A concurrent save can still produce a version conflict.
30 September update: these two read tools extend the original five-tool application submitted on 26 September. The original tool inputs and MCP endpoint are unchanged. The extension is deployed-preview functionality, not a Meta approval or a new submission.
All top-level tool inputs and field objects are strict: do not add tenant IDs, role overrides or undeclared fields.
Continue work in the browser
Connect your invited workspace and open Client Intake. The Saved client intakes panel lists your work and opens the complete saved answer set in labeled fields. Save answers before refreshing or disconnecting: unsaved drafts remain only in the current tab.
Saving includes the whole displayed answer set. If someone saves a newer version first, your draft stays visible. Select Review latest saved answers, resolve any overlapping edits, then apply the choices to your draft. Review the result and save separately; preparing a merged draft does not write it to the server.
Wire examples
Every value below is illustrative. Replace the invitation-key placeholder and save the actual record IDs and versions returned by your own workspace.
MCP: create a brief
After initializing your authenticated MCP client, call this write tool. The retry key belongs inside the arguments wrapper; an HTTP idempotency header alone does not satisfy the MCP tool schema.
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "create_client_intake",
"arguments": {
"input": {
"project_name": "Client website",
"fields": [
{
"key": "audience",
"label": "Who is the website for?",
"required": true
},
{
"key": "launch_date",
"label": "Preferred launch date",
"required": false
}
]
},
"idempotencyKey": "client-intake-create-example-0001"
}
}
}
MCP: read, then save answers
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_intake_completeness",
"arguments": { "intake_id": "<SAVED_INTAKE_ID>" }
}
}
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "save_intake_responses",
"arguments": {
"input": {
"intake_id": "<SAVED_INTAKE_ID>",
"expected_version": 1,
"responses": {
"audience": "Local businesses in Porto",
"launch_date": "To be agreed"
},
"submit": true
},
"idempotencyKey": "client-intake-answers-example-0001"
}
}
}
HTTP API: the same create operation
The custom HTTP API is separate from the MCP transport. Use the tool name in the URL, the plain product payload in the body and the retry key in a header.
POST /api/tools/11/create_client_intake
Authorization: Bearer <INVITATION_KEY>
Content-Type: application/json
Idempotency-Key: client-intake-create-example-0001
{
"project_name": "Client website",
"fields": [
{
"key": "audience",
"label": "Who is the website for?",
"required": true
},
{
"key": "launch_date",
"label": "Preferred launch date",
"required": false
}
]
}
HTTP read tools also use POST with a JSON body, for example:
POST /api/tools/11/get_intake_completeness
Authorization: Bearer <INVITATION_KEY>
Content-Type: application/json
{ "intake_id": "<SAVED_INTAKE_ID>" }
Result envelope
A successful HTTP tool call returns the envelope below. MCP returns the same envelope in structuredContent and as JSON text in its content array. This example omits no top-level envelope fields; the tool-specific result varies by operation.
{
"result": {
"intake_id": "<SAVED_INTAKE_ID>",
"version": 1,
"complete": false,
"missing": [
{
"field": "audience",
"label": "Who is the website for?",
"rule": "required"
}
],
"state": "draft"
},
"requestId": "<REQUEST_ID>",
"observedAt": "2026-09-26T12:00:00.000Z",
"source": "workspace_records"
}
Retries, limits and errors
Persist one retry key before attempting each write. Keys contain 8–160 printable ASCII characters with no spaces. If delivery times out or the outcome is uncertain, retry with the same authenticated account, tool, key and identical input. A completed operation returns its original receipt; the same key with different input is rejected. Generate a new key for a genuinely new operation.
Both transports share the same durable receipt boundary. Repeating the same example through both transports with the same account, tool, key and input returns the same completed operation. Do not replace the key just to get past an uncertain result.
AUTH_REQUIRED/AUTH_INVALID: missing, expired or revoked credentials. Obtain a valid invitation.SCOPE_REQUIRED: the credential does not grant the required product operation.INVALID_INPUT,DUPLICATE_FIELD,INVALID_CONDITION,UNKNOWN_FIELD: correct the supplied template or responses.NOT_FOUND: the record does not exist in the authenticated workspace and product.VERSION_CONFLICT: the intake changed. Read its current version with the completeness tool, reconcile the full answer map and submit an intentional new operation. Do not blindly overwrite newer work.IDEMPOTENCY_REQUIRED/IDEMPOTENCY_CONFLICT: supply the original write key and matching input, or use a distinct key for a distinct operation.QUOTA_EXHAUSTED: the provisioned entitlement, record allowance or write limit prevents a new write. It does not mean a charge was taken.RATE_LIMITED: pause before retrying. The shared account/workspace request allowance is 120 requests per minute.
HTTP errors return an error object and request ID with an appropriate status; for example, conflicts return 409, missing authorization returns 401, and scope failures return 403. MCP business failures return isError: true with an error object in the tool result. An HTTP 200 carrying an MCP tool error is not a successful operation.
Request bodies are limited to 100,000 bytes, stored record content to 64 KiB and tool results to 256 KiB. Monthly write and stored-record allowances are workspace-specific; inspect the authenticated GET /api/entitlements response or the limits supplied with your invitation. This preview does not offer unlimited storage or request volume.
Data ownership and export
Supply only project information you are authorized to store. Records and their immutable historical versions are isolated by tenant and product. Do not put passwords, payment details or health records into intake answers. This connector does not need them.
An owner with the separate workspace:export scope and product:11:read can request a paginated JSON export over HTTP:
GET /api/workspace/export?products=11&limit=25
Authorization: Bearer <OWNER_EXPORT_KEY>
Collect the items from every page. While nextCursor is non-null, URL-encode it as the cursor parameter and repeat the request with the same product selection and owner identity. Stop when complete is true. Cursors are opaque, authenticated and expire after 24 hours. An ordinary product invitation does not automatically grant export permission.
The export covers immutable record versions present at its start; it includes version numbers and content hashes. Record deletion metadata is observed on each page. Credentials, payment sessions and internal receipts are excluded. Recognized embedded secret patterns are redacted with explicit paths; arbitrary pasted secrets cannot be identified reliably. A redacted version carries an exported-content hash separately from its source hash.
This is a business-record export, not a full infrastructure backup. Permanent erasure is not automated in this preview, and workspace deactivation retains history. Contact support@doozle.io for access, export or removal requests.