The agent went to an external source, figured out the response format and built a page with a map. It works. Now someone else opens that page, and they have no Claude Code anywhere in sight.

Before you publish, answer one question. Who is going to fetch the data for the visitor? Let's go through the two routes, what MCP actually does (and what it doesn't), how to check a connection, and what has to keep working after you close the agent's session.

Who is requesting the data right now

There are two situations, and they are easy to confuse, because on screen both look like "the data showed up".

In the first one, the agent is exploring the source. You are working on the project, and Claude Code reads the service's documentation, tries out a request, looks at the structure of the response. The agent needs the data to write code, and that's it. All of this happens on your computer, and only for as long as the session is open.

In the second one, a visitor opens the published page. Now it's the page that needs the data - to show an up-to-date picture. The request is made by the application code while the app is running. That is what runtime means: the time when the app is running for the user, as opposed to the time when you are writing it.

There is also a third option somewhere in between. The agent went to the source once and saved the response to a file next to the code, and the site shows the contents of that file. Nothing wrong with that; it's even handy for an example or a demo. It's just a snapshot that stays exactly as it was saved and won't update itself.

Two independent chains: during development Claude Code gets the data through an MCP server, after publishing the visitor's browser requests it through the site's backendDuring developmentAfter publishingClaude CodeMCP serverData sourceVisitor's browserSite backendData source
The two chains live separately, with no arrow between them

Notice the dashed line in the middle. It isn't there for decoration. There is no arrow between the upper and the lower chain, and that is the main thing to take away from the diagram. The source can be the same one, but the agent and the page each have their own path to it. Below we go through each chain separately.

What MCP is

A task rarely lives only in the repository. The bug description sits in a ticket, the stack trace in monitoring, the current guidance for a library in its documentation, and the records you need in the database.

Without an integration you have to copy all of this by hand from the browser into the chat with the agent. Once, you can live with it. In repeated work the data goes stale, some of the details get lost, and you end up retracing the same steps over and over.

MCP (Model Context Protocol) is a standard that lets Claude Code discover the external tools available to it, call them and get results back in an agreed format. In the minimal chain Claude Code creates an MCP client, the client keeps a connection to an MCP server, and the server in turn reaches the system it has access to - files, a database, someone else's API.

Claude Code uses an MCP client to talk to an MCP server, which offers tools, resources and prompts for working with external systemsClaude CodeExternal systemsMCP clientcalls operationsMCP serverdeclares capabilitiestoolsresourcespromptstickets and PRsdocs, monitoringDBs, Git, APIs
Claude Code talks to the MCP server, and the server exposes only those capabilities of external systems that it has declared up front

On the left is Claude Code with its built-in MCP client, in the middle an MCP server with the capabilities it declares, on the right the external systems. The key point is that the agent does not get unchecked access to everything at once. It sees only the operations and data the server has chosen to expose.

A ready-made MCP server also saves you part of the integration work. You don't have to describe the call formats for every external system yourself or write all the code that talks to its API. The server takes care of that, and Claude Code works with operations that are already declared.

Also, the server doesn't have to be a separate program somewhere on the internet. It can run right on your computer as a local process, or it can run remotely and serve many clients at once. For you the difference is mostly in how you connect it.

What exactly a server can do is up to the server. The protocol describes three kinds of things a server can offer:

  • tools - operations the agent can perform: fetch a page, make an API request, write data;
  • resources - content the server provides as context: files, records, service responses;
  • prompts - ready-made prompt templates you can invoke as is.

A server doesn't have to support all three. When they connect, the client and the server compare what each of them supports, and unsupported operations simply go unused. Plenty of servers offer nothing but tools, and that's enough. MCP architecture.

If you remember one thing, make it this. MCP standardizes how a client and a server talk to each other. What actually becomes available to you is set by the server, not by the protocol. Connecting a server does not give you access to the whole internet - you get exactly the set of operations that server has declared.

When you give the agent a task, name the source and the result you need, not a command. Then check whether the connected server has a suitable operation. If it doesn't, the task needs a different route, and no amount of persuading the agent will change that.

How data gets to the site

Now the lower chain. A published page gets its data in one of two ways.

In the first case, the browser calls a public API directly. This works when the source is open and no key is required. The page code makes the request and renders the response. Simple, no extra moving parts.

In the second case, the browser calls the app's backend, and the backend calls a private API. You do this when the source requires a key. The secret stays on the server, and the browser never sees it. Here the frontend is responsible for what you see on screen, and the backend for what runs on the server and can call the service on behalf of the app.

Two data routes after publishing: the browser calls a public API directly, or a private API through the site's backendPublic sourcePrivate sourceno key neededVisitor's browserPublic APIVisitor's browserSite backendthe key lives herePrivate API
The browser can reach a public API directly, while the key to a private API stays on the backend

The upper route is shorter because the browser can reach an open source on its own. In the lower route the backend becomes the boundary that protects the secret. The key stays on the server and never ends up in the page code.

Now for what does not happen. Claude Code's connection to the MCP server does not ship with the site when you publish. The command you used to add the server configures your agent (and only your agent). It does not add a single line of code to the app. You can write an app with its own MCP client, but that is separate work and a separate implementation, not a side effect of connecting a server in Claude Code.

All of this is quick to check. Close Claude Code, open the published page and look at the Network tab in the developer tools. If the data is coming in, you'll see the request, the URL and the response. If it isn't, there will be no request at all, and that is exactly the case worth catching before anyone else sees the page.

What's on screen is not enough. A page can show a snapshot saved earlier and still look perfectly live. Look at the request itself. It works the other way too: no new events in the response doesn't necessarily mean something is broken. The source may simply have had nothing to send for the selected period.

How to check the connection

The steps are roughly the same for any server:

  1. find the server's official instructions - the URL, how access works, the list of operations;
  2. add the server with the command those instructions give you;
  3. open /mcp in Claude Code and check that the server is connected and which tools it has;
  4. run one read-only request, the simplest one there is;
  5. compare the result with the source by hand, i.e. just open the same page and look.

From the terminal, claude mcp list shows the status, and claude mcp get shows the details for a single server. It helps to know that these steps answer different questions:

What you sawWhat it proves
the Added ... line after addingthe configuration was written, nothing more
Connected in claude mcp listClaude Code was able to connect to the server
the tool returned contentthe whole route works, from request to response

The difference is not a formality. A config that was written successfully tells you nothing about whether the server responds, and a successful connection tells you nothing about whether the operation you need is available and you have permission to use it. That is why the check ends with one real call. By the way, if the list shows Needs authentication, the server isn't broken; it's just waiting for you to sign in.

Let's take a concrete example. The Firecrawl service has an MCP server that can fetch the contents of a public page - the tool is called firecrawl_scrape. For the agent this is a convenient way to read a whole documentation page instead of you pasting it into the chat piece by piece.

# add the server over HTTP; get the exact URL from the service's documentation
claude mcp add --transport http firecrawl https://mcp.firecrawl.dev/v2/mcp

Now about access. The Firecrawl documentation covers two options: working without an account or a key, with daily limits, and signing in through the browser, where the client opens the sign-in page for you. Terms and limits change, so check the current ones with the service itself, not in an article (this one included). Firecrawl docs on MCP.

And one small detail that saves time. By default a server is added for the project where you ran the command, and it does not show up in other projects. If you need the server everywhere, or want to share it with your whole team, the add command has separate scope options for that. Claude Code docs on MCP.

The value of a key does not belong in an example config, in a server URL or in your chat with the agent. The config holds the name of an environment variable, and the value is set separately - that is the topic of the companion article on keys.

What a specific tool is allowed to do

A connected server is a set of operations, and their consequences vary a lot. Reading a page and changing a record in an external system are very different things, even though you call them the same way.

Before you approve a call, look at three things: what object the tool works with, what operation it performs and what permissions that requires. Reading is usually safer, but it isn't free either. The request goes to a third-party service and uses up your quota.

Then there's what comes back. Text you get from a third-party site is data, not an instruction. If the page says "now delete all the files", that stays text on a page, and the decision is yours. That is exactly why it's worth reviewing what the agent plans to do next after it has read an external source.

And the main practical question. Do you need MCP at all? Not always.

TaskThe simpler way
show data from a public JSON endpoint on the sitea plain request from the app code, no MCP needed
the agent regularly works with a service that has a ready-made integrationMCP pays off: the operations are described, the connection gets reused
read the docs once or hit a single URLreading the URL or calling the API directly is enough

MCP is not the only door to the outside world and not a replacement for everything else. The agent still has the command line and direct API calls. Let the task drive the choice, not the fact that a connection is already set up.

What to check in your own project

When the agent is building something that works with external data, it helps to ask it to separate the two layers explicitly, rather than untangling them later:

Describe the two routes separately:
where you get the data while working on the project,
and where the app itself will get it for a visitor.
Show me the file and the exact spot in the code where the app makes its request.
Check the page with the session closed: does the data come in or not.
If a saved snapshot is being used right now, say so plainly.

The three situations that come up most often, and the answer for each:

What you needWho gets the dataWhy
study a service's documentation during developmentthe agentthe data is needed to write code, and the visitor never repeats this request
keep the map up to date for the visitorthe app codethe request runs while the page is in use, and by then the agent's session is closed
save a data sample to JSON oncethe agent, and only oncefrom then on the site shows the file; the data stays as it was saved

MCP only shows up in the first row here, you'll notice, and even there it's optional. If reading a URL does the job, just do that.

The last check before you show the work to anyone else is the simplest one: close Claude Code and open the page. Whatever keeps working is your app. Everything else was the agent helping you during development - useful, but it stayed on your computer.