# Directory Structure ``` ├── .gitignore ├── .python-version ├── autocad_manager.py ├── CAD-mpc简单实现.mp4 ├── db_manager.py ├── main.py ├── pyproject.toml ├── README (2).md ├── README.md ├── requirements.txt ├── server.py ├── server.spec └── uv.lock ``` # Files -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- ``` 1 | 3.13 2 | ``` -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- ``` 1 | Python 2 | pycache/ 3 | *.py[cod] 4 | *$py.class 5 | *.so 6 | .Python 7 | env/ 8 | build/ 9 | develop-eggs/ 10 | dist/ 11 | downloads/ 12 | eggs/ 13 | .eggs/ 14 | lib/ 15 | lib64/ 16 | parts/ 17 | sdist/ 18 | var/ 19 | *.egg-info/ 20 | .installed.cfg 21 | *.egg 22 | .env 23 | .venv 24 | venv/ 25 | ENV/ 26 | PyInstaller 27 | dist/ 28 | build/ 29 | Database 30 | *.db 31 | *.sqlite 32 | *.sqlite3 33 | AutoCAD files 34 | *.dwg 35 | *.dxf 36 | *.bak 37 | IDE files 38 | .idea/ 39 | .vscode/ 40 | *.swp 41 | *.swo 42 | OS specific 43 | .DS_Store 44 | Thumbs.db 45 | ``` -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- ``` 1 | mcp>=1.2.0 2 | pywin32 3 | comtypes 4 | pyautocad 5 | sqlalchemy 6 | pyinstaller ``` -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- ```python 1 | def main(): 2 | print("Hello from autocad-mcp-server!") 3 | 4 | 5 | if __name__ == "__main__": 6 | main() 7 | ``` -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- ```toml 1 | [project] 2 | name = "autocad-mcp-server" 3 | version = "0.1.0" 4 | description = "Add your description here" 5 | readme = "README.md" 6 | requires-python = ">=3.13" 7 | dependencies = [ 8 | "comtypes>=1.4.10", 9 | "mcp[cli]>=1.4.1", 10 | "psycopg2-binary>=2.9.10", 11 | "pyautocad>=0.2.0", 12 | "pyinstaller>=6.12.0", 13 | "pywin32>=309", 14 | "sqlalchemy>=2.0.39", 15 | ] 16 | ``` -------------------------------------------------------------------------------- /db_manager.py: -------------------------------------------------------------------------------- ```python 1 | from sqlalchemy import create_engine, MetaData, Table, Column, inspect 2 | from sqlalchemy.exc import SQLAlchemyError 3 | 4 | 5 | class DatabaseManager: 6 | def __init__(self, connection_string): 7 | """初始化数据库连接管理器""" 8 | self.connection_string = connection_string 9 | self.engine = None 10 | self.metadata = None 11 | self.inspector = None 12 | 13 | def connect(self): 14 | """连接到数据库""" 15 | try: 16 | self.engine = create_engine(self.connection_string) 17 | self.metadata = MetaData() 18 | self.metadata.reflect(bind=self.engine) 19 | self.inspector = inspect(self.engine) 20 | return True 21 | except Exception as e: 22 | print(f"数据库连接失败: {str(e)}") 23 | return False 24 | 25 | def disconnect(self): 26 | """断开数据库连接""" 27 | if self.engine: 28 | self.engine.dispose() 29 | 30 | def get_all_tables(self): 31 | """获取所有表名""" 32 | try: 33 | return self.inspector.get_table_names() 34 | except SQLAlchemyError as e: 35 | return f"获取表列表失败: {str(e)}" 36 | 37 | def get_table_schema(self, table_name): 38 | """获取指定表的结构信息""" 39 | try: 40 | if table_name not in self.metadata.tables: 41 | return f"表 '{table_name}' 不存在" 42 | 43 | columns = [] 44 | for column in self.inspector.get_columns(table_name): 45 | columns.append({ 46 | "name": column['name'], 47 | "type": str(column['type']), 48 | "nullable": column['nullable'], 49 | "default": str(column['default']) if column['default'] else None 50 | }) 51 | 52 | # 获取主键 53 | primary_keys = self.inspector.get_pk_constraint(table_name) 54 | 55 | # 获取外键 56 | foreign_keys = [] 57 | for fk in self.inspector.get_foreign_keys(table_name): 58 | foreign_keys.append({ 59 | "name": fk['name'], 60 | "referred_table": fk['referred_table'], 61 | "referred_columns": fk['referred_columns'], 62 | "constrained_columns": fk['constrained_columns'] 63 | }) 64 | 65 | # 获取索引 66 | indices = [] 67 | for index in self.inspector.get_indexes(table_name): 68 | indices.append({ 69 | "name": index['name'], 70 | "columns": index['column_names'], 71 | "unique": index['unique'] 72 | }) 73 | 74 | return { 75 | "table_name": table_name, 76 | "columns": columns, 77 | "primary_key": primary_keys, 78 | "foreign_keys": foreign_keys, 79 | "indices": indices 80 | } 81 | except SQLAlchemyError as e: 82 | return f"获取表 '{table_name}' 结构失败: {str(e)}" 83 | 84 | def execute_query(self, query, params=None): 85 | """执行自定义查询""" 86 | try: 87 | with self.engine.connect() as connection: 88 | if params: 89 | result = connection.execute(query, params) 90 | else: 91 | result = connection.execute(query) 92 | 93 | # 检查是否是SELECT查询 94 | if result.returns_rows: 95 | columns = result.keys() 96 | rows = [dict(zip(columns, row)) for row in result] 97 | return {"columns": columns, "rows": rows} 98 | else: 99 | return {"affected_rows": result.rowcount} 100 | except SQLAlchemyError as e: 101 | return f"执行查询失败: {str(e)}" ```