MCP server for SANS (Small-Angle Neutron Scattering) data analysis, powered by SANS-fitter.
| Tool | Description |
|---|---|
describe-possibilities |
Describe server capabilities |
list-sans-models |
List available sasmodels for fitting (e.g., cylinder, sphere, ellipsoid) |
get-model-parameters |
Get parameter specs for a model (value, min, max, vary, description) |
list-structure-factors |
List available structure factors for inter-particle interactions |
get-structure-factor-parameters |
Get parameters for a form_factor@structure_factor product model |
get-polydisperse-parameters |
Get parameters that support polydispersity for a model |
get-polydispersity-options |
Get available PD distribution types (gaussian, lognormal, etc.) and defaults |
list-uploaded-files |
List uploaded data files (optional: filter by extension, limit) |
list-analyses |
List available analysis types with parameters |
run-analysis |
Run analysis, returns fit results and plot |
- Discover models: Call
list-sans-modelsto see available sasmodels - Get parameters: Call
get-model-parameterswith model name to see default params - Find data: Call
list-uploaded-filesto find your CSV data file - Run fit: Call
run-analysiswith analysis name, input file, model, and param overrides
{
"name": "fitting-with-custom-model",
"parameters": {
"input_csv": "simulated_sans_data.csv",
"model": "cylinder",
"engine": "bumps",
"method": "amoeba",
"param_overrides": {
"radius": { "value": 20, "min": 1, "max": 200, "vary": true },
"length": { "value": 400, "min": 10, "max": 4000, "vary": true },
"scale": { "value": 1.0, "min": 0.0, "max": 10, "vary": true },
"background": { "value": 0.001, "min": 0, "max": 1, "vary": true }
}
}
}Use get-polydisperse-parameters to see which parameters support size distributions, then add a polydispersity config:
{
"name": "fitting-with-custom-model",
"parameters": {
"input_csv": "simulated_sans_data.csv",
"model": "cylinder",
"engine": "bumps",
"method": "amoeba",
"param_overrides": {
"radius": { "value": 20, "min": 1, "max": 200, "vary": true },
"length": { "value": 400, "min": 10, "max": 4000, "vary": true },
"scale": { "value": 1.0, "vary": true },
"background": { "value": 0.001, "vary": true }
},
"polydispersity": {
"radius": {
"pd_width": 0.1,
"pd_type": "gaussian",
"pd_n": 10,
"vary": false
}
}
}
}Polydispersity options:
pd_width: Relative width (0.1 = 10% polydispersity)pd_type: Distribution shape (gaussian,lognormal,schulz,rectangle,boltzmann)pd_n: Number of quadrature points (higher = more accurate, slower)pd_nsigma: Number of standard deviations to includevary: Whether to fit the pd_width during optimization
Structure factors model inter-particle interactions in concentrated systems. Use list-structure-factors to see available options:
hardsphere- Hard sphere (Percus-Yevick closure)hayter_msa- Hayter-Penfold MSA for charged spheressquarewell- Square well potentialstickyhardsphere- Sticky hard sphere (Baxter model)
{
"name": "fitting-with-custom-model",
"parameters": {
"input_csv": "simulated_sans_data.csv",
"model": "sphere",
"engine": "bumps",
"method": "amoeba",
"param_overrides": {
"radius": { "value": 50, "min": 10, "max": 100, "vary": true },
"scale": { "value": 0.01, "vary": true },
"background": { "value": 0.001, "vary": true }
},
"structure_factor": "hardsphere",
"structure_factor_params": {
"volfraction": { "value": 0.2, "min": 0.0, "max": 0.6, "vary": true },
"radius_effective": { "value": 50, "min": 10, "max": 100, "vary": true }
}
}
}Structure factor options:
structure_factor: Name of the structure factorstructure_factor_params: Parameter overrides (volfraction, radius_effective, charge for hayter_msa)radius_effective_mode:"unconstrained"(default) or"link_radius"to constrain radius_effective to equal the form factor radius
Set API_TOKEN environment variable to enable bearer token authentication:
API_TOKEN="your-secret-token" sans-pilotClients must include Authorization: Bearer <token> header. If API_TOKEN is not set, authentication is disabled.
Analyses are auto-discovered from src/sans_pilot/analyses/. Each analysis module exports:
ANALYSIS_DESCRIPTION— shown bylist-analysesrun(**parameters)— called byrun-analysis
| Variable | Default | Description |
|---|---|---|
UPLOAD_DIR |
/uploads |
Directory for uploaded data files |
SANS_PILOT_RUNS_DIR |
/tmp/sans-pilot-runs |
Output directory for analysis runs |
API_TOKEN |
(none) | Bearer token for API authentication |
cd sans-pilot
python -m venv .venv
source .venv/bin/activate
pip install -e .
sans-pilotdocker build -f Dockerfile.dev -t sans-pilot .
docker run -p 8001:8001 -e API_TOKEN="your-token" sans-pilotMount a local data file into /uploads:
docker run -p 8001:8001 \
-v /path/to/simulated_sans_data.csv:/uploads/simulated_sans_data.csv \
sans-pilotRun the test script to verify all MCP endpoints:
cd test
./test_endpoints.shThe script tests all tools against a running server at http://localhost:8001. Pass a different URL as argument if needed:
./test_endpoints.sh http://localhost:9000Future improvements planned:
- Run scripts in a separate container for security and isolation
- Add input parameter validation for all tools