@@ -106,71 +106,60 @@ else
106106 log_info " You can run the server with: uv run fpd-mcp"
107107fi
108108
109- # Step 5: Secure API Key Configuration
109+ # Step 5: API Key Configuration
110110echo " "
111- echo " =========================================="
112- echo " SECURE API KEY CONFIGURATION"
113- echo " =========================================="
114- echo " "
115- log_info " API keys will be stored in ENCRYPTED secure storage"
116- log_info " Location: ~/.uspto_api_key and ~/.mistral_api_key"
117- log_info " Format: Secure file storage (Linux: file permissions 600)"
111+ log_info " API Key Configuration"
118112echo " "
119113
120- # Collect USPTO API key with validation
121- echo " Enter your USPTO API key (required - get from https://data.uspto.gov/myodp/):"
122- echo -n " > "
123- read -s USPTO_API_KEY # Silent read (no echo to terminal)
114+ log_info " USPTO FPD MCP requires two API keys:"
115+ log_info " 1. USPTO Open Data Portal API key (required)"
116+ log_info " 2. Mistral API key (optional - for OCR document extraction)"
117+ echo " "
118+ log_info " Get your free USPTO API key from: https://data.uspto.gov/myodp/"
119+ log_info " Get your Mistral API key from: https://console.mistral.ai/"
124120echo " "
125121
126- # Validate USPTO key format
127- while ! validate_uspto_api_key " $USPTO_API_KEY " ; do
128- echo " "
129- log_error " Invalid USPTO API key format"
130- echo " Expected: Exactly 30 lowercase letters (a-z)"
131- echo " "
132- echo " Enter your USPTO API key:"
133- echo -n " > "
134- read -s USPTO_API_KEY
135- echo " "
136- done
122+ # Prompt for USPTO API key with validation (uses secure hidden input)
123+ USPTO_API_KEY=$( prompt_and_validate_uspto_key)
124+ if [[ -z " $USPTO_API_KEY " ]]; then
125+ log_error " Failed to obtain valid USPTO API key"
126+ exit 1
127+ fi
137128
129+ log_success " USPTO API key validated and configured"
138130echo " "
139- log_success " USPTO API key format validated"
140131
141- # Collect Mistral API key with validation
142- echo " "
143- echo " Enter your Mistral API key (optional for OCR - press Enter to skip):"
144- echo -n " > "
145- read -s MISTRAL_API_KEY
132+ # Prompt for Mistral API key (optional)
146133echo " "
147-
148- if [[ -n " $MISTRAL_API_KEY " ]]; then
149- # Validate Mistral key format
150- while ! validate_mistral_api_key " $MISTRAL_API_KEY " ; do
151- echo " "
152- log_error " Invalid Mistral API key format"
153- echo " Expected: Exactly 32 alphanumeric characters (A-Z, a-z, 0-9)"
154- echo " "
155- echo " Enter your Mistral API key (or press Enter to skip):"
156- echo -n " > "
157- read -s MISTRAL_API_KEY
158- echo " "
159-
160- # Allow empty to skip
161- if [[ -z " $MISTRAL_API_KEY " ]]; then
162- break
163- fi
164- done
134+ log_info " Mistral API key configuration (optional - for OCR document extraction)"
135+ read -p " Would you like to configure Mistral API key now? (Y/n): " CONFIGURE_MISTRAL
136+ CONFIGURE_MISTRAL=${CONFIGURE_MISTRAL:- Y}
137+
138+ MISTRAL_API_KEY=" "
139+ if [[ " $CONFIGURE_MISTRAL " =~ ^[Yy]$ ]]; then
140+ MISTRAL_API_KEY=$( prompt_and_validate_mistral_key)
141+ if [[ -z " $MISTRAL_API_KEY " ]]; then
142+ log_warning " Failed to obtain valid Mistral API key - skipping"
143+ log_info " You can configure it later using: ./deploy/manage_api_keys.sh"
144+ else
145+ log_success " Mistral API key validated and configured"
146+ fi
147+ else
148+ log_info " Skipping Mistral API key configuration"
149+ log_info " You can configure it later using: ./deploy/manage_api_keys.sh"
165150fi
166151
167152# Step 6: Store API keys in SECURE storage (NOT in config file!)
168153echo " "
169- log_info " Storing API keys in encrypted secure storage..."
154+ log_info " Storing API keys in secure storage..."
155+ log_info " Location: ~/.uspto_api_key and ~/.mistral_api_key (file permissions: 600)"
170156echo " "
171157
172- # Store USPTO key using environment variable (NOT command line argument )
158+ # Store USPTO key using environment variable (more secure than command line)
173159export SETUP_USPTO_KEY=" $USPTO_API_KEY "
160+ if [[ -n " $MISTRAL_API_KEY " ]]; then
161+ export SETUP_MISTRAL_KEY=" $MISTRAL_API_KEY "
162+ fi
174163
175164STORE_RESULT=$( python3 << 'EOF '
176165import sys
@@ -181,87 +170,66 @@ from pathlib import Path
181170sys.path.insert(0, str(Path.cwd() / 'src'))
182171
183172try:
184- from fpd_mcp.shared_secure_storage import store_uspto_api_key
173+ from fpd_mcp.shared_secure_storage import store_uspto_api_key, store_mistral_api_key
185174
186- # Read from environment variable (NOT from command line - more secure )
187- api_key = os.environ.get('SETUP_USPTO_KEY', '')
188- if not api_key :
189- print('ERROR: No API key provided')
175+ # Store USPTO key (required )
176+ uspto_key = os.environ.get('SETUP_USPTO_KEY', '')
177+ if not uspto_key :
178+ print('ERROR: No USPTO API key provided')
190179 sys.exit(1)
191180
192- if store_uspto_api_key(api_key):
193- print('SUCCESS')
194- else:
181+ if not store_uspto_api_key(uspto_key):
195182 print('ERROR: Failed to store USPTO key')
196183 sys.exit(1)
184+
185+ # Store Mistral key (optional)
186+ mistral_key = os.environ.get('SETUP_MISTRAL_KEY', '')
187+ if mistral_key:
188+ if not store_mistral_api_key(mistral_key):
189+ print('ERROR: Failed to store Mistral key')
190+ sys.exit(1)
191+ print('SUCCESS:BOTH')
192+ else:
193+ print('SUCCESS:USPTO_ONLY')
194+
197195except Exception as e:
198196 print(f'ERROR: {str(e)}')
199197 sys.exit(1)
200198EOF
201199)
202200
203- # Clear environment variable immediately
201+ # Clear environment variables immediately
204202unset SETUP_USPTO_KEY
203+ unset SETUP_MISTRAL_KEY
205204
206- if [[ " $STORE_RESULT " == " SUCCESS" ]]; then
207- log_success " USPTO API key stored in secure storage"
208- log_info " Location: ~/.uspto_api_key"
205+ if [[ " $STORE_RESULT " == " SUCCESS:BOTH" ]]; then
206+ log_success " USPTO and Mistral API keys stored in secure storage"
207+ log_info " USPTO Location: ~/.uspto_api_key"
208+ log_info " Mistral Location: ~/.mistral_api_key"
209209 log_info " Permissions: 600 (owner read/write only)"
210- log_audit " USPTO API key configured via linux_setup.sh"
211210
212- # Verify file permissions
211+ # CRITICAL SECURITY: Set file permissions on both API key files
213212 if [ -f " $HOME /.uspto_api_key" ]; then
214- PERMS=$( stat -c ' %a' " $HOME /.uspto_api_key" 2> /dev/null || stat -f ' %A' " $HOME /.uspto_api_key" 2> /dev/null)
215- if [[ " $PERMS " == " 600" ]]; then
216- log_success " Verified: File permissions are secure (600)"
217- else
218- log_warning " Warning: File permissions are $PERMS (expected 600)"
219- # Try to fix
220- chmod 600 " $HOME /.uspto_api_key" 2> /dev/null || true
221- fi
213+ set_secure_file_permissions " $HOME /.uspto_api_key"
222214 fi
223- else
224- log_error " Failed to store USPTO API key: $STORE_RESULT "
225- exit 1
226- fi
227-
228- # Store Mistral key if provided
229- if [[ -n " $MISTRAL_API_KEY " ]]; then
230- echo " "
231- export SETUP_MISTRAL_KEY=" $MISTRAL_API_KEY "
232-
233- STORE_RESULT=$( python3 << 'EOF '
234- import sys
235- import os
236- from pathlib import Path
237-
238- sys.path.insert(0, str(Path.cwd() / 'src'))
239-
240- try:
241- from fpd_mcp.shared_secure_storage import store_mistral_api_key
242215
243- api_key = os.environ.get('SETUP_MISTRAL_KEY', '')
244- if store_mistral_api_key(api_key):
245- print('SUCCESS')
246- else:
247- print('ERROR: Failed to store Mistral key')
248- sys.exit(1)
249- except Exception as e:
250- print(f'ERROR: {str(e)}')
251- sys.exit(1)
252- EOF
253- )
216+ if [ -f " $HOME /.mistral_api_key" ]; then
217+ set_secure_file_permissions " $HOME /.mistral_api_key"
218+ fi
254219
255- unset SETUP_MISTRAL_KEY
220+ elif [[ " $STORE_RESULT " == " SUCCESS:USPTO_ONLY" ]]; then
221+ log_success " USPTO API key stored in secure storage"
222+ log_info " Location: ~/.uspto_api_key"
223+ log_info " Permissions: 600 (owner read/write only)"
256224
257- if [[ " $STORE_RESULT " == " SUCCESS" ]]; then
258- log_success " Mistral API key stored in secure storage"
259- log_info " Location: ~/.mistral_api_key"
260- log_info " Permissions: 600 (owner read/write only)"
261- log_audit " Mistral API key configured via linux_setup.sh"
262- else
263- log_warning " Failed to store Mistral API key: $STORE_RESULT "
225+ # CRITICAL SECURITY: Set file permissions on USPTO API key file
226+ if [ -f " $HOME /.uspto_api_key" ]; then
227+ set_secure_file_permissions " $HOME /.uspto_api_key"
264228 fi
229+
230+ else
231+ log_error " Failed to store API keys: $STORE_RESULT "
232+ exit 1
265233fi
266234
267235# CRITICAL: Clear sensitive variables from memory
@@ -270,10 +238,6 @@ unset MISTRAL_API_KEY
270238unset SETUP_USPTO_KEY
271239unset SETUP_MISTRAL_KEY
272240
273- echo " "
274- log_success " API keys stored securely - NOT in Claude Code config file!"
275- log_info " Keys will be loaded automatically from encrypted storage at runtime"
276-
277241# Step 7: PFW MCP Detection
278242echo " "
279243log_info " USPTO MCP Ecosystem Integration"
@@ -448,67 +412,61 @@ except Exception as e:
448412 fi
449413
450414 log_success " Claude Code configuration complete!"
451- log_audit " Claude Code configured via linux_setup.sh (no API keys in config)"
415+
416+ # Display configuration method used
417+ echo " "
418+ log_success " Security Configuration:"
419+ log_info " - USPTO API key stored in secure storage: ~/.uspto_api_key"
420+ if [ -f " $HOME /.mistral_api_key" ]; then
421+ log_info " - Mistral API key stored in secure storage: ~/.mistral_api_key"
422+ fi
423+ log_info " - File permissions: 600 (owner read/write only)"
424+ log_info " - API keys NOT in Claude Desktop config file"
425+ log_info " - Config directory permissions: 700 (owner only)"
426+ log_info " - Shared storage across all USPTO MCPs (PFW/PTAB/FPD/Citations)"
452427else
453- log_info " Skipping Claude Code configuration"
454- log_info " You can manually configure later"
428+ log_info " Skipping Claude Code configuration"
429+ log_info " You can manually configure later by editing $CLAUDE_CONFIG_FILE "
430+ log_info " See README.md for configuration template"
455431fi
456432
457- echo " "
458- echo " =========================================="
459- log_success " Linux setup complete!"
460- echo " =========================================="
461433echo " "
462434
435+ # Step 9: Final Summary
436+ echo -e " ${GREEN} [OK] Linux setup complete!${NC} "
463437log_warning " Please restart Claude Code to load the MCP server"
464- echo " "
465438
466- log_info " Configuration Summary:"
467439echo " "
468- log_success " ✓ USPTO API Key: Stored in encrypted secure storage"
469- log_info " File: ~/.uspto_api_key (permissions: 600)"
470- log_info " Encryption: File permissions + Linux security"
471-
440+ log_info " Configuration Summary:"
441+ log_success " USPTO API Key: Stored in secure storage (~/.uspto_api_key)"
472442if [ -f " $HOME /.mistral_api_key" ]; then
473- log_success " ✓ Mistral API Key: Stored in encrypted secure storage"
474- log_info " File: ~/.mistral_api_key (permissions: 600)"
475- log_info " OCR: Enabled"
443+ log_success " Mistral API Key: Stored in secure storage (~/.mistral_api_key)"
476444else
477- log_info " ℹ Mistral API Key: Not configured (OCR disabled )"
445+ log_warning " Mistral API Key: Not configured (optional - for OCR )"
478446fi
447+ log_success " Dependencies: Installed"
448+ log_success " Package: Available as command"
449+ log_success " Installation Directory: $PROJECT_DIR "
450+ log_success " Security: File permissions 600 (owner only)"
451+ log_success " Security: Config directory permissions 700 (owner only)"
479452
480453echo " "
481- log_success " ✓ Installation Directory: $PROJECT_DIR "
482- echo " "
483-
484- if [ -f " $HOME /.claude.json" ]; then
485- log_success " ✓ Claude Code config: $HOME /.claude.json"
486- log_info " API keys: NOT in config (loaded from secure storage)"
487-
488- # Verify permissions
489- PERMS=$( stat -c ' %a' " $HOME /.claude.json" 2> /dev/null || stat -f ' %A' " $HOME /.claude.json" 2> /dev/null)
490- log_info " Permissions: $PERMS "
491- else
492- log_info " ℹ Claude Code config: Not configured"
493- fi
454+ log_info " Test the server:"
455+ echo " uv run fpd-mcp --help"
494456
495457echo " "
496- log_info " Security Features:"
497- echo " ✓ API keys stored in encrypted secure storage (NOT plain text)"
498- echo " ✓ File permissions: 600 on all sensitive files"
499- echo " ✓ Directory permissions: 700 on config directories"
500- echo " ✓ API key format validation (prevents typos)"
501- echo " ✓ Audit logging enabled (~/.uspto_mcp_audit.log)"
502- echo " "
458+ log_info " Test with Claude Code:"
459+ echo " Ask Claude: 'Use fpd_search_petitions_minimal to search for petitions'"
460+ echo " Ask Claude: 'Use fpd_get_tool_reflections to learn about FPD MCP features'"
503461
504- log_info " Test the server:"
505- echo " uv run fpd-mcp --help"
506462echo " "
463+ log_info " Verify MCP is running:"
464+ echo " claude mcp list"
507465
508- log_info " Test with Claude Code:"
509- echo " Ask Claude: 'Use fpd_search_petitions_minimal to search for patents'"
510466echo " "
467+ log_info " Manage API keys later:"
468+ echo " (Future enhancement - currently use deployment script to update)"
511469
512- log_info " Manage API keys: "
513- echo " Run: ./deploy/manage_api_keys.ps1 (Windows) or edit secure storage files "
470+ echo " "
471+ echo -e " ${GREEN} === Setup Complete! === ${NC} "
514472echo " "
0 commit comments