Tests for mcp/store.py uncovered a real defect: the
backend_mcp_token_audit table was created **only** by the one-shot
migration script scripts/migrate_add_refresh_tokens.py, never by
init_mcp_database(). Fresh deployments that never ran the migration
would silently swallow every log_token_audit() call (the function
has a broad except that just logs ERROR and rolls back).
Fix: init_mcp_database now CREATE TABLE IF NOT EXISTS the audit
table plus its two indexes, matching what the migration script does.
Existing installs already have the table — the IF NOT EXISTS makes
it a no-op for them.
Tests for mcp/store.py: 26 new tests, 0% → 90% coverage. Notable:
- auth_token round-trips through Fernet — test reads the raw column
value back and checks plaintext is NOT in the ciphertext.
- update_mcp_server() rejects column names outside its whitelist
with ValueError (SQL-injection guard).
- list_mcp_servers(user_id=...) respects explicit-deny rows but
defaults to allowed when no permission row exists.
- get_servers_needing_refresh() returns only servers with both
token_expires_at within window AND a refresh_token_hash (no point
waking up a server that can't refresh).
Tests caught the bug — wrote the audit-table tests, they failed
with sqlite3.OperationalError, traced back to the missing CREATE
TABLE in init_mcp_database. Exactly the value tests deliver.
262 + 26 = 288 tests pass. mypy still 0. Coverage 50% → 52%.