Skip to main content

Tower MCP Server - from Zero to App

Our CLI docs explain how to start and add an MCP server to your client... but it may not be super obvious how to use the Tower MCP server to enhance your productivity - or why you would want it in the first place!

So here I've decided to walk you through the process in one Claude code session, vibe engineering an app from scratch.

Prerequisites for following at home

  1. Claude code (obviously you can use whatever client you like, but the setup can differ)
  2. The Tower CLI
  3. A tower account
  4. A computer with an ability to open a terminal

You can install the Tower cli with pip:

pip install tower

Or you can run the Tower CLI without installing with uvx:

uvx tower --help

In this walkthrough, I'm using uvx.

1. MCP init

First things first, we need to start the mcp server, and set up Claude to be able to see it. We start the mcp-server with:

tower mcp-server --port 34567 &

This will run the MCP server in the background (n.b. it's important to keep the server running in a terminal window while using the MCP server, but it's not necessary to start it more than once, as the LLM can specify its own working directories).

Next we add the MCP server to our claude project configuration with:

claude mcp add tower "http://127.0.0.1/sse" --transport sse

Here's how that looks:

2. Getting started

To get a good session with an agentic coding tool like Claude, it's vitally important to write a detailed prompt at the beginning of your chat. Here I've come up with an idea of an app - a weather forecast app that will let me know what kind of clothes I should be putting on in the morning.

Bullet points are good for LLMs (you can get newlines in the Claude code CLI tool by typing \ before hitting enter). Additionally, try to scope down the project as much as possible as we can always add complexity later. In this case, I know I want it to text me every day, but let's start off with it just printing out the result. And if I want it to use an MCP server like the Tower MCP server, it helps if I instruct it to use it. MCP servers are great at keeping LLMs in their lane, so they don't try to hallucinate so much when they could just call an external tool.

Here, we can see our first hallucination from Claude - it wants to use hatchling. There's no reason to use hatchling for deploying to Tower - all you need is a pyproject.toml and a Towerfile. And we just generated the former!

3. Starting to vibe engineer

Now Claude will start generating some code. It's good at Python, so it will easily be able to solve almost any problem you throw at it when it comes to Python code... But not necessarily in the best possible way.

One strategy with agentic coding is rather than attempt to understand everything at once, if you have a gut feeling that there's just too much code, or too much for you to read at once - reject the code, and tell it to simplify. This can result in much easier to grok code!

4. Starting to use the Tower MCP tools

To use Tower, we need to make a Towerfile. Without the mcp-server running, Claude will happily hallucinate some random convincing looking YAML that could be a Towerfile... if it doesn't read the docs. However, with the MCP server, it can easily generate one with exactly the right syntax from a pyproject.toml file, and modify it as it needs.

Next, it tries to create a Tower app... and fails. Oops! I forgot to login to Tower before starting the MCP server. No biggie - we can quit claude, run tower login to log into your Tower account in a browser window, then continue the claude conversation with claude --continue:

5. First MCP tools integration

Since I interrupted it trying to find out how the Tower workflow works, let's prompt it to continue where it left off. The workflow MCP tool explains to Claude how it should be using all the other Tower MCP tools, and in what order. We could add this into the MCP server's documentation, but then it will forever eat up your context window, even when you're not using the MCP server. We can save precious context window space by letting it ask how to use the MCP server when it needs to know.

As usual, I continue to ask it to simplify the code it comes up with, making things a lot more tractable to review (until you review and understand the code generated by Claude, the bus factor of that code is 0, so make your life easier!).

Now Claude is starting to get the hang of Tower! It's able to:

  • deploy your app
  • run the app locally
  • run the app remotely

When it has the ability to deploy and run things on its own, now the power of agentic coding can come into play. Claude is able to make a change, run that change, and then use the result of that change as feedback.

6. ETL phone home?

Tower apps are useful if they can get data from the outside world. Previously, it was mocking data, and now we can fetch it. I ask it to get its data from https://open-meteo.com/, an excellent free API for getting the weather forecast.

7. Parameters

A very useful feature of Tower is being able to parametize an app, giving different inputs for different runs. For example, this could mean that you can have multiple ETL jobs running on different schedules for different tasks.

Let's use this feature to be able to change the location where we're checking the weather.

Parameters are passed into Tower apps directly as environment variables. However, Claude doesn't necessarily know that, and some gentle probing can point it in the right direction.

It's able to fetch these very docs in order to be able to work out how to use the tool. After looking it up, it sees that they're passed in as env vars.

But now it doesn't know what those env vars look like - at the time of writing, we do not modify these environment variable names at all, they're exactly the same as the parameter names. However, Claude will try and work this out on its own:

And... it's actually successful! Yes, it hallucinated a bunch of ways to get Tower parameters, but the agentic workflow meant that in the end it worked out on its own what they should look like.

So here's it actually using those parameters:

8. Verify verify verify

If you wanna avoid the pitfalls of LLM hallucinations, it helps to always be skeptical. It generates code getting stuff from an API? Let's double check that it works!

9. Crafting the app

Now it's a matter of getting the LLM to modify the app it came up with to better fit your needs. I'm not American, so I don't know what a Fahrenheit is or how many football fields a second it represents. So I'll ask Claude to please Europeanize it all for me 😉

It generated a list of longitude and latitudes for a bunch of EU cities. Possibly they're all correct, but I'm not super talented at memorizing longitude and latitude numbers off the top of my head. Given that random specific numbers are not really the strong points of large language models, I wanted to double check if they were real.

And of course, it turns out that if you ask Claude this, it suggests that we don't even needd to use them, when we can just pass in the city to Open Meteo 😅

10. Tower secrets

Using an open API is sort of cheating - most APIs need secret keys and authorization. Luckily, Tower supports that too!

Let's bring in twilio notifications. I have an API key that Claude can read and create a Tower secret for, which is accessible in our Python app through environment variables, similar to the parameters.

11. Scheduling and Automation

Now the most important part of it all - running it on a schedule! Now I can finally find out what the weather is outside without having to bother to look out my window.

Conclusion

And that's it! We've gone from zero to a fully automated weather app that texts me every morning - all in one Claude session with the Tower MCP server doing the heavy lifting. The real magic here is that Claude can now deploy, test, and iterate on real infrastructure, turning ideas into running applications without you having to context-switch between coding and ops work.

Happy hacking!