<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Engraphis]]></title><description><![CDATA[Engraphis]]></description><link>https://engraphis.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 08 Nov 2026 13:28:14 GMT</lastBuildDate><atom:link href="https://engraphis.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[MCP server ownership: the checklist I use before an agent touches production]]></title><description><![CDATA[An ownership checklist for MCP servers before a coding agent touches production: owners, tool scope, credentials, logs, provenance, and revocation.]]></description><link>https://engraphis.hashnode.dev/mcp-server-ownership-the-checklist-i-use-before-an-agent-touches-production</link><guid isPermaLink="true">https://engraphis.hashnode.dev/mcp-server-ownership-the-checklist-i-use-before-an-agent-touches-production</guid><category><![CDATA[mcp]]></category><category><![CDATA[AI]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Security]]></category><dc:creator><![CDATA[Coding-Dev-Tools]]></dc:creator><pubDate>Tue, 03 Nov 2026 05:56:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6ae96f3a7b7b39a314a45f6a/f6dcdeb6-2de7-4b88-8303-a756d62ca6f0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A local MCP server starts as a convenience. Someone adds it to a config file, points it at a database, and uses it to speed up a task. Six months later, nobody remembers who owns it, what it can read, or why it has a write token.</p>
<p>That is the point where an MCP server stops being a helper and becomes infrastructure. Infrastructure needs an owner, a scope, logs, and a way to turn it off.</p>
<p>This is the checklist I use before an agent gets access to anything that matters.</p>
<h2>1. Name an owner and a backup</h2>
<p>Every MCP server needs one person who is accountable for it and one person who can revoke it. Put both names in the repository, next to the server configuration.</p>
<p>If the owner leaves the team, the server should not become a mystery. The backup should be able to explain what the server does, which credentials it uses, and how to disable it.</p>
<p>A simple line in the repo is enough:</p>
<pre><code class="language-text">Server: postgres-read
Owner: Dana
Backup: Miguel
Purpose: read-only customer lookup for support agents
Kill switch: remove the tool from the MCP config and revoke the database role
</code></pre>
<h2>2. Write down the exact tool surface</h2>
<p>Do not describe the server as "database access." List the tools and what each one can do.</p>
<p>For each tool, record:</p>
<ul>
<li>the input it accepts</li>
<li>the data it returns</li>
<li>whether it reads or writes</li>
<li>the maximum result size</li>
<li>the scope it can reach</li>
</ul>
<p>A tool that runs <code>SELECT</code> against a read replica is a different risk from a tool that runs migrations. A tool that returns 50 rows is a different risk from a tool that returns the whole table.</p>
<p>If the tool list is too long to review, the server is too broad.</p>
<h2>3. Scope credentials to the minimum</h2>
<p>Use a separate credential for each MCP server. Do not reuse an admin token because it is convenient.</p>
<p>For a read-only server, use a read-only role. For a write-capable server, restrict it to the tables or actions it actually needs. If the server only creates draft records, it should not be able to delete them.</p>
<p>Store the credential in the environment or the OS credential store, not in the repository. Rotate it on a schedule and after any suspected exposure.</p>
<h2>4. Log reads and writes separately</h2>
<p>Most teams log errors and ignore successful tool calls. That makes it hard to answer basic questions:</p>
<ul>
<li>Which customer records did the agent read?</li>
<li>Which records did it change?</li>
<li>Which agent session made the change?</li>
<li>What did the human verify before the change was accepted?</li>
</ul>
<p>Log the tool name, the scope, the record IDs, and the session. Do not log raw secrets or full customer records. Separate read logs from write logs so a write review does not get buried in read noise.</p>
<h2>5. Record provenance in the pull request</h2>
<p>"The agent used the database" is not provenance. The pull request should say which server, which record, and what the human checked.</p>
<p>A useful line looks like this:</p>
<pre><code class="language-text">Source: postgres-read, customer 1842, subscription status changed on 2026-10-30
Human check: verified the cancellation reason in the billing dashboard
</code></pre>
<p>That line gives the reviewer something to inspect. It also makes the agent's reasoning auditable after the fact.</p>
<h2>6. Test revocation before you need it</h2>
<p>Revocation is not a document. It is a test.</p>
<p>Pick one server and walk through the shutdown:</p>
<ol>
<li>Remove the tool from the agent configuration.</li>
<li>Revoke the credential.</li>
<li>Confirm the agent can no longer call the tool.</li>
<li>Confirm the audit log shows the failed attempt.</li>
<li>Record how long the process took.</li>
</ol>
<p>If the test takes an hour, the real incident will take longer. Do it while the system is calm.</p>
<h2>7. Set a review cadence</h2>
<p>MCP servers drift. A token that was read-only last quarter may have been widened for a demo. A tool that was internal may now be exposed to a customer-facing agent.</p>
<p>Review the server every quarter:</p>
<ul>
<li>Is the owner still on the team?</li>
<li>Is the credential still scoped correctly?</li>
<li>Are the tools still necessary?</li>
<li>Are the logs still complete?</li>
<li>Has the server been used in the last 30 days?</li>
</ul>
<p>If nobody uses it, remove it. An unused server with a live credential is pure risk.</p>
<h2>A read versus write example</h2>
<p>Consider a memory server for a coding agent.</p>
<p>A read-only version can recall decisions and return the source. The worst case is a bad answer that a human catches.</p>
<p>A write-capable version can store a new decision, close an old one, or change the scope of a memory. The worst case is a corrupted project record that later agents treat as true.</p>
<p>The tool surface should make that difference obvious. The read tools should be separate from the write tools. The write tools should require an explicit scope and return a receipt.</p>
<h2>How Engraphis handles this</h2>
<p>Engraphis is the local-first memory server I built for coding agents. The governance model is the part I care about most.</p>
<ul>
<li>Memories are scoped by workspace, repository, and session.</li>
<li>Every record keeps its provenance and temporal history.</li>
<li>Superseded facts are closed, not silently overwritten.</li>
<li>Recall is bounded and cited.</li>
<li>The local dashboard lets you inspect, correct, and review conflicts.</li>
<li>The local core is Apache-2.0 and free. Pro adds hosted memory health and sync.</li>
</ul>
<p>The retrieval is useful. The ownership model is what makes it safe to leave running.</p>
<h2>If you want the setup done for you</h2>
<p>I do a fixed-scope MCP setup for teams. It includes:</p>
<ul>
<li>clean setup of Claude Code, Cursor, or Codex</li>
<li>integration of up to three MCP servers</li>
<li>environment, credential, and security configuration</li>
<li>a one-page runbook with the owner, scope, logs, and revocation steps</li>
<li>seven days of async text support</li>
</ul>
<p>The price is $250, the turnaround is 24 hours, and the delivery is text only. No calls or screen sharing.</p>
<p>Start here: <a href="https://engraphis.com">https://engraphis.com</a></p>
<hr />
<p>Disclosure: I built Engraphis. This checklist comes from building and operating it, not from a certification or a vendor audit.</p>
]]></content:encoded></item></channel></rss>