This package provides a Python implementation of the Model Context Protocol (MCP) server for Apache Polaris. It wraps the Polaris REST APIs so MCP-compatible clients (IDEs, agents, chat applications) can issue structured requests via JSON-RPC on stdin/stdout.
The implementation is built on top of FastMCP for streamlined server registration and transport handling.
Run the following commands from the mcp-server directory:
uv sync - install runtime dependenciesuv run polaris-mcp - start the MCP server (stdin/stdout transport)uv sync --extra test --extra dev - install runtime, test and dev dependenciesuv run pytest - run the test suiteuv run pre-commit run --all-files - lint all filesuv build && uv publish --index testpypi --token [Pypi-API-token] - Publish a nightly to test.pypi.orguv build && uv publish --index pypi --token [Pypi-API-token] - Publish a formal binary release to pypi.orgFor a tools/call invocation you will typically set environment variables such as POLARIS_BASE_URL and authentication settings before launching the server. A default .polaris_mcp.env file is included on the tool root directory, and any of the configuration variables can be specified in this file. After adding configuration variables to the .polaris_mcp.env file, explicitly setting these is no longer needed. However, shell environment variables will always take precedence if provided.
{ "mcpServers": { "polaris": { "command": "uv", "args": [ "--directory", "/path/to/polaris-tools/mcp-server", "run", "polaris-mcp" ], "env": { "POLARIS_CONFIG_FILE": "/path/to/polaris-tools/mcp-server/.polaris_mcp.env" } } } }
Please note: --directory specifies a local directory. It is not needed when we pull polaris-mcp from PyPI package.
For quick local testing without configuring a full client like Claude Desktop, you can use the included client.py script.
# Start client in interactative mode with STDIO transport uv run int_test/client.py polaris_mcp/server.py
You can also run client directly from the command line with non-interactive mode:
uv run int_test/client.py http://localhost:8000/mcp --tool polaris-catalog-request --args '{"operation": "list"}'
Here are sample client commands:
# Create catalog uv run int_test/client.py polaris_mcp/server.py \ --tool polaris-catalog-request \ --args '{ "operation": "create", "body": { "catalog": { "name": "quickstart_catalog", "type": "INTERNAL", "readOnly": false, "properties": { "default-base-location": "s3://bucket123" }, "storageConfigInfo": { "storageType": "S3", "allowedLocations": ["s3://bucket123"], "endpoint": "http://localhost:9000", "pathStyleAccess": true } } } }' # List catalog uv run int_test/client.py polaris_mcp/server.py \ --tool polaris-catalog-request \ --args '{"operation": "list"}' # List catalog in realm "POLARIS" uv run int_test/client.py polaris_mcp/server.py \ --tool polaris-catalog-request \ --args '{"operation": "list", "realm": "POLARIS"}' # Create principal uv run int_test/client.py polaris_mcp/server.py \ --tool polaris-principal-request \ --args '{ "operation": "create", "body": { "principal": { "name": "quickstart_user", "properties": {} } } }' # Create principal role uv run int_test/client.py polaris_mcp/server.py \ --tool polaris-principal-role-request \ --args '{ "operation": "create", "body": { "principalRole": { "name": "quickstart_user_role", "properties": {} } } }' # Assign principal role uv run int_test/client.py polaris_mcp/server.py \ --tool polaris-principal-request \ --args '{ "operation": "assign-principal-role", "principal": "quickstart_user", "body": { "principalRole": { "name": "quickstart_user_role" } } }'
| Variable | Description | Default |
|---|---|---|
POLARIS_BASE_URL | Base URL for all Polaris REST calls. | http://localhost:8181/ |
POLARIS_API_TOKEN / POLARIS_BEARER_TOKEN / POLARIS_TOKEN | Static bearer token (if supplied, overrides other auth). | unset |
POLARIS_CLIENT_ID | OAuth client id for client-credential flow. | unset |
POLARIS_CLIENT_SECRET | OAuth client secret. | unset |
POLARIS_TOKEN_SCOPE | OAuth scope string. | unset |
POLARIS_TOKEN_URL | Optional override for the token endpoint URL. | ${POLARIS_BASE_URL}api/catalog/v1/oauth/tokens |
POLARIS_REALM_{realm}_CLIENT_ID | OAuth client id for a specific realm. | unset |
POLARIS_REALM_{realm}_CLIENT_SECRET | OAuth client secret for a specific realm. | unset |
POLARIS_REALM_{realm}_TOKEN_SCOPE | OAuth scope for a specific realm. | unset |
POLARIS_REALM_{realm}_TOKEN_URL | Token endpoint URL for a specific realm. | unset |
POLARIS_REALM_CONTEXT_HEADER_NAME | Header name used for realm context. | Polaris-Realm |
POLARIS_TOKEN_REFRESH_BUFFER_SECONDS | Minimum remaining token lifetime before refreshing in seconds. | 60.0 |
POLARIS_HTTP_TIMEOUT_SECONDS | Default timeout in seconds for all HTTP requests. | 30.0 |
POLARIS_HTTP_CONNECT_TIMEOUT_SECONDS | Timeout in seconds for establishing HTTP connections. | 30.0 |
POLARIS_HTTP_READ_TIMEOUT_SECONDS | Timeout in seconds for reading HTTP responses. | 30.0 |
POLARIS_HTTP_RETRIES_TOTAL | Total number of retries for HTTP requests. | 3 |
POLARIS_HTTP_RETRIES_BACKOFF_FACTOR | Factor for exponential backoff between retries. | 0.5 |
POLARIS_CONFIG_FILE | Path to a configuration file containing configuration variables. | .polaris_mcp.env in current working directory |
When OAuth variables are supplied, the server automatically acquires and refreshes tokens using the client credentials flow; otherwise a static bearer token is used if provided. Realm-specific variables (e.g., POLARIS_REALM_${realm}_CLIENT_ID) override the global settings for a given realm for client ID, client secret, token scope, and token URL. If realm-specific credentials are provided but incomplete, the server will not fall back to global credentials for that realm.
The server exposes the following MCP tools:
polaris-iceberg-table — Table operations (list, get, create, update, delete).polaris-namespace-request — Namespace lifecycle management.polaris-policy — Policy lifecycle management and mappings.polaris-catalog-request — Catalog lifecycle management.polaris-principal-request — Principal lifecycle helpers.polaris-principal-role-request — Principal role lifecycle and catalog-role assignments.polaris-catalog-role-request — Catalog role and grant management.Each tool returns both a human-readable transcript of the HTTP exchange and structured metadata under result.meta.