Skip to main content
Glama
ET-MCP

ET-MCP

by ConTresillo

ET-MCP — EarthTekniks MCP Servers (standalone)

Python MCP servers for EarthTekniks — 17 tools across 3 domain servers. No frontend, no auth, no LLM needed. Just tools.

LLM / Inspector / Claude Desktop → MCP (stdio or HTTP) → tools → answer

What's inside

Server

Command

Tools

What it does

calc / calculator

--server calc

6

11 optics calculators (FOV, working distance, DOF, exposure, focal length, line-scan, etc.) + reference tables (sensor sizes, f-stops, pixel formats)

site

--server site

2

Company / project / vision KB — BM25+grep search over 25 docs, no DB needed

catalog

--server catalog

9

Lens catalog — Supabase Postgres (read-only) + safe SQL, schema-aware search

all

--server all

17

All 3 servers in one process

src/et_mcp/
├── server.py              # FastMCP entry: --server calc|site|catalog|all, --transport stdio|streamable-http
├── settings.py            # env-only config (pydantic-settings, no hardcoding)
├── retrieval/             # shared hybrid retrieval (Qdrant + BM25, optional)
├── services/
│   ├── calc/              # pure math + knowledge docs + BM25 index
│   ├── catalog/           # DB (psycopg2, read-only, timeout + row cap) + SQL validator (sqlglot)
│   └── site/              # KB chunker + BM25 index
└── tools/                 # thin MCP adapters — no business logic

Related MCP server: Works With Agents MCP Server

Requirements

  • Python 3.12+

  • SUPABASE_DB_URL — only for catalog tools (read-only Postgres). site + calc work without it.

  • Internet on first run — downloads BAAI/bge-small-en-v1.5 (~40MB, via fastembed) for optional vector stages. Falls back to BM25 if offline.

Quickstart

# 1. install
pip install -e .

# 2. env - copy and fill DB URL (catalog only)
cp .env.example .env
# edit .env: set SUPABASE_DB_URL=postgresql://user:pass@host:5432/db

# 3. run - pick one
python -m et_mcp.server --server all --transport stdio                          # for Claude Desktop / Inspector stdio
python -m et_mcp.server --server catalog --transport streamable-http --port 8001  # HTTP
python -m et_mcp.server --server site    --transport streamable-http --port 8002
python -m et_mcp.server --server calc    --transport streamable-http --port 8003
python -m et_mcp.server --server all     --transport streamable-http --port 8001  # all 17 tools on one port

Verify HTTP: curl http://127.0.0.1:8001/mcp should return 200 / SSE stream.

Docker

cp .env.example .env  # set SUPABASE_DB_URL
docker build -f Dockerfile.mcp -t et-mcp .
docker run --env-file .env -p 8001:8001 et-mcp python -m et_mcp.server --server all --transport streamable-http --port 8001 --host 0.0.0.0

Dockerfile.mcp is standalone — no chatbot, no Node.

MCP clients

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "et-mcp": {
      "command": "python",
      "args": ["-m", "et_mcp.server", "--server", "all"],
      "cwd": "C:\\path\\to\\ETGPT"
    }
  }
}

Or split (3 servers, uses same .venv):

{
  "mcpServers": {
    "et-mcp-calc":    { "command": "python", "args": ["-m","et_mcp.server","--server","calc"], "cwd": "C:\\path\\to\\ETGPT" },
    "et-mcp-site":    { "command": "python", "args": ["-m","et_mcp.server","--server","site"], "cwd": "C:\\path\\to\\ETGPT" },
    "et-mcp-catalog": { "command": "python", "args": ["-m","et_mcp.server","--server","catalog"], "cwd": "C:\\path\\to\\ETGPT" }
  }
}

Use absolute cwd or absolute command (C:\path\to\.venv\Scripts\python.exe) if Claude can't find python.

Inspector

npx -y @modelcontextprotocol/inspector -- python -m et_mcp.server --server all
# or HTTP: python -m et_mcp.server --server all --transport streamable-http --port 8001
# then open http://127.0.0.1:6274, connect to http://127.0.0.1:8001/mcp

Tools reference

calc (6) — search_calculator → get_calculator → calculate is the main flow; search_lookups → get_reference → lookup for reference tables.

Tool

Purpose

search_calculator

Find calculators for NL query

get_calculator

Inputs / gotchas / related for a formula_id

calculate

Run a calculator (formula_id + args dict)

search_lookups

Find reference tables

get_reference

Schema for a reference table

lookup

Single value lookup from reference table

site (2)

Tool

Purpose

search_knowledge_base

BM25+grep over 25 docs, returns confident flag — don't answer from memory if false

get_document

Full doc by doc_id

catalog (9)

Tool

Purpose

list_families

Lens families

list_tables

Tables, optional family filter

describe_table

Columns, purpose, signature columns — call before run_select

search_knowledge

Which table/family fits an NL use-case

get_table_knowledge

Full doc for a table: column meanings, NL→SQL examples, gotchas

lookup_model

Which table/family a model belongs to

get_product

Full row(s) for a model name

search_products

Filtered search (table/family/filters/columns/sort/limit)

run_select

Escape hatch: validated read-only SELECT (sqlglot, single statement, timeout 8s, 500 rows)

Smoke tests

No LLM needed — all direct Python / curl.

# 0. import check (no DB needed)
python -c "from et_mcp.tools.registry import TOOLSETS; print({k: len(v) for k,v in TOOLSETS.items()})"
# expect: {'calc': 6, 'site': 2, 'catalog': 9}

# 1. calc — BM25 + math (no DB)
python -c "
from et_mcp.services.calc.retrieval import search
from et_mcp.services.calc.dispatch import DISPATCH
from et_mcp.tools.calc import calculate
print(search('field of view for 12mm lens at 500mm', top_k=3))
# pick a formula_id from above, e.g. fov_using_sensor_size
print(calculate('fov_using_sensor_size', {'sensor_size_mm': 8.8, 'working_distance_mm': 500, 'focal_length_mm': 12}))
"

# 2. site — BM25+grep (no DB)
python -c "
from et_mcp.tools.site import search_knowledge_base, get_document
print(search_knowledge_base('garuda inspection system', top_k=3))
print(get_document('company_overview')['title'])
"

# 3. catalog — needs SUPABASE_DB_URL in .env (read-only)
python -c "
from et_mcp.tools.catalog import list_families, list_tables, describe_table
print(list_families())
print(list_tables('line_scan'))
print(describe_table('line_scan_lens_8k5u'))
"
python -c "
from et_mcp.tools.catalog import search_knowledge, get_table_knowledge
print(search_knowledge('lens for conveyor belt inspection', top_k=3))
print(get_table_knowledge('line_scan_lens_8k5u')['purpose'][:200])
"
python -c "
from et_mcp.tools.catalog import search_products, run_select
print(search_products(table='line_scan_lens_8k5u', filters=[{'column':'focal_length_mm','op':'=','value':12}], limit=2))
print(run_select('SELECT model_name, focal_length_mm FROM line_scan_lens_8k5u LIMIT 2'))
"

# 4. MCP stdio smoke (spawns server, lists tools, exits)
python -c "
import asyncio, sys
from mcp.client.stdio import stdio_client
from mcp import StdioServerParameters
async def main():
    params = StdioServerParameters(command=sys.executable, args=['-m','et_mcp.server','--server','all'])
    async with stdio_client(params) as (read, write):
        from mcp.client.session import ClientSession
        async with ClientSession(read, write) as s:
            await s.initialize()
            tools = await s.list_tools()
            print([t.name for t in tools.tools])
asyncio.run(main())
"
# expect 17 tool names

# 5. HTTP smoke (needs server running in another terminal)
# terminal A: python -m et_mcp.server --server all --transport streamable-http --port 8001
# terminal B:
curl http://127.0.0.1:8001/mcp -H "Accept: text/event-stream"

If catalog tests return hint: check SUPABASE_DB_URL — set it in .env. Site/calc failures without DB are bugs.

Environment

All via .env (see .env.example). No os.environ[...] elsewhere, no hardcoding.

Var

Required

Default

Used for

SUPABASE_DB_URL

catalog only

—

psycopg2 read-only pool

QDRANT_URL

no

.qdrant_storage

local dir auto-created

EMBEDDING_MODEL_NAME

no

BAAI/bge-small-en-v1.5

vector stages (optional)

DB_STATEMENT_TIMEOUT_MS

no

8000

per-query timeout

DB_ROW_LIMIT

no

500

max rows per query

SITE_MIN_CONFIDENCE

no

0.35

site confidence gate

DISABLE_SITE_VECTOR

no

true

site = BM25+grep only

Troubleshooting

  • Catalog DB unavailable — check SUPABASE_DB_URL — set URL in .env (format postgresql://user:pass@host:5432/postgres). Site/calc still work.

  • mcp not installed. Run: pip install -e . — pip install -e . from repo root (Python 3.12+).

  • Model not found / fastembed download failed — first run needs internet; falls back to BM25 if offline. Re-run with internet to cache.

  • ModuleNotFoundError: et_mcp — pip install -e . or PYTHONPATH=src.

  • address already in use :8001 — another MCP server on port; use --port 8002.

Available Tools

17 tools
calculateB

Execute a calculator. Flow: search_calculator → get_calculator → calculate.

Inputs: args (required), formula_id (required).

describe_tableA

Describe a table: columns, purpose, signature columns. Call before run_select.

Inputs: table (required).

get_calculatorA

Get inputs, gotchas, related calculators for a formula_id. Call after search_calculator.

Inputs: formula_id (required).

get_documentA

Read full text of a KB document by doc_id.

Inputs: doc_id (required).

get_productB

Get full spec row(s) for a lens model.

Inputs: model_name (required).

get_referenceA

Get a lookup table's purpose, keys, notes. Call after search_lookups.

Inputs: table_id (required).

get_table_knowledgeB

Full knowledge for a table: purpose, column meanings, NL->SQL examples, gotchas.

Inputs: table (required).

list_familiesB

List lens families and their tables.

Inputs: no named parameters.

list_tablesC

List catalog tables with purpose. Optional family filter.

Inputs: family.

lookupC

Retrieve one value from a reference table.

Inputs: key (required), table_id (required).

lookup_modelB

Find which table/family a lens model belongs to.

Inputs: name (required).

run_selectB

Run a validated read-only SELECT.

Inputs: sql (required).

search_calculatorA

Find optics calculators for a natural-language question. → get_calculator → calculate.

Inputs: query (required), top_k.

search_knowledgeC

Find which table/family fits a use-case NL question. → get_table_knowledge.

Inputs: query (required), top_k.

search_knowledge_baseB

Search EarthTekniks KB (company, platforms, projects, vision fundamentals). Returns ranked snippets + confident flag.

Inputs: query (required), top_k.

search_lookupsC

Find reference/lookup tables (sensor sizes, f-stops, pixel formats). → get_reference → lookup.

Inputs: query (required), top_k.

search_productsC

Filtered search over one table or family. filters: [{column, op, value}].

Inputs: sort, limit, table, family, +2 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.2/5.0

    Scored across 17 tools

    Disambiguation3/5

    The set has several similarly named tools, especially search_knowledge vs search_knowledge_base and lookup vs lookup_model, which could cause misselection. However, the descriptions include distinct target objects and explicit workflow arrows (search → get → execute) that mostly help an agent separate calculators, lookups, tables, and products.

    Naming Consistency4/5

    Most tools follow a consistent verb_noun snake_case pattern such as get_document, search_products, list_tables, and describe_table. The main deviations are the bare verbs calculate and lookup, plus the confusingly parallel search_knowledge and search_knowledge_base names.

    Tool Count3/5

    At 17 tools, the server sits in the heavy range and feels padded by the repeated search → get → execute triads for calculators, lookups, and table knowledge. Each tool does have a distinct role, but the count is borderline for smooth agent navigation.

    Completeness4/5

    The read-only surface covers the main domains: KB documents, calculators, reference lookups, product specs, and catalog SQL queries with no obvious dead ends. Minor gaps exist—like no browse-all for calculators or lookups and no document listing—but the search tools provide workable entry points.

    Maintenance

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      D
      maintenance
      A collection of production-ready MCP tools for common tasks such as web search, code execution, file operations, and database queries, enabling AI agents to perform these actions through a unified interface.
      -
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI agents to discover and execute solar energy domain tools such as solar cell simulation, perovskite parameter/bandgap/aging prediction, RAG knowledge retrieval, and curve/table generation through MCP.
      MIT