ThisCalculator

Everyday

MCP Claude Tool Use: Lambda Streams Agent Responses

Updated · Standard formula, shown below

This article explains how Lambda streams agent responses when using the Model Context Protocol (MCP) with Claude. You provide a prompt and tool definitions; the Lambda function orchestrates the agent loop and streams back each incremental update, including tool calls and final text, as a sequence of events.

Background: MCP and Claude Tool Use

The Model Context Protocol (MCP) is an open standard that lets AI applications connect to external tools and data sources. When Claude uses MCP, it can request tool calls (like querying a database or calling an API) and receive structured results. In a serverless setup, AWS Lambda hosts the orchestration logic that manages these interactions.

Claude’s tool use works via a loop: the model receives a user message and a list of available tools, decides whether to call one, and if so, emits a structured request. The application executes the tool and returns the result to the model, which then continues until it produces a final answer. Streaming this process is important for user experience—nobody wants to wait for the entire chain to finish before seeing anything.

How Lambda Streams Responses

Lambda functions can stream responses using the LambdaResponseStreams invocation mode. When you configure this, your function returns a series of payload chunks rather than a single JSON object. For agentic workflows, you typically use the AWS SDK to write each event to the stream as it becomes available.

Here is a simplified sequence:

  1. The client sends a prompt to Lambda (via API Gateway or directly).
  2. Lambda starts the agent loop, calling the Claude API with the prompt and tool definitions.
  3. When Claude returns a streaming response, Lambda reads each delta (text or tool call) and writes it to the Lambda response stream.
  4. If Claude requests a tool, Lambda executes it (e.g., a database query) and writes a tool_result event to the stream.
  5. Lambda then calls Claude again with the updated conversation, and the cycle repeats until the final answer is streamed.

Each chunk is a JSON object with a type field (e.g., text_delta, tool_call, tool_result) and the relevant payload. The client can parse these events and update the UI in real time.

Streaming Events Format

While the exact format depends on your implementation, a common pattern is to send events like:

  • text_delta: a piece of the assistant’s text response.
  • tool_call: a request from Claude to invoke a tool, including the tool name and arguments.
  • tool_result: the output from the tool execution.
  • end: signals the end of the stream.

For example, a chunk might look like {"type":"text_delta","text":"The weather in Paris is "}. The client can append each text delta to a display buffer, and when a tool call arrives, it can show a spinner or a “checking database…” message.

Choosing the Right Lambda Configuration

To use streaming, you must set the Lambda function’s InvokeMode to RESPONSE_STREAM when creating the function URL or using the InvokeWithResponseStream API. This mode is available for both synchronous and asynchronous invocations, but for agentic responses you typically want synchronous streaming so the client receives events as they happen.

Key considerations:

  • Response streaming works with all Lambda runtimes, but you need to use the AWS SDK to write to the stream.
  • Your function must return a stream of chunks, not a single JSON. The SDK provides methods like streamWriter.write() to send each event.
  • If you use API Gateway, you can enable response streaming on the integration, and the gateway will forward the chunks to the client.

Common Problems and Troubleshooting

One frequent issue is that the client receives all chunks at once instead of incrementally. This usually happens when the Lambda function buffers the entire response before writing to the stream. Ensure you are writing each event immediately as it arrives from the Claude API.

Another problem is timeouts. Lambda has a maximum execution time of 15 minutes, but for agentic loops with multiple tool calls, you may hit that limit. Consider breaking the work into smaller steps or using a step function to orchestrate the loop instead of a single Lambda.

If you see errors like StreamingResponseNotAvailable, check that the function URL or API Gateway integration is configured with RESPONSE_STREAM invoke mode. Also, ensure your IAM role has permissions for lambda:InvokeWithResponseStream.

Comparing Lambda Streaming to Other Approaches

Lambda streaming is ideal for short-lived agentic tasks that need real-time updates. For longer-running processes, you might use AWS Step Functions, which can handle multiple Lambda calls and still stream progress via a WebSocket or polling. Alternatively, you could use a dedicated compute service like ECS or Fargate for full control over the streaming connection.

Lambda’s main advantage is its simplicity and cost model—you only pay for the compute time used. The downside is the 15-minute limit and the need to manage the streaming protocol manually. For most MCP agent use cases, Lambda streaming is a good fit.

Cost and Performance Considerations

Lambda pricing is based on the number of requests and the duration of execution. Streaming responses can increase the duration because you are keeping the connection open while Claude generates tokens. However, for typical agent responses (a few tool calls and a few hundred tokens), the cost is minimal.

Performance-wise, streaming reduces the perceived latency because the user sees text appearing as it is generated. The actual time to complete the full response is similar to non-streaming, but the user experience is much better. To optimize, you can set a reasonable max_tokens for each Claude call and limit the number of tool calls per request.

Frequently Asked Questions

Can I stream tool calls and results separately?

Yes, you can send separate events for tool calls and results. This allows the client to display a notification like “Calling tool: get_weather” and then show the result when it arrives.

What if the client disconnects mid-stream?

Lambda will stop writing to the stream if the client disconnects. The function may continue running until it completes or times out, but the data is lost. You can detect disconnects by catching write errors and aborting the process.

Does streaming work with the MCP protocol?

MCP itself is a protocol for tool discovery and invocation. Streaming is a transport-level feature. You can use MCP to define the tools, and then stream the agent’s responses over Lambda’s response stream. The two are independent.

How do I handle errors during streaming?

You can send an error event (e.g., {"type":"error","message":"..."}) and then close the stream. The client should be prepared to handle such events and display an error message.

Is there a limit on the number of chunks I can send?

There is no hard limit, but the total response size is limited to 20 MB for synchronous invocations. For most agent responses, this is more than enough.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.