Skip to main content
Glama
basic_info.py24.8 kB
"""Company basic information tools.""" from utils import TWSEAPIClient, format_properties_with_values_multiline, has_meaningful_data, format_meaningful_fields_only def register_tools(mcp): """Register company basic info tools with the MCP instance.""" @mcp.tool def get_company_profile(code: str) -> str: """Obtain the basic information of a listed company as a JSON string object based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap03_L", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_company_dividend(code: str) -> str: """Obtain the dividend distribution information of a listed company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap45_L", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_company_monthly_revenue(code: str) -> str: """Obtain monthly revenue information for a listed company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap05_L", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_public_company_monthly_revenue(code: str) -> str: """Obtain monthly revenue summary for a public company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap05_P", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_company_major_shareholders(code: str) -> str: """Obtain major shareholders (over 10% ownership) information for a listed company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap02_L", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_company_eps_statistics(code: str) -> str: """Obtain EPS statistics by industry for a listed company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap14_L", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_company_board_insufficient_shares() -> str: """Get all listed companies where board members hold insufficient shares as required by law.""" try: data = TWSEAPIClient.get_data("/opendata/t187ap08_L") if not data: return "目前沒有資料。" result = f"共有 {len(data)} 筆董監事持股不足法定成數的資料:\n\n" for item in data: company_code = item.get("公司代號", "N/A") company_name = item.get("公司名稱", "N/A") director_count = item.get("董監事人數", "N/A") insufficient_count = item.get("持股不足法定成數人數", "N/A") result += f"- {company_name} ({company_code}): {insufficient_count}/{director_count} 人持股不足\n" return result except Exception as e: return f"查詢失敗: {str(e)}" @mcp.tool def get_company_board_shareholdings(code: str) -> str: """Obtain board members' shareholding details for a listed company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap11_L", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_company_daily_insider_trades_preannounced(code: str) -> str: """Obtain daily insider share transfer pre-announcements for a listed company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap12_L", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_company_daily_insider_trades_untransferred(code: str) -> str: """Obtain daily insider share transfers that have not yet been executed for a listed company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap13_L", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_company_sec_regulatory_penalties(code: str) -> str: """Obtain SEC regulatory penalty information for a listed company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap22_L", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_companies_with_independent_directors() -> str: """Get all listed companies with information about independent directors.""" try: data = TWSEAPIClient.get_data("/opendata/t187ap30_L") if not data: return "目前沒有資料。" result = f"共有 {len(data)} 筆獨立董監事兼任情形資料:\n\n" for item in data: company_code = item.get("公司代號", "N/A") company_name = item.get("公司名稱", "N/A") total_directors = item.get("董監事總人數", "N/A") independent_directors = item.get("獨立董監事人數", "N/A") result += f"- {company_name} ({company_code}): {independent_directors}/{total_directors} 位獨立董監事\n" return result except Exception as e: return f"查詢失敗: {str(e)}" @mcp.tool def get_company_director_compensation(code: str) -> str: """Obtain director compensation information for a listed company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap29_A_L", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_company_supervisor_compensation(code: str) -> str: """Obtain supervisor compensation information for a listed company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap29_B_L", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_company_consolidated_director_compensation(code: str) -> str: """Obtain consolidated director compensation information for a listed company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap29_C_L", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_company_consolidated_supervisor_compensation(code: str) -> str: """Obtain consolidated supervisor compensation information for a listed company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap29_D_L", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_company_information_disclosure_violations(code: str) -> str: """Obtain information disclosure and shareholder meeting regulation violations for a listed company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap23_L", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_companies_with_csr_reports_103() -> str: """Get all companies required to prepare and submit CSR reports in 2014 (103 year).""" try: data = TWSEAPIClient.get_data("/static/20151104/CSR103") if not data: return ( "查無 103 年度 CSR 報告名單或資料格式不符(來源可能為舊式靜態頁)。\n" "建議改查近年永續報告(ESG)相關端點,或至公司官網/公告查詢。" ) valid = [ it for it in data if isinstance(it, dict) and has_meaningful_data(it, ["公司代號", "公司名稱"]) ] total = len(valid) if total == 0: return ( "查無有效的公司名單(欄位皆為空或 N/A)。\n" "請稍後再試或改查其他相關來源。" ) limit = 50 head = valid[:limit] lines = [f"共有 {total} 家公司需編製與申報 103 年度 CSR 報告書:\n"] for item in head: company_code = item.get("公司代號", "N/A") company_name = item.get("公司名稱", "N/A") lines.append(f"- {company_name} ({company_code})") if total > limit: lines.append(f"\n... 還有 {total - limit} 家未顯示。") return "\n".join(lines) except Exception as e: return f"查詢失敗: {str(e)}" @mcp.tool def get_public_company_profile(code: str) -> str: """Obtain basic information for a public company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap03_P", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_market_disposal_stocks() -> str: """Get stocks that have been disposed by the market.""" try: data = TWSEAPIClient.get_data("/announcement/punish") if not data: return "目前沒有處置股票資料。" result = f"集中市場公布處置股票共 {len(data)} 筆:\n\n" for item in data: stock_code = item.get("證券代號", "N/A") stock_name = item.get("證券名稱", "N/A") disposal_type = item.get("處置種類", "N/A") result += f"- {stock_name} ({stock_code}): {disposal_type}\n" return result except Exception as e: return f"查詢失敗: {str(e)}" @mcp.tool def get_company_board_insufficient_shares_consecutive() -> str: """Get companies where board members have held insufficient shares for 3 consecutive months or more.""" try: data = TWSEAPIClient.get_data("/opendata/t187ap10_L") if not data: return "目前沒有資料。" result = f"共有 {len(data)} 筆董監事持股不足法定成數連續達3個月以上的資料:\n\n" for item in data: company_code = item.get("公司代號", "N/A") company_name = item.get("公司名稱", "N/A") consecutive_months = item.get("連續達3個月以上之月數", "N/A") result += f"- {company_name} ({company_code}): 連續 {consecutive_months} 個月\n" return result except Exception as e: return f"查詢失敗: {str(e)}" @mcp.tool def get_company_shareholder_meeting_announcements() -> str: """Get comprehensive shareholder meeting announcements with all available information (since 2008).""" try: data = TWSEAPIClient.get_data("/opendata/t187ap38_L") if not data: return "目前沒有股東會公告資料。" # Use the correct field names from the actual API response filtered = [ it for it in data if isinstance(it, dict) and has_meaningful_data(it, [ "公司代號", "公司名稱", "股東常(臨時)會日期-日期", "股東常(臨時)會日期-常或臨時" ]) ] if not filtered: return "查無有效的股東會公告資料。" limit = 20 head = filtered[:limit] result = f"共有 {len(filtered)} 筆股東會公告資料(僅顯示前 {limit} 筆):\n\n" for i, item in enumerate(head, 1): company_code = item.get("公司代號", "N/A") company_name = item.get("公司名稱", "N/A") result += f"【{i}】{company_name} ({company_code})\n" # Use centralized utils to format only meaningful fields # Exclude basic fields we already show in the header meaningful_fields = format_meaningful_fields_only(item, ["公司代號", "公司名稱", "出表日期"]) if meaningful_fields: # Add indentation to each line indented_fields = "\n".join(f" {line}" for line in meaningful_fields.split("\n") if line.strip()) result += f"{indented_fields}\n" result += "\n" if len(filtered) > limit: result += f"... 還有 {len(filtered) - limit} 筆資料未顯示" return result except Exception as e: return f"查詢失敗: {str(e)}" @mcp.tool def get_company_shareholder_meeting_announcements_by_code(code: str) -> str: """Get comprehensive shareholder meeting announcements for a specific company by stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap38_L", code) if not data: return f"查無股票代碼 {code} 的股東會公告資料。" # Check if the returned data has meaningful information if not has_meaningful_data(data, [ "公司代號", "公司名稱", "股東常(臨時)會日期-日期", "股東常(臨時)會日期-常或臨時" ]): return f"股票代碼 {code} 的股東會公告資料無效或不完整。" company_name = data.get("公司名稱", "N/A") company_code = data.get("公司代號", code) result = f"{company_name} ({company_code}) 股東會公告資訊:\n\n" # Use centralized utils to format only meaningful fields # Exclude basic fields we already show in the header meaningful_fields = format_meaningful_fields_only(data, ["公司代號", "公司名稱", "出表日期"]) if meaningful_fields: result += meaningful_fields else: result += "無其他詳細資訊。" return result except Exception as e: return f"查詢失敗: {str(e)}" @mcp.tool def get_companies_with_ownership_changes() -> str: """Get companies with changes in ownership structure.""" try: data = TWSEAPIClient.get_data("/opendata/t187ap24_L") if not data: return "目前沒有經營權異動公司資料。" result = f"共有 {len(data)} 筆經營權異動公司資料:\n\n" for item in data: company_code = item.get("公司代號", "N/A") company_name = item.get("公司名稱", "N/A") change_date = item.get("異動日期", "N/A") result += f"- {company_name} ({company_code}): {change_date}\n" return result except Exception as e: return f"查詢失敗: {str(e)}" @mcp.tool def get_company_shareholder_meeting_dates() -> str: """Get shareholder meeting dates, locations and electronic voting information.""" try: data = TWSEAPIClient.get_data("/opendata/t187ap41_L") if not data: return "目前沒有股東會日期資料。" # Use the correct field names from the actual API response filtered = [ it for it in data if isinstance(it, dict) and has_meaningful_data(it, [ "公司代號", "公司名稱", "開會日期", "開會地點", "是否採電子投票" ]) ] if not filtered: return "查無有效的股東會日期/地點/電子投票資料。" limit = 20 head = filtered[:limit] result = f"共有 {len(filtered)} 筆股東會日期、地點及電子投票資料(僅顯示前 {limit} 筆):\n\n" for item in head: company_code = item.get("公司代號", "N/A") company_name = item.get("公司名稱", "N/A") meeting_date = item.get("開會日期", "N/A") location = item.get("開會地點", "N/A") electronic_voting = item.get("是否採電子投票", "N/A") meeting_type = item.get("股東常(臨時)會", "N/A") result += f"- {company_name} ({company_code}): {meeting_type} - {meeting_date} at {location}, 電子投票: {electronic_voting}\n" if len(filtered) > limit: result += f"\n... 還有 {len(filtered) - limit} 筆資料未顯示" return result except Exception as e: return f"查詢失敗: {str(e)}" @mcp.tool def get_companies_with_business_scope_changes() -> str: """Get companies with major changes in business scope.""" try: data = TWSEAPIClient.get_data("/opendata/t187ap25_L") if not data: return "目前沒有營業範圍重大變更公司資料。" result = f"共有 {len(data)} 筆營業範圍重大變更公司資料:\n\n" for item in data: company_code = item.get("公司代號", "N/A") company_name = item.get("公司名稱", "N/A") change_date = item.get("變更日期", "N/A") result += f"- {company_name} ({company_code}): {change_date}\n" return result except Exception as e: return f"查詢失敗: {str(e)}" @mcp.tool def get_companies_ownership_changes_business_scope() -> str: """Get companies with ownership changes that also have major business scope changes and were suspended from trading.""" try: data = TWSEAPIClient.get_data("/opendata/t187ap26_L") if not data: return "目前沒有經營權異動且營業範圍重大變更停止買賣公司資料。" result = f"共有 {len(data)} 筆經營權異動且營業範圍重大變更停止買賣公司資料:\n\n" for item in data: company_code = item.get("公司代號", "N/A") company_name = item.get("公司名稱", "N/A") suspension_date = item.get("停止買賣日期", "N/A") result += f"- {company_name} ({company_code}): {suspension_date}\n" return result except Exception as e: return f"查詢失敗: {str(e)}" @mcp.tool def get_companies_ownership_changes_business_scope_trading() -> str: """Get companies with ownership changes and major business scope changes that were changed to trading method.""" try: data = TWSEAPIClient.get_data("/opendata/t187ap27_L") if not data: return "目前沒有經營權異動且營業範圍重大變更列為變更交易公司資料。" result = f"共有 {len(data)} 筆經營權異動且營業範圍重大變更列為變更交易公司資料:\n\n" for item in data: company_code = item.get("公司代號", "N/A") company_name = item.get("公司名稱", "N/A") change_date = item.get("變更日期", "N/A") result += f"- {company_name} ({company_code}): {change_date}\n" return result except Exception as e: return f"查詢失敗: {str(e)}" @mcp.tool def get_company_governance_regulations(code: str) -> str: """Obtain corporate governance regulations and rules for a listed company based on its stock code.""" try: data = TWSEAPIClient.get_company_data("/opendata/t187ap32_L", code) return format_properties_with_values_multiline(data) if data else "" except Exception: return "" @mcp.tool def get_company_ceo_dual_role() -> str: """Get information about whether company chairmen also serve as CEOs.""" try: data = TWSEAPIClient.get_data("/opendata/t187ap33_L") if not data: return "目前沒有資料。" result = f"共有 {len(data)} 筆董事長是否兼任總經理資料:\n\n" for item in data: company_code = item.get("公司代號", "N/A") company_name = item.get("公司名稱", "N/A") dual_role = item.get("董事長是否兼任總經理", "N/A") result += f"- {company_name} ({company_code}): {dual_role}\n" return result except Exception as e: return f"查詢失敗: {str(e)}" @mcp.tool def get_company_board_pledged_shares() -> str: """Get board members' pledged shares as a percentage of their actual holdings.""" try: data = TWSEAPIClient.get_data("/opendata/t187ap09_L") if not data: return "目前沒有資料。" result = f"共有 {len(data)} 筆董監事質權設定占實際持有股數資料:\n\n" for item in data: company_code = item.get("公司代號", "N/A") company_name = item.get("公司名稱", "N/A") pledged_percentage = item.get("質權設定占實際持有股數百分比", "N/A") result += f"- {company_name} ({company_code}): {pledged_percentage}%\n" return result except Exception as e: return f"查詢失敗: {str(e)}" @mcp.tool def get_companies_cumulative_voting() -> str: """Get companies that use cumulative voting, full roll-call voting, or nominee nomination systems for electing directors and supervisors.""" try: data = TWSEAPIClient.get_data("/opendata/t187ap34_L") if not data: return "目前沒有資料。" result = f"共有 {len(data)} 筆採累積投票制、全額連記法、候選人提名制選任董監事資料:\n\n" for item in data: company_code = item.get("公司代號", "N/A") company_name = item.get("公司名稱", "N/A") voting_system = item.get("選任方式", "N/A") result += f"- {company_name} ({company_code}): {voting_system}\n" return result except Exception as e: return f"查詢失敗: {str(e)}" @mcp.tool def get_company_shareholder_proposal_exercise() -> str: """Get information about shareholder exercise of proposal rights.""" try: data = TWSEAPIClient.get_data("/opendata/t187ap35_L") if not data: return "目前沒有資料。" result = f"共有 {len(data)} 筆股東行使提案權情形資料:\n\n" for item in data: company_code = item.get("公司代號", "N/A") company_name = item.get("公司名稱", "N/A") proposal_count = item.get("提案總件數", "N/A") adopted_count = item.get("通過件數", "N/A") result += f"- {company_name} ({company_code}): {adopted_count}/{proposal_count} 件通過\n" return result except Exception as e: return f"查詢失敗: {str(e)}"

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/twjackysu/TWSEMCPServer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server