amselect-mcp
An MCP server for AirMettle Select. Ask Claude Code, Grok CLI, Codex CLI, Claude Desktop, Cursor, VS Code or any other MCP host to query CSV, JSON lines and Parquet data in your Azure Blob Storage with SQL, including gzip-compressed CSV and JSON lines, without moving or ingesting it.
Requires an active Azure AirMettle Select subscription.
amselect-mcpruns your queries through the AirMettle Select service, so set up your subscription first: it provides the endpoints and API key used below.
How It Works
Your MCP host starts amselect-mcp on your machine and talks to it over standard input and output. When the model decides to run a query, amselect-mcp sends the request to your AirMettle Select endpoints with your subscription credentials and hands the rows back to the model. Nothing else is installed or hosted.
MCP host (Claude Code, ...) ──stdio──► amselect-mcp ──HTTPS──► AirMettle Select
(on your machine) query + metadata services
Your subscription ID and API key stay in the host's configuration on your machine. The model never sees them: they are not tool arguments, and amselect-mcp removes the key from any error text it returns.
Before You Start
You need:
- An active Azure AirMettle Select subscription. It provides:
- your subscription ID and API key
- the query endpoint host
- the metadata service endpoint URL
- Data in an Azure storage account that is registered under your subscription.
- uv, or Python 3.10 or later with pip.
Setup
amselect-mcp is a Python package on PyPI. Your AI tool starts it on demand, so setup takes three steps: get the package, provide your AirMettle Select details, and register it with your tool.
1. Get the Package
| Option | Command | Notes |
|---|---|---|
| Run with uv (recommended) | uvx amselect-mcp |
uv fetches the package from PyPI and runs it on demand. |
| Install with pip | pip install amselect-mcp |
Python 3.10 or later. Use amselect-mcp wherever this guide says uvx amselect-mcp. |
2. Your AirMettle Select Details
| Variable | Value |
|---|---|
AMSELECT_HOST |
Query endpoint host |
AMSELECT_SUBSCRIPTION_ID |
Subscription ID |
AMSELECT_API_KEY |
Subscription API key |
AMSELECT_METADATA_ENDPOINT |
Metadata service URL, used by prepare |
3. Register It With Your AI Tool
Option A: Export Once in Your Shell
Set the values in the shell you start the AI tool from, then register the server with no credentials in the command. The tool passes your shell's environment on to amselect-mcp. Tested with Claude Code:
export AMSELECT_HOST="<query-host>"
export AMSELECT_METADATA_ENDPOINT="https://<metadata-endpoint>"
export AMSELECT_SUBSCRIPTION_ID="<subscription-id>"
export AMSELECT_API_KEY="<api-key>"
claude mcp add amselect -- uvx amselect-mcp
claude
Add the exports to ~/.bashrc or ~/.zshrc to have them in every new terminal. Desktop apps read their own configuration, so use Option B for them.
Option B: Save the Values With the Tool
Each tool keeps the values in its own configuration, so the server works from any terminal and in desktop apps.
Claude Code
claude mcp add amselect \
-e AMSELECT_HOST="<query-host>" \
-e AMSELECT_METADATA_ENDPOINT="https://<metadata-endpoint>" \
-e AMSELECT_SUBSCRIPTION_ID="<subscription-id>" \
-e AMSELECT_API_KEY="<api-key>" \
-- uvx amselect-mcp
Add --scope user to make it available in every project. Run /mcp inside Claude Code to check that the amselect server is connected.
To share the setup with a team through a project .mcp.json file, reference the credentials from each person's environment instead of writing them into the file:
{
"mcpServers": {
"amselect": {
"command": "uvx",
"args": ["amselect-mcp"],
"env": {
"AMSELECT_HOST": "<query-host>",
"AMSELECT_METADATA_ENDPOINT": "https://<metadata-endpoint>",
"AMSELECT_SUBSCRIPTION_ID": "${AMSELECT_SUBSCRIPTION_ID}",
"AMSELECT_API_KEY": "${AMSELECT_API_KEY}"
}
}
}
}
Grok CLI
grok mcp add amselect \
-e AMSELECT_HOST="<query-host>" \
-e AMSELECT_METADATA_ENDPOINT="https://<metadata-endpoint>" \
-e AMSELECT_SUBSCRIPTION_ID="<subscription-id>" \
-e AMSELECT_API_KEY="<api-key>" \
uvx amselect-mcp
Codex CLI
codex mcp add amselect \
--env AMSELECT_HOST="<query-host>" \
--env AMSELECT_METADATA_ENDPOINT="https://<metadata-endpoint>" \
--env AMSELECT_SUBSCRIPTION_ID="<subscription-id>" \
--env AMSELECT_API_KEY="<api-key>" \
-- uvx amselect-mcp
Claude Desktop and Cursor
Add the server to claude_desktop_config.json (Claude Desktop: Settings → Developer → Edit Config) or ~/.cursor/mcp.json (Cursor):
{
"mcpServers": {
"amselect": {
"command": "uvx",
"args": ["amselect-mcp"],
"env": {
"AMSELECT_HOST": "<query-host>",
"AMSELECT_METADATA_ENDPOINT": "https://<metadata-endpoint>",
"AMSELECT_SUBSCRIPTION_ID": "<subscription-id>",
"AMSELECT_API_KEY": "<api-key>"
}
}
}
}
Restart the app after editing the file. If it cannot find uvx, use the full path that which uvx prints.
VS Code
Add the server to .vscode/mcp.json. VS Code prompts for the API key the first time the server starts and keeps it in its secret storage rather than in the file:
{
"inputs": [
{
"type": "promptString",
"id": "amselect-api-key",
"description": "AirMettle Select API key",
"password": true
}
],
"servers": {
"amselect": {
"type": "stdio",
"command": "uvx",
"args": ["amselect-mcp"],
"env": {
"AMSELECT_HOST": "<query-host>",
"AMSELECT_METADATA_ENDPOINT": "https://<metadata-endpoint>",
"AMSELECT_SUBSCRIPTION_ID": "<subscription-id>",
"AMSELECT_API_KEY": "${input:amselect-api-key}"
}
}
}
}
Other Hosts
Any MCP host that can launch a local (stdio) server works: run the command uvx amselect-mcp with the variables from step 2.
Tools
query runs a SQL SELECT on one object and returns the rows. The table is always named Object (SELECT * FROM Object LIMIT 5). Supported objects are CSV, gzip-compressed CSV, JSON lines (one JSON record per line), gzip-compressed JSON lines, and Parquet. The format is inferred from the blob extension (.csv, .tsv, .jsonl, .ndjson, .json, .parquet, with .gz marking gzip compression) and can also be passed explicitly, together with CSV header and delimiter settings. Results come back as CSV or JSON lines.
prepare generates the query metadata an object needs. Run it once per object, and again with overwrite after the object's contents change. It waits up to a minute by default; if the prepare is still running after that, calling it again reports whether the object is ready.
export runs a query like query but saves the complete result to a file on your machine instead of returning it to the model, for when you want every row. Files are created in the export directory (AMSELECT_EXPORT_DIR, default ~/amselect-exports) under the name the model picks; existing files are never overwritten, and names that point outside the directory are rejected. The model gets back the file path, the row count and a short preview.
Result Size
Query results returned to the model are capped at 64 KiB by default (see AMSELECT_MAX_RESULT_BYTES). Longer output is cut at the last whole record and marked as truncated. A truncated query still runs to completion on the service, so ask for LIMIT, filters and aggregates (COUNT, SUM, GROUP BY) rather than whole objects. To keep a full result, ask for an export: it goes to a file rather than into the conversation (up to 2 GiB by default, see AMSELECT_MAX_EXPORT_BYTES).
Troubleshooting
| Symptom | What to check |
|---|---|
| The server does not start or shows as failed | A required variable is missing or invalid; the host's MCP log shows a line such as amselect-mcp: AMSELECT_HOST is required. Check that uvx is on the host's PATH. |
| "AMSelect rejected the credentials (HTTP 401)" | AMSELECT_SUBSCRIPTION_ID and AMSELECT_API_KEY |
| "Object is not prepared for querying" | Prepare the object first (the model normally does this itself) |
| "prepare is not configured" | Set AMSELECT_METADATA_ENDPOINT |
| HTTP 403 or 404 | The storage account must be registered under your subscription, and the subscription must be active |
| "Could not reach the AMSelect query endpoint" | AMSELECT_HOST, AMSELECT_PORT and your network or proxy settings |
License
MIT — see the LICENSE file. Use of the AirMettle Select service itself is governed by your service agreement.
Release files for amselect-mcp 1.2.7
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| amselect_mcp-1.2.7.tar.gz | 14.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| amselect_mcp-1.2.7-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 31.8 kB
Release files / amselect_mcp-1.2.7.tar.gz
| Download URL | amselect_mcp-1.2.7.tar.gz |
|---|---|
| Size | 14.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
730586777259c08cf6f9a95a61647ab4a518ee1a2814a759c13274b6e7880ae6
|
|
BLAKE2b-256 checksum How to use checksums |
6e0715374f782f28a9b6b30f7156ac7bee3e16844299a77df11c132418359a6b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / amselect_mcp-1.2.7-py3-none-any.whl
| Download URL | amselect_mcp-1.2.7-py3-none-any.whl |
|---|---|
| Size | 17.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
66b38e863086ee3bc0f687eb7c31d18b1334eca3d2533259fe798ebfb8b8019a
|
|
BLAKE2b-256 checksum How to use checksums |
2bd6fb6f185a333a95d865f79f081557d7d0d1b0851ff6981c0e8601de3bfce1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|