# Capstone: a real end-to-end Claude workflow
You are going to build a research-to-report assistant that wakes up every Monday, pulls fresh data from your live sources, drafts a structured report in your house voice, and drops it where your team already works. No copy-pasting, no babysitting a chat window. This lesson is about the architecture decisions, not the keystrokes, so you can swap in your own domain (competitive intelligence, weekly metrics, regulatory monitoring) without rewriting anything.
We will assemble it from the pieces you have already met: Projects, Connectors, MCP, Claude Code, the Messages APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.View full definition →, and a schedule. The skill here is choosing the *right* piece for each job.
Here is the shape of what we are building:
1. Context lives in a Project so every run starts with the same background, sources, and instructions.
2. Live data comes in through Connectors or a custom MCP server, not a stale paste.
3. The heavy lifting (multi-step reasoning, file generation) runs through Claude Code or the Messages APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.View full definition →.
4. Voice and format are enforced with a Style and a reusable Skill.
5. A schedule triggers the whole thing so it runs without you.
The mistake most people make is collapsing all five into one giant prompt. Keep them separate. Each layer has a different rate of change: your context evolves slowly, your data changes daily, your formatting almost never changes. Separating them is what makes the thing maintainable.
Start in the Claude app and create a Project for this assistant. A Project is a workspace that carries persistent instructions plus a knowledge base of files into every conversation inside it.
Put three things in the Project's custom instructions:
Upload your reference files to the Project knowledge: last quarter's reports, your taxonomy of competitors, a glossary. This is the slow-changing context. You set it once and it grounds every run.
Why a Project and not just a system prompt in the APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.View full definition →? Because you want a human-usable surface too. When the scheduled run produces something odd, you open the Project, ask follow-up questions against the same context, and debug interactively. The Project and the automation share the same brain.
Read the current capabilities in the Projects documentation.
A report is only as good as its freshest input. This is where MCP (Model Context Protocol) earns its place. MCP is an open standard that lets Claude talk to external tools and data sources through a uniform interface, so you do not hand-roll a custom integration for every source.
You have two routes:
Connectors are pre-built MCP integrations you enable from the connector directory inside the Claude apps: things like Google Drive, web search, and a growing marketplace of third-party services. If your data already lives somewhere with an official connector, use it. Zero code.
A custom MCP server is what you build when your data lives somewhere bespoke: an internal pricing database, a partner APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.View full definition →, a scraping pipelinepipelineAll active sales opportunities across the stages of the sales process, together with their combined potential value and probability of closing.View full definition →. You expose that source as a small server that speaks MCP, and Claude can then call it like any other tool.
For our EV report, say we need live charger deployment numbers from an internal APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.View full definition →. A minimal MCP server tool looks like this:
from mcp.server.fastmcp import FastMCP
import httpx
mcp = FastMCP("ev-data")
@mcp.tool()
async def get_deployments(region: str, since_days: int = 7) -> dict:
"""Fetch new charger deployments for a region in the last N days."""
url = f"https://internal.example.com/deployments"
params = {"region": region, "since_days": since_days}
async with httpx.AsyncClient() as client:
resp = await client.get(url, params=params, timeout=30)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
mcp.run()That is the whole pattern. One decorated function becomes a tool Claude can invoke by name, with the docstring acting as the description the model reads to decide when to call it. Write tight docstrings: they are prompt surface, not just comments.
Start at modelcontextprotocol.io for the spec and SDKs.
Decision rule: reachreachThe number of unique people exposed to your message in a given period. Unlike impressions, reach counts each person once, no matter how often they see it.View full definition → for a Connector first. Build a custom MCP server only when no connector exists or your source is private. Do not build what you can enable.
Now the heavy lifting: read the data, reason across sources, write the report, save a file. You have two engines, and the choice matters.
Claude Code is Anthropic's agentic coding tool that runs in your terminal. It is not just for writing software. It can read and write files in a working directory, run commands, and call your MCP servers, which makes it a capable *workflow* runner. For our report, Claude Code can pull data, synthesize, and write report-2026-W12.md to disk in one agentic loop.
The Messages API (or the Claude Agent SDK on top of it) is what you use when you want to embed this in your own service: a web app, a Lambda, an existing data pipelinedata pipelineETL (Extract, Transform, Load) is a data integration process that pulls data from sources, reshapes it into a consistent format, and writes it into a target system.View full definition →. More control, more code.
For a capstone you are running for yourself or a small team, Claude Code is the faster path. It already handles the agent loop, file I/O, and tool calls. You configure your MCP servers once in its settings and point it at a prompt.
Here is the project-level MCP config Claude Code reads:
{
"mcpServers": {
"ev-data": {
"command": "python",
"args": ["./servers/ev_data.py"]
}
}
}With that in place, a single instruction like "Generate this week's report using the ev-data tool for the West and Northeast regions, follow the Project's section contract, and save it as a dated markdown file" runs the entire chain.
The Agent SDK is the right call later, when you want this running headless inside production infrastructure with your own retry logic, logging, and guardrails. Browse it at github.com/anthropics.
Your report cannot read like generic AI prose. Two features fix this.
Styles control tone and writing conventions. Create a custom Style trained on a few of your past reports so output matches your house voice: terse, no hedging, bullet-heavy. The Style travels with the Project.
Skills are packaged, reusable instructions plus optional resources that Claude loads when relevant. For our report, build a Skill that encodes the *report-generation procedure*: how to weight sources, how to flag low-confidence claims, the exact table format for the deployment numbers. A Skill is more durable than stuffing all that into one prompt, and you can version it.
The split is clean: the Style governs *how it sounds*, the Skill governs *how it is built*. Keep formatting logic out of your data layer and out of your engine. When your boss asks for a new section next quarter, you edit the Skill, nothing else.
Knowledge check
1. According to the lesson, what is the central skill required to build this end-to-end Claude workflow?
2. Why does the lesson argue for keeping the five layers separate rather than collapsing them into one giant prompt?
3. In the Claude ecosystem, what best describes a Project?
4. Select ALL correct answers. Which responsibilities does the lesson assign specifically to the live data layer of the workflow?
Sélectionnez toutes les réponses correctes.
5. Select ALL correct answers. According to the lesson, what should be placed in a Project's custom instructions for this assistant?
Sélectionnez toutes les réponses correctes.
An assistant you have to launch by hand is not automation. You need a trigger.
Claude Code runs as a command, so the scheduler is just your operating system or CI. The cleanest approach is a cron job (a Unix scheduler that runs a command on a time pattern) or a GitHub Actions workflow.
A cron entry for every Monday at 7am:
0 7 * * 1 cd ~/ev-report && claude -p "Generate this week's report using the prompt in run.md" >> run.log 2>&1The -p flag runs Claude Code in non-interactive ("print") mode: it executes the prompt, does its agentic work, and exits. That is what makes it scriptable. Your run.md holds the standing instruction so the cron line stays stable.
For a team, push this into GitHub Actions instead. A scheduled workflow runs the same command on Anthropic-hosted or your own runners, commits the generated report to the repo, and the GitHub integration lets the model open a pull request with the draft for human review before anything ships. That review gate matters: you want a person approving the report, not a robot publishing unread claims to stakeholders.
Step back and notice how the layers hand off:
Each seam is a place you can swap a part without touching the rest. Change data sources? New MCP server, same engine. Change the engine to the Agent SDK for production? Same MCP config, same Skill. This is the real lesson of the capstone: good AI workflows are *composed of replaceable parts*, not monolithic prompts.
Two things will break first, so design for them now.
Stale or empty data. Your MCP tool should return a clear signal when a source is down, and your Skill should instruct Claude to flag a degraded report rather than hallucinate around missing numbers. A report that says "deployment data unavailable this week" is correct. One that invents numbers is dangerous.
Silent drift. Schedule a monthly human read of a full output, end to end. Automation hides slow decay. The Project surface is exactly where you do that audit, because it shares context with the automated run.