Skip to main content
Lesson 11 of 12 · Remote MCP: Connect External Tools

Security and Best Practices

Lesson 11 of 12 Updated July 29, 2026 Developer
On this page
  1. What Connecting a Server Opens Up
  2. HTTPS and Authentication: The Non-Negotiable Foundation
  3. Allowlists as a Second Line of Defense
  4. Context Is a Finite Resource
  5. Descriptions That Improve Precision
  6. Key Takeaways

What Connecting a Server Opens Up

Connecting Grok to remote MCP servers gives the model the ability to act on your systems. This power comes with risks, and previous lessons introduced the parameters that control it. Now it’s time to organize them into a coherent security posture for production deployment.

HTTPS and Authentication: The Non-Negotiable Foundation

The rule is simple: every production MCP server must use HTTPS and require authentication. xAI already enforces the first point and rejects any plain HTTP URLs. The second, however, depends entirely on you, and that’s where errors creep in.

A server without authentication is accessible to anyone who knows the URL. This means anyone can call your internal tools, your data circulates without access control, and you have no way to trace who did what when an anomaly occurs. The URL isn’t a secret: it travels over networks, ends up in logs, and is guessable if it follows a convention.

# Production: ALWAYS with authentication
mcp(
    server_url="https://api.monentreprise.com/mcp",
    server_label="interne",
    authorization=f"Bearer {os.getenv('MCP_TOKEN')}"
)

# Development ONLY: without authentication
# NEVER deploy to production
mcp(
    server_url="https://mcp.deepwiki.com/mcp",
    server_label="deepwiki"
)

Token management follows four simple disciplines, but you must stick to them over time. Store tokens in environment variables, never in source code. Otherwise, your first public git push sends your token to the world. Rotate them periodically, at least every 90 days. A scheduled rotation turns a potential leak into a bounded exposure window. Generate them with the minimum permissions required, so a token stolen for a read-only agent is useless to anyone trying to write. If one is compromised, revoke it immediately before generating a new one. Order matters: a token revoked after the fact continues to work for the entire time you spend looking for its replacement.

Allowlists as a Second Line of Defense

A valid token proves the caller’s identity; it says nothing about what the caller should be able to do. This is where allowed_tool_names comes in. It applies the principle of least privilege by exposing only what’s strictly necessary to the model.

The specific restriction depends on the agent’s profile. A public chatbot sticks to read-only operations, with no write tools within reach.

allowed_tool_names=["search_docs", "get_article", "list_categories"]
# No access to: create_article, update_article, delete_article

An internal agent can afford more access, including commenting on a ticket, while keeping irreversible actions or actions visible to third parties out of reach.

allowed_tool_names=[
    "search_tickets", "get_ticket", "add_comment",
    # No access to: close_ticket, delete_ticket, reassign_ticket
]

Finally, an automated pipeline only needs the two tools its workflow chains together. There’s no justification for it to reconfigure anything.

allowed_tool_names=["run_analysis", "get_results"]
# No access to: configure_pipeline, delete_results

The scenario these lists protect you against is prompt injection. An analyzed document, a ticket, or an incoming email can contain an instruction intended for the model. Without restriction, this instruction can lead it to delete data via a delete_* tool, modify a setting via update_config, or issue unwanted communications via send_email. A tool that was never exposed cannot be hijacked. This is the only truly solid guarantee.

Context Is a Finite Resource

Each exposed tool consumes tokens in the context window, since its name, description, and parameter schema must reside there. A server publishing thirty tools can consume several thousand tokens before the user even asks a question.

The consequences show up in three ways: less space for the conversation itself, longer processing time due to the volume to analyze, and an increased risk of confusion when multiple tools look similar. Three practices address this. First, restrict with allowed_tool_names, which remains the most direct lever. Next, segment by use case rather than maintaining a single configuration. A customer support agent, an internal agent, and a pipeline have no reason to share the same catalog. Finally, reevaluate periodically. Check your traces to see which tools are actually called. You’ll often find several that have never been used yet cost context on every request.

Descriptions That Improve Precision

Careful descriptions at both the server and tool level measurably reduce erroneous calls. The contrast below illustrates the difference between a usable description and a useless one.

# Good: specific and actionable
server_description="Product knowledge base. Search help articles, FAQ, and troubleshooting guides for products A, B, and C."

# Bad: vague and generic
server_description="Database"

The system prompt is the final layer of this setup. It lets you express usage rules that configuration alone can’t enforce, such as a priority order between sources or a confirmation requirement.

When the user asks a technical question, search the internal knowledge base (kb) first.
If the answer is not found, use web search as a supplement.
Never modify a ticket without explicit user confirmation.

Keep in mind, however, that these guidelines orient the model’s behavior without constraining it. They complement the allowlist; they never replace it.

Key Takeaways

  • HTTPS is enforced by xAI, but authentication is your responsibility
  • Store tokens in environment variables and rotate them regularly
  • Use allowed_tool_names to apply the principle of least privilege
  • Monitor context load: every tool consumes tokens
  • Write precise descriptions to improve Grok’s tool selection