Skip to main content
Glama
server.py5.04 kB
""" OneNote MCP Server - An MCP implementation for browsing and interacting with OneNote web app. This MCP server provides the ability to browse and interact with a shared OneNote notebook via browser-use automation. It allows operations like reading pages, navigating to specific sections, adding notes, and more. Usage: uvx install-local-mcp-server --path /path/to/this/directory # Or to run manually: uv sync --all-extras python -m onenote_mcp """ import asyncio import json import logging import os import sys from typing import Dict, List, Optional, Any, Tuple, Union from pathlib import Path # Import MCP SDK from mcp.server.fastmcp import FastMCP # Import browser-use from browser_use import Agent, Controller from browser_use.agent.views import ActionResult from browser_use.browser.browser import Browser, BrowserConfig from browser_use.browser.context import BrowserContext # Configure logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[logging.StreamHandler()] ) logger = logging.getLogger("onenote-mcp") # Create MCP server mcp = FastMCP("onenote_mcp") # Initialize browser and controller browser = Browser( config=BrowserConfig( headless=False, # Set to True for headless mode in production ) ) controller = Controller() # Global state active_browser_context = None active_agent = None onenote_url = None class OneNoteState: """Store state information about the OneNote session.""" def __init__(self): self.current_notebook = None self.current_section = None self.current_page = None self.all_notebooks = [] self.all_sections = [] self.all_pages = [] self.last_action_result = None def to_dict(self): """Convert state to a dictionary.""" return { "current_notebook": self.current_notebook, "current_section": self.current_section, "current_page": self.current_page, "all_notebooks": self.all_notebooks, "all_sections": self.all_sections, "all_pages": self.all_pages, "last_action_result": self.last_action_result, } # Initialize state onenote_state = OneNoteState() async def get_or_create_browser_context() -> BrowserContext: """Get existing browser context or create a new one.""" global active_browser_context if active_browser_context is None: active_browser_context = await browser.new_context() return active_browser_context @controller.action("Get all notebooks in the current OneNote") async def get_notebooks(browser: BrowserContext) -> ActionResult: """Get all notebooks in the current OneNote view.""" notebooks = [] try: # Based on your screenshot, we may need to look for different selectors # Try multiple possible selectors for notebook names # First try the standard selector try: await browser.session.wait_for_selector(".NotebookName, .Notebook, #NotebooksNavigationContainer li", timeout=5000) # Try different possible selectors for selector in [".NotebookName", ".Notebook", "#NotebooksNavigationContainer li", ".TreeNodeContent"]: elements = await browser.session.query_selector_all(selector) if elements and len(elements) > 0: for element in elements: text = await element.text_content() if text and text.strip(): notebooks.append(text.strip()) # If we found notebooks, we can break the loop if notebooks: break except Exception as e: logger.warning(f"Standard notebook selectors failed: {str(e)}") # If standard selectors fail, try to get all list items in the navigation area # This is a fallback approach elements = await browser.session.query_selector_all("li") for element in elements: text = await element.text_content() # Check if this looks like a notebook name (not too long, not empty) if text and text.strip() and len(text.strip()) < 50: notebooks.append(text.strip()) # Attempt to filter and deduplicate notebooks if notebooks: # Remove duplicates notebooks = list(dict.fromkeys(notebooks)) result = f"Found notebooks: {', '.join(notebooks)}" onenote_state.all_notebooks = notebooks return ActionResult(extracted_content=result, include_in_memory=True) else: logger.warning("No notebooks found with any selector") # Last resort: take a screenshot to help diagnose the issue screenshot_path = "notebooks_view.png"

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/hwillGIT/onenote-mcp'

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