Why your wiki should probably be an MCP resource, not a tool
Nearly every internal-docs MCP server I’ve seen starts the same way: someone wraps the wiki search endpoint in a tool called search_wiki, ships it, and waits for the magic.
What happens next is consistent. The model calls it constantly for things that aren’t in the wiki, doesn’t call it for the one question the wiki actually answers, and pulls back three thousand tokens of a page whose first paragraph would have done. After a fortnight somebody quietly turns it off.
The failure isn’t the wiki and it isn’t the model. It’s that documentation was modelled as an action when it’s a body of content.
What the protocol actually distinguishes
MCP separates tools from resources, and the split is about who decides.
A tool is model-invoked. You expose it, describe it, and the model chooses when to call it based on that description and whatever it can infer from the conversation. That’s the right shape for something with an effect, or for a query whose parameters genuinely depend on context the model is holding.
A resource is application-controlled. It has a URI, it gets listed, and something outside the model, the client or the person using it, decides to attach it. The model doesn’t guess. The content is either in context or it isn’t.
Documentation is overwhelmingly the second kind. Your architecture decision record for the payments service isn’t an action anyone takes. It’s a document that is either relevant to this conversation or isn’t, and the person who knows which is the human who opened the conversation.
Why the tool version disappoints
Three failure modes, and they compound.
The model has to infer relevance from a tool description, which means the quality of your integration is capped by how well you can summarise your entire wiki in two sentences. That’s not a solvable writing problem. The description that says “search internal engineering documentation” gets called for questions about the standard library, and the one narrow enough to avoid that gets skipped when it was needed.
Retrieval quality becomes invisible. When a search tool returns the wrong three pages, the model works with the wrong three pages and produces something confidently derived from them. You see a fluent answer and no indication that the retrieval missed. With an attached resource, you can see exactly what’s in context, because you put it there.
And the token cost is unbounded and unpredictable. Search returns whatever it returns, on a trigger you don’t control, which is the specific combination that produces a surprising bill.
What the resource version needs from you
It isn’t free, and the work is mostly in one place: the URI scheme.
Resources get listed, and a listing of eleven thousand wiki pages is not usable by anyone, human or otherwise. So the design work is deciding what granularity is addressable. Per-page is usually too fine. Per-space is usually too coarse. The thing that has worked for me is exposing the stable, curated documents individually, the architecture records, the runbooks, the onboarding guides, and leaving the long tail behind a search tool for the cases where somebody genuinely needs to go hunting.
Which means the answer is generally both, with the split made deliberately rather than by default. Resources for the documents you’d hand a new colleague on day one. A tool for the archive.
The second piece of work is staleness, and MCP won’t help you. A resource that returns a runbook last edited in 2023 will be treated as current, because nothing in the protocol carries editorial confidence. If your wiki has a review date field, put it in the content itself rather than in metadata nobody reads. If it doesn’t have one, this integration will surface that fact quickly and somewhat painfully.
The access control question you have to answer first
Worth saying plainly, because it’s easy to defer and expensive to defer.
A wiki almost always has spaces that aren’t meant for everyone. HR material, security reviews, anything half-drafted about people. The moment it’s reachable through a server running with one service account, those permissions are gone, and the model will happily quote a compensation band into a conversation.
Whatever you build needs to carry the requesting user’s identity through to the wiki’s own access checks, or needs to expose an explicitly allowlisted subset and nothing else. The second option is uglier, faster, and the one I’d pick first, because an allowlist that’s too small produces a complaint and a permission leak produces an incident.
The part that actually changed my mind
I built the tool version first, like everyone does, and the thing that convinced me to switch wasn’t token cost or retrieval quality. It was watching people use it.
With a search tool, nobody knows what the model knows. Every answer arrives with an invisible provenance and the humans in the loop start either trusting everything or trusting nothing, and both are wrong. With attached resources, the person asking has already decided which three documents are in play, which means they can evaluate the answer against something specific.
That’s a smaller, less impressive claim than “give the model access to all your knowledge”. It’s also the version that people were still using six months later.
More field notes on MCP servers
This piece is one entry in a running series on how AI coding tools change day-to-day engineering work. For more practical notes on MCP specifically, browse the full set at /blog/tag/mcp/. For the wider view across every tool in the stack, the AI coding tag collects the whole archive in one place.
One email a month: the upcoming live event + free recording access for subscribers. No spam, unsubscribe anytime.