From 738e5fc9912f7b807e7541bbdca8014bad9f5d2e Mon Sep 17 00:00:00 2001 From: ben Date: Mon, 2 Feb 2026 08:49:17 +0000 Subject: [PATCH] =?UTF-8?q?feat(notion):=20=E6=B7=BB=E5=8A=A0Notion?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E9=9B=86=E6=88=90=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=92=8C=E7=9B=B8=E5=85=B3=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加Notion数据库集成配置和访问脚本,包括: - 配置Notion MCP服务器设置 - 添加数据库查询、内容查看和添加功能 - 创建测试脚本和集成文档 --- NOTION_INTEGRATION.md | 47 ++++++++++++++++ README.md | 11 +++- add_notion_content.py | 85 ++++++++++++++++++++++++++++ mcp_settings.json | 103 ++++++++++++++++++++++++++++++++++ notion_database_access.py | 95 +++++++++++++++++++++++++++++++ scripts/test-api-endpoints.sh | 44 +++++++++++++++ view_database_content.py | 59 +++++++++++++++++++ 7 files changed, 443 insertions(+), 1 deletion(-) create mode 100644 NOTION_INTEGRATION.md create mode 100644 add_notion_content.py create mode 100644 mcp_settings.json create mode 100644 notion_database_access.py create mode 100755 scripts/test-api-endpoints.sh create mode 100644 view_database_content.py diff --git a/NOTION_INTEGRATION.md b/NOTION_INTEGRATION.md new file mode 100644 index 0000000..d8e1357 --- /dev/null +++ b/NOTION_INTEGRATION.md @@ -0,0 +1,47 @@ +# Notion 数据库集成 + +此项目已配置为通过 Model Context Protocol (MCP) 与 Notion 数据库进行集成。 + +## 配置详情 + +已在 `mcp_settings.json` 中添加了 Notion 服务器配置: + +```json +"notion": { + "command": "npx", + "args": [ + "-y", + "@notionhq/notion-mcp-server" + ], + "env": { + "OPENAPI_MCP_HEADERS": "{\"Authorization\": \"Bearer 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\", \"Notion-Version\": \"2022-06-28\"}" + } +} +``` + +## 使用方法 + +### 1. 运行 Notion 数据库访问脚本 + +```bash +python notion_database_access.py +``` + +这将显示所有可访问的 Notion 数据库及其详细信息。 + +### 2. 手动测试 API + +您也可以使用以下命令测试 API 连接: + +```bash +curl -H "Authorization: Bearer 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" \ + -H "Content-Type: application/json" \ + -H "Notion-Version: 2022-06-28" \ + https://api.notion.com/v1/users/me +``` + +## 注意事项 + +- 确保您的 Notion 集成已正确连接到所需的页面 +- 请妥善保管您的 API 密钥 +- 如果遇到权限错误,请检查 Notion 集成的权限设置 \ No newline at end of file diff --git a/README.md b/README.md index 52d3a57..2151dcf 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,12 @@ # 项目说明 -这是一个概念验证项目,旨在通过控制我不方便控制的阿里巴巴的 DSW WebIDE,让它当牛马,它上面已经运行了 runner。 \ No newline at end of file +"notion": { + "command": "npx", + "args": [ + "-y", + "@notionhq/notion-mcp-server" + ], + "env": { + "OPENAPI_MCP_HEADERS": "{\"Authorization\": \"Bearer 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\", \"Notion-Version\": \"2022-06-28\"}" + } +} \ No newline at end of file diff --git a/add_notion_content.py b/add_notion_content.py new file mode 100644 index 0000000..876cbc7 --- /dev/null +++ b/add_notion_content.py @@ -0,0 +1,85 @@ +""" +Script to add sample content to your Notion database +""" + +import requests +import json + +class NotionDatabaseUpdater: + def __init__(self, integration_token="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"): + self.integration_token = integration_token + self.headers = { + "Authorization": f"Bearer {integration_token}", + "Content-Type": "application/json", + "Notion-Version": "2022-06-28" + } + self.base_url = "https://api.notion.com/v1" + + def create_page_in_database(self, database_id, page_title, additional_properties=None): + """Create a new page in the specified database""" + url = f"{self.base_url}/pages" + + # Basic structure for a page with a title + data = { + "parent": {"database_id": database_id}, + "properties": { + "名称": { # Assuming "名称" is the title property based on our earlier discovery + "title": [ + { + "text": { + "content": page_title + } + } + ] + } + } + } + + # Add any additional properties if provided + if additional_properties: + for prop_name, prop_value in additional_properties.items(): + data["properties"][prop_name] = prop_value + + response = requests.post(url, headers=self.headers, json=data) + if response.status_code == 200: + return response.json() + else: + print(f"Error creating page: {response.status_code} - {response.text}") + return None + +def main(): + # Initialize the updater + updater = NotionDatabaseUpdater() + + # Use the database ID we found earlier + database_id = "2fbdaaa6-ba07-804a-b48a-ce9c0a107416" + + # Create a sample page + sample_pages = [ + { + "title": "今天的工作计划", + "properties": {} + }, + { + "title": "学习新技能", + "properties": {} + }, + { + "title": "项目进展", + "properties": {} + } + ] + + print("正在向您的 Notion 数据库添加示例内容...") + + for page in sample_pages: + print(f"添加页面: {page['title']}") + result = updater.create_page_in_database(database_id, page['title'], page['properties']) + if result: + print(f" ✓ 页面创建成功! 页面ID: {result['id']}") + else: + print(f" ✗ 页面创建失败") + print() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/mcp_settings.json b/mcp_settings.json new file mode 100644 index 0000000..f646687 --- /dev/null +++ b/mcp_settings.json @@ -0,0 +1,103 @@ +{ + "mcpServers": { + "context7": { + "command": "npx", + "args": [ + "-y", + "@upstash/context7-mcp" + ], + "env": { + "DEFAULT_MINIMUM_TOKENS": "" + } + }, + "filesystem": { + "command": "npx", + "args": [ + "-y", + "@modelcontextprotocol/server-filesystem", + "./" + ], + "alwaysAllow": [ + "create_directory", + "write_file", + "edit_file" + ] + }, + "sequentialthinking": { + "command": "npx", + "args": [ + "-y", + "@modelcontextprotocol/server-sequential-thinking" + ] + }, + "memory": { + "command": "npx", + "args": [ + "-y", + "@modelcontextprotocol/server-memory" + ] + }, + "tavily": { + "command": "npx", + "args": [ + "-y", + "tavily-mcp@0.2.3" + ], + "env": { + "TAVILY_API_KEY": "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" + } + }, + "supabase": { + "command": "npx", + "args": [ + "-y", + "@supabase/mcp-server-supabase@0.5.5", + "--access-token", + "sbp_v0_cb9da057017b752cd9dbd232d92e482a123f787b" + ] + }, + "n8n-mcp": { + "command": "npx", + "args": [ + "-y", + "n8n-mcp@2.12.2" + ], + "env": { + "MCP_MODE": "stdio", + "LOG_LEVEL": "error", + "DISABLE_CONSOLE_OUTPUT": "true", + "N8N_API_KEY": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1ODY1YmU5Mi0wNGVkLTRiODItYjY4OC1hODc3ODZmYTZhYzQiLCJpc3MiOiJuOG4iLCJhdWQiOiJwdWJsaWMtYXBpIiwiaWF0IjoxNzY5ODMyNjY1fQ.hy-MEy2qZzipI42mHrWtWoWx3t2Cm5UXJnHUwt7zObM", + "N8N_HOST": "houzhongxu-n8n-free.hf.space", + "N8N_PROTOCOL": "https", + "N8N_PORT": "443" + }, + "alwaysAllow": [ + "get_database_statistics", + "list_nodes", + "search_templates" + ] + }, + "gitea": { + "command": "/home/ben/comfy/modelscope/gitea-mcp", + "args": [ + "-t", + "stdio", + "--host", + " `https://gitea.tailnet-68f9.ts.net` " + ], + "env": { + "GITEA_ACCESS_TOKEN": "8d7d70f324796be650b79415303c31f567bf459b" + } + }, + "notion": { + "command": "npx", + "args": [ + "-y", + "@notionhq/notion-mcp-server" + ], + "env": { + "OPENAPI_MCP_HEADERS": "{\"Authorization\": \"Bearer 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\", \"Notion-Version\": \"2022-06-28\"}" + } + } + } +} \ No newline at end of file diff --git a/notion_database_access.py b/notion_database_access.py new file mode 100644 index 0000000..420ddcd --- /dev/null +++ b/notion_database_access.py @@ -0,0 +1,95 @@ +""" +Notion Database Access Script +This script demonstrates how to connect to and access your Notion database +using the Notion API with the configuration you have set up. +""" + +import requests +import json + +class NotionDatabaseAccess: + def __init__(self, integration_token="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"): + self.integration_token = integration_token + self.headers = { + "Authorization": f"Bearer {integration_token}", + "Content-Type": "application/json", + "Notion-Version": "2022-06-28" + } + self.base_url = "https://api.notion.com/v1" + + def list_databases(self): + """List all databases accessible with the integration token""" + url = f"{self.base_url}/search" + payload = { + "filter": { + "property": "object", + "value": "database" + } + } + + response = requests.post(url, headers=self.headers, json=payload) + if response.status_code == 200: + return response.json() + else: + print(f"Error: {response.status_code} - {response.text}") + return None + + def query_database(self, database_id): + """Query a specific database by ID""" + url = f"{self.base_url}/databases/{database_id}/query" + response = requests.post(url, headers=self.headers) + if response.status_code == 200: + return response.json() + else: + print(f"Error querying database: {response.status_code} - {response.text}") + return None + + def get_database_info(self, database_id): + """Get information about a specific database""" + url = f"{self.base_url}/databases/{database_id}" + response = requests.get(url, headers=self.headers) + if response.status_code == 200: + return response.json() + else: + print(f"Error getting database info: {response.status_code} - {response.text}") + return None + +def main(): + # Initialize the Notion database access + notion = NotionDatabaseAccess() + + print("Connecting to your Notion account...") + print("Searching for accessible databases...") + + # List all databases + databases_result = notion.list_databases() + + if databases_result and 'results' in databases_result: + databases = databases_result['results'] + + if databases: + print(f"\nFound {len(databases)} database(s):\n") + + for db in databases: + db_id = db['id'] + db_title = ''.join([title.get('plain_text', '') for title in db.get('title', [])]) + + print(f"Database ID: {db_id}") + print(f"Title: {db_title}") + print("-" * 50) + + # Get detailed info about each database + db_info = notion.get_database_info(db_id) + if db_info: + print(f"Description: {''.join([desc.get('plain_text', '') for desc in db_info.get('description', [])])}") + print(f"Properties:") + for prop_name, prop_info in db_info.get('properties', {}).items(): + print(f" - {prop_name}: {prop_info.get('type', 'unknown')}") + print() + else: + print("No databases found. Make sure your integration is properly connected to your Notion pages.") + else: + print("Failed to retrieve databases. Check your integration token and permissions.") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/scripts/test-api-endpoints.sh b/scripts/test-api-endpoints.sh new file mode 100755 index 0000000..ca7ac3a --- /dev/null +++ b/scripts/test-api-endpoints.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# 配置信息 +GITEA_URL="https://gitea.tailnet-68f9.ts.net" +TOKEN="8d7d70f324796be650b79415303c31f567bf459b" + +# 函数:测试API端点 +function test_endpoint() { + local endpoint=$1 + echo "测试端点: $endpoint" + + response=$(curl -s -w "\n%{http_code}" \ + -H "Authorization: token $TOKEN" \ + "$GITEA_URL$endpoint") + + # 分离响应内容和HTTP状态码 + http_status=$(echo "$response" | tail -n1) + response_body=$(echo "$response" | sed '$d') + + echo "HTTP状态码: $http_status" + if [ "$http_status" -eq 200 ]; then + echo "✓ 成功 - 响应: $response_body" + elif [ "$http_status" -eq 404 ]; then + echo "✗ 未找到" + elif [ "$http_status" -eq 403 ] || [ "$http_status" -eq 401 ]; then + echo "✗ 访问被拒绝 (可能权限不足)" + else + echo "✗ 其他错误 - 响应: $response_body" + fi + echo "---" +} + +echo "=== 测试Gitea Actions Runner API端点 ===" +echo "" + +# 测试可能的API端点 +test_endpoint "/api/v1/actions/runners" +test_endpoint "/api/v1/actions/runners/5" +test_endpoint "/api/v1/admin/runners" +test_endpoint "/api/v1/admin/runners/5" +test_endpoint "/api/v1/user/actions/runners" +test_endpoint "/api/v1/user/actions/runners/5" +test_endpoint "/api/v1/users/ben/actions/runners" +test_endpoint "/api/v1/repos/ben/modelscope/actions/runners" \ No newline at end of file diff --git a/view_database_content.py b/view_database_content.py new file mode 100644 index 0000000..6d040f2 --- /dev/null +++ b/view_database_content.py @@ -0,0 +1,59 @@ +""" +Script to view content in your Notion database +""" + +import requests +import json + +class NotionDatabaseViewer: + def __init__(self, integration_token="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"): + self.integration_token = integration_token + self.headers = { + "Authorization": f"Bearer {integration_token}", + "Content-Type": "application/json", + "Notion-Version": "2022-06-28" + } + self.base_url = "https://api.notion.com/v1" + + def query_database(self, database_id): + """Query a specific database to get its content""" + url = f"{self.base_url}/databases/{database_id}/query" + response = requests.post(url, headers=self.headers, json={}) + if response.status_code == 200: + return response.json() + else: + print(f"Error querying database: {response.status_code} - {response.text}") + return None + +def main(): + # Initialize the viewer + viewer = NotionDatabaseViewer() + + # Use the database ID we found earlier + database_id = "2fbdaaa6-ba07-804a-b48a-ce9c0a107416" + + print("正在查询数据库内容...") + result = viewer.query_database(database_id) + + if result and 'results' in result: + pages = result['results'] + print(f"在数据库中找到 {len(pages)} 个页面:\n") + + for page in pages: + page_id = page['id'] + # Extract the title from the page properties + title_property = page['properties'].get('名称', {}) + if title_property and 'title' in title_property: + title_parts = title_property['title'] + page_title = ''.join([part.get('text', {}).get('content', '') for part in title_parts]) + else: + page_title = "[无标题]" + + print(f"页面ID: {page_id}") + print(f"标题: {page_title}") + print("-" * 50) + else: + print("未能检索到数据库内容") + +if __name__ == "__main__": + main() \ No newline at end of file