Workflow tutorial for the DevSpeak MCP server showing the full three-stage pipeline inside an AI IDE: optimize_text for Stage 1 lexical cleanup of a raw stakeholder message, translate_text for Stage 2 generation of an API Design with audience, context, format, and tone parameters, and refine_translation for Stage 3 iterative revision using previousOutput and feedback. Explains why Stage 1 targets raw input while Stage 3 targets generated output, when to skip Stage 1, and how summarize_input handles text above the 10,000-character limit.
Translate Requirements Into an API Design Without Leaving Your Editor
A product manager drops a message in Slack. It is clear enough to a human and useless to an implementer. This tutorial walks that message through all three DevSpeak stages using MCP tools, ending with an API design you would actually put in a pull request.
What You'll Learn
optimize_text (Stage 1)translate_text (Stage 2)refine_translation (Stage 3)Prerequisites
refine_translation additionally needs iterative refinement (VIBECODER and above)Time Estimate
~12 minutes
The Input
Here is the message, unedited:
`` hey so we need users to be able to like save their stuff and come back to it later, also should probably work if theyre on their phone. oh and marketing wants to know how many people actually use it. asap plstext
`
Four requirements are buried in there: persistence, session resumption, mobile support, and usage analytics. None are specified.
Stage 1 — Optimize the Input
optimize_text is a monolingual edit pass. It fixes grammar, tone, and clarity without adding meaning. It accepts audience and context, but uses them only to calibrate tone. It never produces a document, so it deliberately rejects the output-shaping parameters format and tone.
Ask your assistant:
> Use optimize_text on this Slack message with audience "Tech Lead" and context "Backend".
`json
{
"input": "hey so we need users to be able to like save their stuff...",
"audience": "Tech Lead",
"context": "Backend"
}
`
The result reads cleanly but says exactly the same thing:
`text
We need users to be able to save their work and return to it later.
This should also function on mobile devices. Additionally, marketing
would like visibility into usage metrics. This is high priority.
`
optimize_text accepts only input, audience, context, and managedModel. The schema is strict, so passing format or tone returns a validation error rather than silently ignoring them. That is intentional — a silent drop would let you believe a parameter applied when it never did.
When to skip this stage: if your input is already well-written, go straight to Stage 2. Stage 1 is a polish pass, not a requirement.
Stage 2 — Generate the API Design
Now the real work. translate_text takes the four parameters that shape the entire output:
| Parameter | Value | Effect |
| ---------- | ------------ | --------------------------------------------- |
| audience | Senior Dev | Assumes fluency; skips basic explanation |
| context | Backend | Frames output around services and data |
| format | API Design | Produces endpoints, schemas, and status codes |
| tone | 70 | Detailed — crosses the 50 threshold |
> Use translate_text with the optimized text, audience "Senior Dev", context "Backend", format "API Design", and tone 70.
`json
{
"input": "We need users to be able to save their work and return to it later...",
"audience": "Senior Dev",
"context": "Backend",
"format": "API Design",
"tone": 70
}
`
The tone value is a hard binary, not a gradient. Below 50 produces a concise rewrite; 50 and above produces a full technical document. A tone of 49 and a tone of 51 give structurally different documents, while 51 and 90 differ only in depth. If your output feels too thin, the first thing to check is whether tone dropped below 50.
The output is a structured API design — resource endpoints, request and response schemas, status codes, and an auth model. Concrete enough to review.
Checkpoint
At this point you should have:
That last one matters. A spec vague enough that nobody can object has not done its job.
Stage 3 — Refine the Output
Reviewing the design, two things are missing: pagination, and the analytics requirement was dropped.
refine_translation handles this. The critical distinction:
> Stage 1 targets raw input. Stage 3 targets generated output. They are not interchangeable.
Passing your original Slack message to refine_translation will not work as expected — it expects the generated document in previousOutput.
> Use refine_translation with that API design as previousOutput and this feedback: "Add cursor-based pagination to the list endpoint, and add an endpoint that exposes usage metrics for the marketing team."
` { "previousOutput": "## API Design: Workspace Persistence\n\n### POST /api/workspaces...", "feedback": "Add cursor-based pagination to the list endpoint, and add an endpoint exposing usage metrics.", "audience": "Senior Dev", "context": "Backend", "format": "API Design", "tone": 70 }json
`
Each refinement returns a complete standalone document, not a diff. Feed the newest version into the next previousOutput — chaining refinements against a stale copy silently discards the intervening work.
Refinements are quota-limited. Over MCP the allowance is the same as in the web app: 25 per month on VIBECODER, 100 on DEVELOPER, and unlimited on ENTERPRISE. Check with get_account_info before a long revision session.Handling Oversized Input
translate_text caps input at 10,000 characters. For a long requirements document, condense it first:
> Use summarize_input on this document, then translate the summary.
`json
{
"input": "<up to 15,000 characters>"
}
`
It returns the summary followed by the before-and-after length:
`text
The platform requires persistent user workspaces...
(14820 → 9480 chars)
`
The REST endpoint behind it, POST /api/v1/optimize/summarize, also returns reductionRatio — the fraction removed, (originalLength − summaryLength) / originalLength, so 14,820 → 9,480 is 0.36.
Feed the summary into translate_text, but check the second number first. The summarizer condenses the text rather than cutting it to a fixed size, so a 15,000-character input can still land above the 10,000-character translate limit. If it does, summarize the result again or split the document. Note the other ceiling: summarize_input accepts 15,000 characters, so a genuinely large document needs splitting before it reaches this tool.Troubleshooting
Input must be at least 10 characters
Every text-accepting tool enforces a 10-character floor. Usually means a variable resolved empty.
The output is far shorter than expected
Tone fell below 50. Values under 50 request a concise rewrite, not a document. Raise it to 60–75.
refine_translation ignored my feedback
Check what went into previousOutput. Passing the original raw input instead of the generated document is the most common cause — the tool then has no document to revise.
HTTP 403 on refine_translation
Refinement needs iterative refinement (VIBECODER and above). Confirm with get_account_info that iterativeRefinement appears in features.
DevSpeak API request to <url> timed out
The MCP client stopped waiting for a response; this is not an error returned by the server. A large input combined with a high tone setting can take long enough to hit it. Shorten the input or lower the tone.
Summary
You've learned how to:
without altering meaning on generated output