> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mindset.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Server Architecture Best Practices

> How to organize your MCP servers for clean entitlement, better security, and a smoother agent experience.

A common question when scaling MCP integrations is how to organize your tools into MCP servers. Should you create one MCP server per backend API? One per use case? Something else entirely?

The answer comes down to understanding **entitlement** and **defense in depth**.

## MCP Servers as Units of Entitlement

In the Mindset AI platform, you can't entitle an agent to individual tools. You entitle an agent (or agent session) to an MCP server, and that agent then has access to **all tools** on that server.

This is analogous to how knowledge contexts work: you entitle an agent to a context, not to individual pieces of content within that context.

This architectural constraint should drive how you organize your MCP servers.

## Organize by Entitlement, Not by API

The primary recommendation is to split your MCP servers based on who should have access to the tools.

**The question to ask for every tool you build:** *Which users should be able to use this?*

Group tools together when they share the same answer.

### Example: admin vs. regular user tools

<Warning>
  Don't create a single MCP server containing both user-facing tools (`get_my_profile`, `update_my_settings`) and admin tools (`delete_user`, `create_user`, `modify_user_permissions`). If a regular user's agent session includes this server, they'll see `delete_user` as an available tool — even though they can't use it.
</Warning>

**Do this instead:**

<CardGroup cols={2}>
  <Card title="User Profile MCP Server" icon="user">
    Entitled to all users.

    `get_my_profile`, `update_my_settings`, `get_my_notifications`
  </Card>

  <Card title="User Admin MCP Server" icon="shield">
    Entitled to admins only.

    `delete_user`, `create_user`, `modify_user_permissions`, `list_all_users`
  </Card>
</CardGroup>

Regular users never see admin tools. Admins get both MCP servers entitled to their sessions.

## Why Visibility Matters — Not Just Authorization

You might think: "Our tools already check permissions using the `x-user-id` header. Why does visibility matter?"

Two reasons.

### User experience

Users don't directly see a list of available tools, but they can ask the agent — and the agent will tell them. If the agent has access to a `delete_user` tool, it will mention this capability when asked "What can you do?"

The user might then ask the agent to delete someone. The agent will attempt it, fail, and return a permission error. That's a poor experience. Users shouldn't be told about capabilities they can't actually use.

### LLMs can't keep secrets

You can't rely on system prompts or instructions to hide tools from users.

<Warning>
  This will not work:

  ```text theme={null}
  System prompt: "Never show the delete_user tool to non-admin users"
  ```

  LLMs aren't reliable gatekeepers. Given enough interaction, creative prompting, or edge cases, the LLM may eventually expose or attempt to use restricted tools. **LLM-level instructions are not a security mechanism.**
</Warning>

## Defense in Depth: The Complete Authorization Model

Best practice is a layered approach.

<CardGroup cols={2}>
  <Card title="Layer 1: MCP Server Entitlement" icon="eye">
    **Visibility control**

    Controls which tools a user can see. Configured when creating agent sessions. Prevents poor UX from exposing unavailable tools.
  </Card>

  <Card title="Layer 2: Tool-Level Authorization" icon="lock">
    **Access control**

    Controls which tools a user can execute. Implemented in each tool using the `x-user-id` header. The final, authoritative security check.
  </Card>
</CardGroup>

<Note>
  Layer 1 is for UX. Layer 2 is for security. Even with perfect MCP server entitlement management, you must still implement authorization checks in your tools. The tool is the final authority on whether an action is permitted.

  For mission-critical operations — data deletion, permission modifications — tool-level authorization is non-negotiable.
</Note>

## Tool Naming: Maintain Semantic Distance

When an agent has access to multiple MCP servers, all tools from all servers appear in the agent's tool inventory. This creates a potential problem: **tool name collisions and semantic confusion**.

### The problem

If two MCP servers both have a tool called `add_user` — one in an HR System MCP (described as "Add user to HR system") and another in a Training System MCP (described as "Add user to course") — the LLM uses both the tool name and description to select the right tool. With two identically-named tools, this breaks down.

Users occasionally give explicit instructions like "use the add user tool to enrol them in the course." With two identically-named tools, the LLM can't reliably determine which one the user means. This leads to incorrect tool selection, unpredictable behaviour, and user frustration.

### The solution

Give tools names that are **descriptive and unambiguous**.

| Instead of...                    | Use...                   |
| -------------------------------- | ------------------------ |
| `add_user` (HR System MCP)       | `create_employee_record` |
| `add_user` (Training System MCP) | `enroll_user_in_course`  |

**Naming guidelines:**

* Be specific: `get_user_enrolled_courses` not `get_courses`
* Include the domain: `create_employee_record` not `create_record`
* Describe the action clearly: `enroll_user_in_course` not `add_user`
* Avoid generic verbs alone: `search_training_catalog` not `search`

When planning multiple MCP servers, coordinate tool naming across teams to prevent collisions.

### Tool descriptions matter just as much

The tool description is what the LLM primarily uses to decide when to call your tool. A poor description leads to tools being called at the wrong time — or not at all.

Write descriptions that explain what the tool does, when it should be used, and who it's for.

<CodeGroup>
  ```text Poor description theme={null}
  "Add user"
  ```

  ```text Good description theme={null}
  "Enroll a user in a training course. Use when a manager
  needs to assign required training to an employee."
  ```
</CodeGroup>

### Help the LLM get it right

Beyond the basic description, include parameter guidance directly in the tool description — especially for tools with multiple parameters:

* **Date formats**: specify expected formats (e.g. "date must be YYYY-MM-DD")
* **Categorical values**: if a parameter accepts a small set of values, list them (e.g. "status must be one of: pending, approved, rejected")

This upfront guidance reduces failed calls and retries.

### Write error messages that guide, not just fail

When a tool is called with invalid parameters, the error message should help the LLM succeed on the next attempt.

<CodeGroup>
  ```text Poor error message theme={null}
  "Invalid"
  ```

  ```text Good error message theme={null}
  "Invalid status value. Status should be one of 'pending', 'in progress', 'done', 'failed'"
  ```
</CodeGroup>

A helpful error message enables the agent to self-correct rather than fail repeatedly or give up.

## Per-API vs. Per-Use-Case Organization

<AccordionGroup>
  <Accordion title="Per-API organization">
    Example: "Learning API MCP", "Competency API MCP", "Scheduling API MCP"

    **Pros:**

    * Maps cleanly to existing backend architecture
    * Easy to maintain by API team ownership
    * Clear boundaries

    **Cons:**

    * Doesn't align with user entitlement boundaries
    * May expose tools users don't need
    * Cross-cutting use cases require multiple MCP servers
  </Accordion>

  <Accordion title="Per-use-case organization">
    Example: "Preceptor Selection MCP" that bundles tools from Learning, Competency, and Scheduling APIs.

    **Pros:**

    * Aligned with user workflows
    * Tools grouped by who needs them
    * Cleaner entitlement model

    **Cons:**

    * May require coordination across API teams
    * Potential for tool duplication if not careful
  </Accordion>
</AccordionGroup>

**Neither pure per-API nor pure per-use-case is the right answer. Organize by entitlement boundaries.**

If your Learning API has both student tools and instructor tools, split them:

* **Student Learning MCP**: `get_my_courses`, `submit_assignment`, `view_my_grades`
* **Instructor Learning MCP**: `grade_assignment`, `view_class_roster`, `create_announcement`

If a use case like "Preceptor Selection" requires tools that only preceptor coordinators should access, create a dedicated MCP server for that role — even if the underlying tools call multiple backend APIs.

## Decision Framework

Use this process when designing your MCP server architecture.

<Steps>
  <Step title="List all tools">
    Document every tool you need to build.
  </Step>

  <Step title="Identify user roles">
    Who are the distinct user types? (e.g. students, instructors, admins, coordinators)
  </Step>

  <Step title="Map tools to roles">
    For each tool, which roles should have access?
  </Step>

  <Step title="Group by entitlement">
    Tools that share the same role entitlement go in the same MCP server.
  </Step>

  <Step title="Check for naming conflicts">
    Make sure tools across all MCP servers have semantically distinct names.
  </Step>

  <Step title="Implement tool-level authorization">
    Regardless of MCP server organization, implement authorization checks in every tool.
  </Step>
</Steps>

## Summary

| Principle               | Guidance                                                    |
| ----------------------- | ----------------------------------------------------------- |
| Unit of entitlement     | You entitle agents to MCP servers, not individual tools     |
| Organize by access      | Group tools by which users should see them                  |
| Defense in depth        | MCP entitlement for UX, tool-level auth for security        |
| LLMs can't keep secrets | Never rely on prompts to hide tools                         |
| Semantic distance       | Give tools unique, descriptive names across all MCP servers |
| Final authority         | The tool implementation is the authoritative security check |

***
