MCP servers at work: what they can reach and how to inventory them
An AI assistant that can only talk is one kind of risk. An assistant wired to your file system, your repositories and your database is another. The wiring is done by employees, in configuration files nobody reviews.
- By
- GhostAudit
- Published
- Last reviewed
- Reading time
- 7 min read
Key points
- An MCP server gives an AI assistant tools: reading files, querying a database, opening pull requests. It acts with the credentials of the person who configured it.
- Local servers are started by the assistant itself from a configuration file on the device. They do not appear in single sign-on logs or on a network proxy.
- The useful inventory is per server: what it is, what it can reach, where it is configured and who decided it was acceptable.
- Inventory the configuration, not the secrets. Server names, package names and hostnames are enough; tokens and connection strings should never leave the device.
What an MCP server is
The Model Context Protocol (MCP) is an open protocol for connecting AI applications to other systems. The AI application, such as a desktop assistant or a coding assistant in an editor, is the client. An MCP server is a small program that offers the client a set of tools: functions the model can call, such as "read this file", "run this SQL query" or "create an issue".
The specification describes tools as model-controlled: the language model discovers them and decides when to invoke them, based on the conversation. That is the point of the protocol, and it is also why it deserves attention. The same specification says there should always be a human in the loop with the ability to deny tool invocations, and that applications should show confirmation prompts. Whether a given client does so, and whether the person reads the prompt on the fortieth occasion, is another matter.
Two ways a server runs, and why it matters for visibility
The specification defines two standard transports.
stdio. The client launches the server as a subprocess on the same computer and talks to it over standard input and output. Most servers a developer adds by hand work this way. A typical entry tells the client to run a package with a launcher such as npx or uvx, which downloads and executes it.
Streamable HTTP. The server runs as an independent process, often operated by a software vendor, and the client connects to a URL. An older HTTP transport based on server-sent events is deprecated but still found.
The difference decides who can see the server.
A remote server is reached over the network, usually after an OAuth sign-in. It may appear in your identity provider as a granted application, and its hostname appears in network logs.
A local server is a process started from a configuration file. No sign-on event is created. No new domain is contacted until the server itself calls something. From the network it looks like the developer's own machine talking to GitHub or to the database, which it is.
What a server can reach
A server can reach whatever its credentials and its host allow. The MCP documentation for connecting local servers says of the filesystem server that it runs with your user account permissions, so it can perform any file operation you can perform. The same logic applies generally.
| Kind of server | What it can typically reach |
|---|---|
| Filesystem | Files in the folders it is pointed at, to read and to write |
| Shell or command execution | Anything the user can run on the device |
| Source control (GitHub, GitLab) | Code, issues and pull requests in every repository the token covers; can push changes |
| Database | Every table the database user can query, which may include customer or personal data |
| Browser automation | Any site, including ones the user is signed in to |
| Mail, documents, calendar | The content of the connected account |
| Chat (Slack and similar) | Messages and files in channels the token can read; can post |
| Cloud infrastructure | Resources the configured credentials can read or change |
| Payments and CRM | Customer and payment records; some can create charges or refunds |
| Web fetch and search | Public pages; the query is sent to the provider |
The token is the boundary. A GitHub server configured with a personal access token that covers the whole organization gives the assistant the whole organization.
The risks in plain terms
Data goes further than intended. Whatever a tool returns becomes part of the conversation and is sent to the model provider. A query against a customer table puts customer rows into a prompt. If the assistant is a personal account outside your company agreement, that data has left your control.
Instructions arrive from untrusted content. A model reads a web page, an issue or a document through one tool and can be induced by text inside it to call another. An assistant with both a "read the web" tool and a "read private files" tool is a path from one to the other. The specification asks clients to treat tool annotations as untrusted unless they come from a trusted server, and to show tool inputs to the user before calling a server, to avoid malicious or accidental data exfiltration.
The server itself is code you are running. A local server started with npx or uvx is a package downloaded from a public registry and executed with the user's privileges. The specification's security best practices list this under local MCP server compromise: a malicious startup command in a client configuration, a malicious payload inside the server, or an insecure local server reached by another process. It names arbitrary code execution, data exfiltration and data loss as the results.
Credentials sit in plain text. Configuration files commonly contain API tokens and database connection strings, in the user's home directory.
None of this is an argument against MCP. It is an argument for knowing what is connected.
Where the configuration lives
Each client keeps its own configuration, usually a JSON file in the user's profile with an object that maps a server name to a command or a URL. For Claude Desktop the documentation gives ~/Library/Application Support/Claude/claude_desktop_config.json on macOS and %APPDATA%\Claude\claude_desktop_config.json on Windows, with servers under an mcpServers key.
Other clients follow the same idea with their own file: coding editors and their extensions, and command-line assistants. Three practical complications:
- Locations change. Clients move and rename these files between releases. Check each vendor's current documentation instead of relying on a list, including this one.
- There are several levels. Many clients read a user-level file and also a project-level file inside a repository. The second kind travels with the code and affects everyone who opens the project.
- Some clients have organization controls. A few let an administrator restrict which servers may be used. If a client you have standardised on offers this, it is the strongest control available, and worth more than any inventory.
How to build an inventory
1. Decide what a record contains
One record per distinct server, not per installation:
| Field | Example |
|---|---|
| Server | @modelcontextprotocol/server-postgres, or mcp.linear.app |
| Transport | stdio or HTTP |
| What it reaches | "Production Postgres, read-only replica" |
| Configured in | Which clients, on how many devices |
| Owner | The team that wants it |
| Decision | Approved, or not approved, with a reason and a date |
Note what the record does not contain: the token, the connection string, the file paths. An inventory that copies secrets out of configuration files has created a new store of secrets.
2. Ask first
For a small engineering team, a short survey works: which assistants do you use, and which servers have you connected to them? It is quick and incomplete, in the usual way of surveys.
3. Read the configuration files
For anything larger, collect from the devices. With endpoint management you can run a script that reads the known configuration files and reports back. If you write one, apply the rule above strictly:
- Report the server name, the launcher, the package name and, for remote servers, the hostname.
- Do not report
envblocks, headers, arguments or full URLs. A URL's path and query can carry a key. - Treat the server name as free text. Someone will have named one after a customer.
4. Check remote servers from the other side
Remote servers that authenticate with OAuth appear as granted applications in Google Workspace or Microsoft Entra ID, with the permissions granted. Review those grants alongside the device inventory; each finds things the other misses.
5. Review by reach
Sort by what a server can touch, not by how many people use it. One database server on one laptop outranks a documentation-search server on two hundred. For each high-reach server, ask three questions: which credential does it use and how broad is it, which assistant is it connected to and under what data terms, and does the client ask for confirmation before a tool runs?
6. Write the rule down
Add a short section to your AI acceptable use policy: which kinds of server need approval before they are connected, that credentials must be scoped to the task, that production data is not reachable from a personal assistant account. Then keep the inventory current, because the configuration changes weekly.
What an inventory will not tell you
An inventory of configuration shows what an assistant could reach. It does not show what it did. Tool calls happen inside the client; seeing them means logging at the server, at the system being called, or in the client where it offers audit logs. For the systems that matter most, the reliable record is the target's own access log, read with the knowledge that some of the access was an assistant acting for a person.
How GhostAudit approaches it
The GhostAudit desktop agent reads the user-level MCP configuration of eleven agent clients on macOS and Windows and reports, for each server, the client, the name, the transport and either the package name or the hostname. It never reports env values, headers, tokens, other arguments, paths or URL paths; the record has no field for them, and the server validates each field again on arrival. Well-known servers are annotated with what a server of that kind can reach, and each can be marked approved or not approved, as a record for reviewers.
It reads configuration, not activity, and it does not read project-level files. It does not block or remove anything. AI agent discovery has the full list of what is and is not covered.
Sources
- Model Context Protocol specification: Tools (version 2025-06-18)modelcontextprotocol.io
- Model Context Protocol specification: Transports (version 2025-06-18)modelcontextprotocol.io
- Model Context Protocol specification: Security best practicesmodelcontextprotocol.io
- Model Context Protocol documentation: Connect to local MCP serversmodelcontextprotocol.io
This guide is for orientation and is not legal advice. It was last reviewed on 10 November 2026; laws and guidance change, so check the official texts linked above. Spotted something out of date? Tell us.