JC321 commited on
Commit
70b4bcc
·
verified ·
1 Parent(s): d40b4a6

Upload mcp_server_sse.py

Browse files
Files changed (1) hide show
  1. mcp_server_sse.py +445 -41
mcp_server_sse.py CHANGED
@@ -22,7 +22,7 @@ import sys
22
  app = FastAPI(
23
  title="SEC Financial Report MCP Server",
24
  description="Model Context Protocol Server for SEC EDGAR Financial Data",
25
- version="2.1.0"
26
  )
27
 
28
  # Server startup time for monitoring
@@ -374,7 +374,7 @@ async def handle_mcp_message(request: MCPRequest):
374
  },
375
  "serverInfo": {
376
  "name": "sec-financial-data",
377
- "version": "2.1.0"
378
  }
379
  }
380
  ).dict()
@@ -466,7 +466,7 @@ async def sse_endpoint(request: Request):
466
 
467
  @app.get("/", response_class=HTMLResponse)
468
  async def root():
469
- """Landing page with MCP connection instructions"""
470
  return """
471
  <!DOCTYPE html>
472
  <html lang="en">
@@ -477,8 +477,8 @@ async def root():
477
  <style>
478
  body {
479
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
480
- max-width: 900px;
481
- margin: 50px auto;
482
  padding: 20px;
483
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
484
  min-height: 100vh;
@@ -493,6 +493,15 @@ async def root():
493
  color: #667eea;
494
  margin-top: 0;
495
  }
 
 
 
 
 
 
 
 
 
496
  .config-box {
497
  background: #f5f5f5;
498
  padding: 20px;
@@ -507,23 +516,145 @@ async def root():
507
  }
508
  .tool {
509
  background: #f9f9f9;
510
- padding: 15px;
511
  margin: 10px 0;
512
- border-left: 4px solid #667eea;
513
- border-radius: 4px;
 
 
 
 
 
 
 
 
 
 
 
 
 
514
  }
515
- .tool h3 {
516
- margin: 0 0 10px 0;
 
 
 
 
 
 
 
 
517
  color: #333;
 
518
  }
519
- .badge {
520
- display: inline-block;
521
- background: #10b981;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
522
  color: white;
523
- padding: 4px 12px;
524
- border-radius: 12px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
525
  font-size: 12px;
526
- font-weight: bold;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
527
  }
528
  code {
529
  background: #e0e0e0;
@@ -553,54 +684,327 @@ async def root():
553
 
554
  <p><strong>Use the URL above to connect to this MCP Server.</strong></p>
555
 
556
- <h2>Available Tools (7)</h2>
 
 
557
  <div class="tools">
 
558
  <div class="tool">
559
- <h3>search_company</h3>
560
- <p>Search for a company by name in SEC EDGAR database</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
561
  </div>
 
 
562
  <div class="tool">
563
- <h3>get_company_info</h3>
564
- <p>Get detailed company information by CIK code</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
565
  </div>
 
 
566
  <div class="tool">
567
- <h3>get_company_filings</h3>
568
- <p>Get list of SEC filings (10-K, 10-Q, 20-F, etc.)</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
569
  </div>
 
 
570
  <div class="tool">
571
- <h3>get_financial_data</h3>
572
- <p>Get financial data for a specific period (annual or quarterly)</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
573
  </div>
 
 
574
  <div class="tool">
575
- <h3>extract_financial_metrics</h3>
576
- <p>Extract comprehensive financial metrics for multiple years</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
577
  </div>
 
 
578
  <div class="tool">
579
- <h3>get_latest_financial_data</h3>
580
- <p>Get the most recent financial data available</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
581
  </div>
 
 
582
  <div class="tool">
583
- <h3>advanced_search_company</h3>
584
- <p>Advanced search supporting name, ticker, or CIK</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
585
  </div>
586
  </div>
587
 
588
- <h2>Example Usage</h2>
589
- <p>Once connected, you can ask your AI assistant:</p>
590
- <ul>
591
- <li>"Search for Microsoft and show me their latest financial data"</li>
592
- <li>"Extract financial metrics for Apple for the past 3 years"</li>
593
- <li>"Compare NVIDIA and AMD's revenue trends"</li>
594
- </ul>
595
-
596
  <h2>Documentation</h2>
597
  <p>Visit <code>/tools</code> to see all available tools in JSON format.</p>
598
 
599
  <hr style="margin: 30px 0; border: none; border-top: 1px solid #e0e0e0;">
600
  <p style="text-align: center; color: #666; font-size: 14px;">
601
- Powered by Model Context Protocol | SEC EDGAR Data
602
  </p>
603
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
604
  </body>
605
  </html>
606
  """
@@ -619,7 +1023,7 @@ async def health_check():
619
  return {
620
  "status": "healthy",
621
  "server": "sec-financial-data",
622
- "version": "2.1.0",
623
  "protocol": "MCP",
624
  "transport": "SSE",
625
  "tools_count": len(MCP_TOOLS),
 
22
  app = FastAPI(
23
  title="SEC Financial Report MCP Server",
24
  description="Model Context Protocol Server for SEC EDGAR Financial Data",
25
+ version="2.2.0"
26
  )
27
 
28
  # Server startup time for monitoring
 
374
  },
375
  "serverInfo": {
376
  "name": "sec-financial-data",
377
+ "version": "2.2.0"
378
  }
379
  }
380
  ).dict()
 
466
 
467
  @app.get("/", response_class=HTMLResponse)
468
  async def root():
469
+ """Interactive landing page with tool testing functionality"""
470
  return """
471
  <!DOCTYPE html>
472
  <html lang="en">
 
477
  <style>
478
  body {
479
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
480
+ max-width: 1000px;
481
+ margin: 30px auto;
482
  padding: 20px;
483
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
484
  min-height: 100vh;
 
493
  color: #667eea;
494
  margin-top: 0;
495
  }
496
+ .badge {
497
+ display: inline-block;
498
+ background: #10b981;
499
+ color: white;
500
+ padding: 4px 12px;
501
+ border-radius: 12px;
502
+ font-size: 12px;
503
+ font-weight: bold;
504
+ }
505
  .config-box {
506
  background: #f5f5f5;
507
  padding: 20px;
 
516
  }
517
  .tool {
518
  background: #f9f9f9;
 
519
  margin: 10px 0;
520
+ border-radius: 8px;
521
+ border: 2px solid #e0e0e0;
522
+ overflow: hidden;
523
+ transition: all 0.3s;
524
+ }
525
+ .tool:hover {
526
+ border-color: #667eea;
527
+ }
528
+ .tool-header {
529
+ padding: 15px 20px;
530
+ cursor: pointer;
531
+ display: flex;
532
+ justify-content: space-between;
533
+ align-items: center;
534
+ background: linear-gradient(to right, #f9f9f9, #ffffff);
535
  }
536
+ .tool-header:hover {
537
+ background: linear-gradient(to right, #f0f0f0, #f9f9f9);
538
+ }
539
+ .tool-title {
540
+ display: flex;
541
+ align-items: center;
542
+ gap: 10px;
543
+ }
544
+ .tool-title h3 {
545
+ margin: 0;
546
  color: #333;
547
+ font-size: 16px;
548
  }
549
+ .tool-title .desc {
550
+ color: #666;
551
+ font-size: 13px;
552
+ }
553
+ .toggle-icon {
554
+ font-size: 20px;
555
+ color: #667eea;
556
+ transition: transform 0.3s;
557
+ }
558
+ .toggle-icon.expanded {
559
+ transform: rotate(90deg);
560
+ }
561
+ .tool-body {
562
+ display: none;
563
+ padding: 20px;
564
+ background: white;
565
+ border-top: 1px solid #e0e0e0;
566
+ }
567
+ .tool-body.show {
568
+ display: block;
569
+ }
570
+ .param-group {
571
+ margin-bottom: 15px;
572
+ }
573
+ .param-group label {
574
+ display: block;
575
+ margin-bottom: 5px;
576
+ font-weight: 500;
577
+ color: #333;
578
+ font-size: 14px;
579
+ }
580
+ .param-group input, .param-group select {
581
+ width: 100%;
582
+ padding: 10px;
583
+ border: 2px solid #e0e0e0;
584
+ border-radius: 6px;
585
+ font-size: 14px;
586
+ box-sizing: border-box;
587
+ }
588
+ .param-group input:focus, .param-group select:focus {
589
+ outline: none;
590
+ border-color: #667eea;
591
+ }
592
+ .param-hint {
593
+ font-size: 12px;
594
+ color: #999;
595
+ margin-top: 3px;
596
+ }
597
+ .test-btn {
598
+ background: linear-gradient(135deg, #667eea, #764ba2);
599
  color: white;
600
+ border: none;
601
+ padding: 12px 30px;
602
+ border-radius: 6px;
603
+ cursor: pointer;
604
+ font-size: 14px;
605
+ font-weight: 600;
606
+ transition: transform 0.2s, box-shadow 0.2s;
607
+ margin-top: 10px;
608
+ }
609
+ .test-btn:hover {
610
+ transform: translateY(-2px);
611
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
612
+ }
613
+ .test-btn:active {
614
+ transform: translateY(0);
615
+ }
616
+ .test-btn:disabled {
617
+ background: #ccc;
618
+ cursor: not-allowed;
619
+ transform: none;
620
+ }
621
+ .result-box {
622
+ margin-top: 15px;
623
+ padding: 15px;
624
+ background: #f5f5f5;
625
+ border-radius: 6px;
626
+ border-left: 4px solid #667eea;
627
+ font-family: 'Monaco', 'Courier New', monospace;
628
  font-size: 12px;
629
+ max-height: 400px;
630
+ overflow-y: auto;
631
+ white-space: pre-wrap;
632
+ word-break: break-word;
633
+ display: none;
634
+ }
635
+ .result-box.show {
636
+ display: block;
637
+ }
638
+ .result-box.error {
639
+ border-left-color: #ef4444;
640
+ background: #fee;
641
+ }
642
+ .result-box.success {
643
+ border-left-color: #10b981;
644
+ background: #f0fdf4;
645
+ }
646
+ .loading {
647
+ display: inline-block;
648
+ width: 14px;
649
+ height: 14px;
650
+ border: 2px solid #ffffff;
651
+ border-radius: 50%;
652
+ border-top-color: transparent;
653
+ animation: spin 1s linear infinite;
654
+ margin-left: 8px;
655
+ }
656
+ @keyframes spin {
657
+ to { transform: rotate(360deg); }
658
  }
659
  code {
660
  background: #e0e0e0;
 
684
 
685
  <p><strong>Use the URL above to connect to this MCP Server.</strong></p>
686
 
687
+ <h2>Available Tools (7) - Interactive Testing</h2>
688
+ <p style="color: #666; font-size: 14px;">Click on any tool below to expand and test it directly!</p>
689
+
690
  <div class="tools">
691
+ <!-- Tool 1: search_company -->
692
  <div class="tool">
693
+ <div class="tool-header" onclick="toggleTool('tool1')">
694
+ <div class="tool-title">
695
+ <span class="toggle-icon" id="icon-tool1">▶</span>
696
+ <div>
697
+ <h3>search_company</h3>
698
+ <div class="desc">Search for a company by name in SEC EDGAR database</div>
699
+ </div>
700
+ </div>
701
+ </div>
702
+ <div class="tool-body" id="tool1">
703
+ <div class="param-group">
704
+ <label>Company Name *</label>
705
+ <input type="text" id="tool1-company_name" placeholder="e.g., Microsoft, Apple, Tesla">
706
+ <div class="param-hint">Enter the full or partial company name</div>
707
+ </div>
708
+ <button class="test-btn" onclick="testTool('search_company', 'tool1')">Run Test</button>
709
+ <div class="result-box" id="result-tool1"></div>
710
+ </div>
711
  </div>
712
+
713
+ <!-- Tool 2: advanced_search_company -->
714
  <div class="tool">
715
+ <div class="tool-header" onclick="toggleTool('tool2')">
716
+ <div class="tool-title">
717
+ <span class="toggle-icon" id="icon-tool2">▶</span>
718
+ <div>
719
+ <h3>advanced_search_company</h3>
720
+ <div class="desc">Advanced search supporting name, ticker, or CIK</div>
721
+ </div>
722
+ </div>
723
+ </div>
724
+ <div class="tool-body" id="tool2">
725
+ <div class="param-group">
726
+ <label>Company Name / Ticker / CIK *</label>
727
+ <input type="text" id="tool2-company_input" placeholder="e.g., MSFT, 0000789019, Microsoft">
728
+ <div class="param-hint">Enter company name, ticker symbol, or CIK code</div>
729
+ </div>
730
+ <button class="test-btn" onclick="testTool('advanced_search_company', 'tool2')">Run Test</button>
731
+ <div class="result-box" id="result-tool2"></div>
732
+ </div>
733
  </div>
734
+
735
+ <!-- Tool 3: get_company_info -->
736
  <div class="tool">
737
+ <div class="tool-header" onclick="toggleTool('tool3')">
738
+ <div class="tool-title">
739
+ <span class="toggle-icon" id="icon-tool3">▶</span>
740
+ <div>
741
+ <h3>get_company_info</h3>
742
+ <div class="desc">Get detailed company information by CIK code</div>
743
+ </div>
744
+ </div>
745
+ </div>
746
+ <div class="tool-body" id="tool3">
747
+ <div class="param-group">
748
+ <label>CIK Code *</label>
749
+ <input type="text" id="tool3-cik" placeholder="e.g., 0000789019">
750
+ <div class="param-hint">10-digit CIK code (use search_company to find it)</div>
751
+ </div>
752
+ <button class="test-btn" onclick="testTool('get_company_info', 'tool3')">Run Test</button>
753
+ <div class="result-box" id="result-tool3"></div>
754
+ </div>
755
  </div>
756
+
757
+ <!-- Tool 4: get_company_filings -->
758
  <div class="tool">
759
+ <div class="tool-header" onclick="toggleTool('tool4')">
760
+ <div class="tool-title">
761
+ <span class="toggle-icon" id="icon-tool4">▶</span>
762
+ <div>
763
+ <h3>get_company_filings</h3>
764
+ <div class="desc">Get list of SEC filings (10-K, 10-Q, 20-F, etc.)</div>
765
+ </div>
766
+ </div>
767
+ </div>
768
+ <div class="tool-body" id="tool4">
769
+ <div class="param-group">
770
+ <label>CIK Code *</label>
771
+ <input type="text" id="tool4-cik" placeholder="e.g., 0000789019">
772
+ </div>
773
+ <div class="param-group">
774
+ <label>Form Types (Optional)</label>
775
+ <select id="tool4-form_types" multiple style="height: 80px;">
776
+ <option value="10-K">10-K (Annual Report)</option>
777
+ <option value="10-Q">10-Q (Quarterly Report)</option>
778
+ <option value="20-F">20-F (Foreign Annual)</option>
779
+ <option value="8-K">8-K (Current Report)</option>
780
+ </select>
781
+ <div class="param-hint">Leave empty for all types, or select specific forms (Ctrl+Click for multiple)</div>
782
+ </div>
783
+ <button class="test-btn" onclick="testTool('get_company_filings', 'tool4')">Run Test</button>
784
+ <div class="result-box" id="result-tool4"></div>
785
+ </div>
786
  </div>
787
+
788
+ <!-- Tool 5: get_latest_financial_data -->
789
  <div class="tool">
790
+ <div class="tool-header" onclick="toggleTool('tool5')">
791
+ <div class="tool-title">
792
+ <span class="toggle-icon" id="icon-tool5">▶</span>
793
+ <div>
794
+ <h3>get_latest_financial_data</h3>
795
+ <div class="desc">Get the most recent financial data available</div>
796
+ </div>
797
+ </div>
798
+ </div>
799
+ <div class="tool-body" id="tool5">
800
+ <div class="param-group">
801
+ <label>CIK Code *</label>
802
+ <input type="text" id="tool5-cik" placeholder="e.g., 0000789019">
803
+ </div>
804
+ <button class="test-btn" onclick="testTool('get_latest_financial_data', 'tool5')">Run Test</button>
805
+ <div class="result-box" id="result-tool5"></div>
806
+ </div>
807
  </div>
808
+
809
+ <!-- Tool 6: get_financial_data -->
810
  <div class="tool">
811
+ <div class="tool-header" onclick="toggleTool('tool6')">
812
+ <div class="tool-title">
813
+ <span class="toggle-icon" id="icon-tool6">▶</span>
814
+ <div>
815
+ <h3>get_financial_data</h3>
816
+ <div class="desc">Get financial data for a specific period (annual or quarterly)</div>
817
+ </div>
818
+ </div>
819
+ </div>
820
+ <div class="tool-body" id="tool6">
821
+ <div class="param-group">
822
+ <label>CIK Code *</label>
823
+ <input type="text" id="tool6-cik" placeholder="e.g., 0000789019">
824
+ </div>
825
+ <div class="param-group">
826
+ <label>Period *</label>
827
+ <input type="text" id="tool6-period" placeholder="e.g., 2024 or 2024Q3">
828
+ <div class="param-hint">Format: YYYY for annual (e.g., 2024) or YYYYQX for quarterly (e.g., 2024Q3)</div>
829
+ </div>
830
+ <button class="test-btn" onclick="testTool('get_financial_data', 'tool6')">Run Test</button>
831
+ <div class="result-box" id="result-tool6"></div>
832
+ </div>
833
  </div>
834
+
835
+ <!-- Tool 7: extract_financial_metrics -->
836
  <div class="tool">
837
+ <div class="tool-header" onclick="toggleTool('tool7')">
838
+ <div class="tool-title">
839
+ <span class="toggle-icon" id="icon-tool7">▶</span>
840
+ <div>
841
+ <h3>extract_financial_metrics</h3>
842
+ <div class="desc">Extract comprehensive financial metrics for multiple years</div>
843
+ </div>
844
+ </div>
845
+ </div>
846
+ <div class="tool-body" id="tool7">
847
+ <div class="param-group">
848
+ <label>CIK Code *</label>
849
+ <input type="text" id="tool7-cik" placeholder="e.g., 0000789019">
850
+ </div>
851
+ <div class="param-group">
852
+ <label>Number of Years</label>
853
+ <select id="tool7-years">
854
+ <option value="1">1 year</option>
855
+ <option value="2">2 years</option>
856
+ <option value="3" selected>3 years</option>
857
+ <option value="5">5 years</option>
858
+ <option value="10">10 years</option>
859
+ </select>
860
+ <div class="param-hint">Number of recent years to extract (1-10)</div>
861
+ </div>
862
+ <button class="test-btn" onclick="testTool('extract_financial_metrics', 'tool7')">Run Test</button>
863
+ <div class="result-box" id="result-tool7"></div>
864
+ </div>
865
  </div>
866
  </div>
867
 
 
 
 
 
 
 
 
 
868
  <h2>Documentation</h2>
869
  <p>Visit <code>/tools</code> to see all available tools in JSON format.</p>
870
 
871
  <hr style="margin: 30px 0; border: none; border-top: 1px solid #e0e0e0;">
872
  <p style="text-align: center; color: #666; font-size: 14px;">
873
+ Powered by Model Context Protocol | SEC EDGAR Data | v2.1.0
874
  </p>
875
  </div>
876
+
877
+ <script>
878
+ function toggleTool(toolId) {
879
+ const body = document.getElementById(toolId);
880
+ const icon = document.getElementById('icon-' + toolId);
881
+
882
+ if (body.classList.contains('show')) {
883
+ body.classList.remove('show');
884
+ icon.classList.remove('expanded');
885
+ } else {
886
+ body.classList.add('show');
887
+ icon.classList.add('expanded');
888
+ }
889
+ }
890
+
891
+ async function testTool(toolName, toolId) {
892
+ const btn = event.target;
893
+ const resultBox = document.getElementById('result-' + toolId);
894
+
895
+ // Get parameters based on tool
896
+ let args = {};
897
+
898
+ if (toolName === 'search_company') {
899
+ const companyName = document.getElementById(toolId + '-company_name').value;
900
+ if (!companyName) {
901
+ alert('Please enter a company name');
902
+ return;
903
+ }
904
+ args = { company_name: companyName };
905
+ }
906
+ else if (toolName === 'advanced_search_company') {
907
+ const companyInput = document.getElementById(toolId + '-company_input').value;
908
+ if (!companyInput) {
909
+ alert('Please enter a company name, ticker, or CIK');
910
+ return;
911
+ }
912
+ args = { company_input: companyInput };
913
+ }
914
+ else if (toolName === 'get_company_info') {
915
+ const cik = document.getElementById(toolId + '-cik').value;
916
+ if (!cik) {
917
+ alert('Please enter a CIK code');
918
+ return;
919
+ }
920
+ args = { cik: cik };
921
+ }
922
+ else if (toolName === 'get_company_filings') {
923
+ const cik = document.getElementById(toolId + '-cik').value;
924
+ if (!cik) {
925
+ alert('Please enter a CIK code');
926
+ return;
927
+ }
928
+ const formTypesSelect = document.getElementById(toolId + '-form_types');
929
+ const selectedForms = Array.from(formTypesSelect.selectedOptions).map(opt => opt.value);
930
+ args = { cik: cik };
931
+ if (selectedForms.length > 0) {
932
+ args.form_types = selectedForms;
933
+ }
934
+ }
935
+ else if (toolName === 'get_latest_financial_data') {
936
+ const cik = document.getElementById(toolId + '-cik').value;
937
+ if (!cik) {
938
+ alert('Please enter a CIK code');
939
+ return;
940
+ }
941
+ args = { cik: cik };
942
+ }
943
+ else if (toolName === 'get_financial_data') {
944
+ const cik = document.getElementById(toolId + '-cik').value;
945
+ const period = document.getElementById(toolId + '-period').value;
946
+ if (!cik || !period) {
947
+ alert('Please enter CIK and period');
948
+ return;
949
+ }
950
+ args = { cik: cik, period: period };
951
+ }
952
+ else if (toolName === 'extract_financial_metrics') {
953
+ const cik = document.getElementById(toolId + '-cik').value;
954
+ const years = parseInt(document.getElementById(toolId + '-years').value);
955
+ if (!cik) {
956
+ alert('Please enter a CIK code');
957
+ return;
958
+ }
959
+ args = { cik: cik, years: years };
960
+ }
961
+
962
+ // Show loading state
963
+ btn.disabled = true;
964
+ btn.innerHTML = 'Running<span class="loading"></span>';
965
+ resultBox.className = 'result-box show';
966
+ resultBox.textContent = 'Loading...';
967
+
968
+ try {
969
+ const response = await fetch('/message', {
970
+ method: 'POST',
971
+ headers: {
972
+ 'Content-Type': 'application/json',
973
+ },
974
+ body: JSON.stringify({
975
+ jsonrpc: '2.0',
976
+ id: Date.now(),
977
+ method: 'tools/call',
978
+ params: {
979
+ name: toolName,
980
+ arguments: args
981
+ }
982
+ })
983
+ });
984
+
985
+ const data = await response.json();
986
+
987
+ if (data.result && data.result.content && data.result.content[0]) {
988
+ const content = data.result.content[0].text;
989
+ const parsed = JSON.parse(content);
990
+ resultBox.className = 'result-box show success';
991
+ resultBox.textContent = JSON.stringify(parsed, null, 2);
992
+ } else if (data.error) {
993
+ resultBox.className = 'result-box show error';
994
+ resultBox.textContent = 'Error: ' + JSON.stringify(data.error, null, 2);
995
+ } else {
996
+ resultBox.className = 'result-box show error';
997
+ resultBox.textContent = 'Unexpected response: ' + JSON.stringify(data, null, 2);
998
+ }
999
+ } catch (error) {
1000
+ resultBox.className = 'result-box show error';
1001
+ resultBox.textContent = 'Error: ' + error.message;
1002
+ } finally {
1003
+ btn.disabled = false;
1004
+ btn.innerHTML = 'Run Test';
1005
+ }
1006
+ }
1007
+ </script>
1008
  </body>
1009
  </html>
1010
  """
 
1023
  return {
1024
  "status": "healthy",
1025
  "server": "sec-financial-data",
1026
+ "version": "2.2.0",
1027
  "protocol": "MCP",
1028
  "transport": "SSE",
1029
  "tools_count": len(MCP_TOOLS),