MCP servers

Enhanced Advanced

Model Context Protocol (MCP) is an open standard that connects AI applications to external tools, data sources, and services. MCP servers expose “tools” that AI clients can discover and invoke.

You can deploy MCP servers to Posit Connect so that AI clients across your organization can access shared tools and resources.

When to deploy MCP servers to Connect

Deploy MCP servers to Connect when you want to:

  • Access shared resources: Provide access to resources only available on the Connect server, such as files on a shared file system or internal databases.
  • Proxy third-party services: Securely proxy access to external APIs and manage credentials centrally. This pairs well with OAuth integrations, which allow your MCP server to obtain short-lived access tokens for third-party services on behalf of users.
  • Sandbox execution: Run MCP tools in a controlled, sandboxed environment.
  • Enable discoverability: Let team members discover and connect to shared MCP tools through the content management features in Connect.
  • Centralize management: Manage MCP server deployments, updates, and scaling from a central location. Some organizations have policies that restrict MCP servers from untrusted sources because they can execute code on users’ machines when run locally. A deployment on Connect allows IT teams to vet and control MCP server deployments.

If your security policies allow it, you may prefer to run MCP servers locally when you want:

  • Local file access: Your tools need to read or write files on the user’s local machine.
  • Low latency: You need minimal response times for tool invocations.
  • Simplicity: You have a simple setup that doesn’t require shared access or centralized management.

Connect to an MCP server

To use an MCP server deployed on Connect, you need:

  1. The content URL for your deployed MCP server. This is the standalone URL that points to the MCP server, not the URL that views it inside the Connect UI. It is common for MCP servers to mount their endpoints under a /mcp path. So if your Connect content URL is https://connect.example.com/content/abc123/, the MCP server URL would likely be https://connect.example.com/content/abc123/mcp.
  2. A Connect API key. See the API key user guide for instructions on how to generate API keys.

Client configuration

You need to provide your AI application with the MCP server URL and authentication details. Most MCP clients accept a configuration that specifies server endpoints. For an MCP server on Connect, configure the URL and authentication headers:

mcp_config.json
{
  "mcpServers": {
    "my-connect-server": {
      "url": "https://connect.example.com/content/abc123/mcp",
      "headers": {
        "Authorization": "Key YOUR_CONNECT_API_KEY"
      }
    }
  }
}

Replace https://connect.example.com/content/abc123/mcp with the actual URL of your server and YOUR_CONNECT_API_KEY with a valid Connect API key.

The exact configuration format varies by client. Consult the documentation for your MCP client for the specific configuration syntax.

Adapting an MCP server for Connect

If you have an MCP server that runs locally, you may need to make adjustments before deploying to Connect.

Use Python instead of JavaScript

Connect supports deploying Python and R applications. If your MCP server is written in JavaScript or TypeScript, consider rewriting it in Python using FastMCP or the MCP Python SDK.

FastMCP provides a high-level interface to build MCP servers:

server.py
from fastmcp import FastMCP

mcp = FastMCP("My MCP Server")

@mcp.tool()
def greet(name: str) -> str:
    """Greet someone by name."""
    return f"Hello, {name}!"

Use streamable HTTP in stateless mode

When running on Connect, configure your MCP server to use Streamable HTTP, rather than the legacy Server-Sent Events (SSE) transport, which has been deprecated in the MCP standard. Additionally, configure your server to use stateless HTTP mode. Without this configuration, Streamable HTTP can still use Server-Sent Events internally for streaming responses.

Stateless HTTP mode ensures that each request is independent and does not rely on session state stored on the server. On high-availability Connect deployments with load balancers, SSE would require additional sticky session configuration beyond what Connect recommends. Not only does stateless mode follow the MCP standard more closely, it also simplifies deployment and scaling.

Specify the entrypoint

To deploy to Connect, you must specify the correct entrypoint so Connect can locate your MCP server object. See the documentation on entrypoints for details.

This may not be the same as how the server is started locally. For example, Python MCP servers often use an if __name__ == "__main__" block to launch the server when run directly. However, Connect needs to import the server object from the module instead of executing code that starts a server. You may need to refactor your code to define the server object outside of the __main__ block.

For a FastMCP server in a file named server.py with the server object named mcp, the entrypoint would be server:mcp.

Configure transport security

When running behind the Connect proxy, your MCP server must allow connections from the Connect server. This requires transport security settings that permit the Connect server hostname.

Here’s a complete configuration example, including both transport security and stateless HTTP mode, and returning the server object named mcp, suitable for referencing as the entrypoint:

server.py
import os
from urllib.parse import urlparse
from fastmcp import FastMCP
from mcp.server.lowlevel.server import TransportSecuritySettings

def get_transport_security():
    """Configure transport security based on environment."""
    connect_server = os.environ.get("CONNECT_SERVER", "")
    if connect_server:
        # Extract host from Connect server URL
        parsed = urlparse(connect_server)
        host = parsed.netloc or parsed.path
        host = host.rstrip("/")
        if host:
            # Include both bare host and port wildcard
            allowed_hosts = [host, f"{host}:*"]
            return TransportSecuritySettings(
                enable_dns_rebinding_protection=True,
                allowed_hosts=allowed_hosts,
            )
    # Default: let FastMCP auto-configure based on host
    return None

mcp = FastMCP(
    "My MCP Server",
    transport_security=get_transport_security(),
    stateless_http=True,
    json_response=True,
)

When running locally, transport_security is None and FastMCP uses its default behavior. When running on Connect, it restricts connections to the Connect server hostname.

Implement file system tools for remote access

MCP servers running on Connect do not have access to the end user’s local file system. If your MCP server needs to work with files, you’ll need to implement tools that provide file access through the server.

Common scenarios where this applies:

  • Expose shared storage: Your MCP server provides access to files on the Connect shared file system or network storage that users cannot access directly.
  • Proxy external files: Your MCP server downloads files from cloud storage, APIs, or other services on behalf of the user.

In these cases, implement tools that mirror standard file operations: reading files, listing directories, searching file contents, and similar operations. These tools let AI clients interact with the remote file system through your MCP server, similar to how local MCP servers provide access to the user’s local files.

Deploying

To deploy your MCP server using rsconnect-python, use the fastapi mode, and specify the entrypoint for your MCP server:

Terminal
rsconnect deploy fastapi \
    -n <saved server name> \
    --entrypoint server:mcp \
    ./

Or use the Posit Publisher extension for VS Code or Positron to deploy directly from your editor. Use the python-fastapi project type and specify the entrypoint in the TOML file if it is not automatically detected.

Ensure your requirements.txt includes the necessary Python dependencies. If you’re using pyproject.toml or another file for dependency management, you can generate requirements.txt with uv pip compile or similar tools.

After deploying, for best performance you can set the minimum number of processes to 1 or higher in the runtime settings. This ensures the MCP server is always available for clients to connect, avoiding cold start delays when all processes have been shut down due to inactivity.

Wrap existing REST APIs

If you already have REST APIs on Connect and want to expose them via MCP without a dedicated MCP server, you can use tools like the FastMCP OpenAPI integration to automatically generate MCP tools from an OpenAPI specification. You could run such a wrapper as a local MCP server or deploy it to Connect.

However, be aware that automatic REST API wrappers have limitations. Design principles that make for good REST APIs do not always align with those for effective MCP tools. See this discussion for considerations when you decide between native MCP implementations and API wrappers.