> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended** (the `-y` flags skip prompts, so the command runs without an interactive terminal):
> ```bash
> npx -y @scalekit-inc/cli setup -y
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup -y
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for other Agent Skills-compatible agents in `~/.agents/skills`.
> Skills: integrate-agentkit, implement-saaskit, add-mcp-oauth, implement-sso, implement-scim.
> [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Connect AI agents to OneNote

The OneNote connector lets your AI agent act in each user's OneNote account. Each user signs in to OneNote once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 13 tools.

**Authentication:** OAuth 2.0
**Categories:** Files & Documents
**Tools:** 13: 6 read, 6 write, 1 destructive
**Users sign in with:** OAuth
**OAuth app:** Scalekit's or your own
**Built by:** Scalekit connector
**Try it:** [Playground in the Scalekit dashboard](https://app.scalekit.com/ws/signup?sk_intent=playground&provider=ONENOTE)

## Setup

1. ### Install the SDK

   **Node.js**

   ```bash
   npm install @scalekit-sdk/node dotenv
   ```

   **Python**

   ```bash
   pip install scalekit-sdk-python python-dotenv
   ```

2. ### Set your credentials

   Add your Scalekit credentials to your `.env` file. Find values in **[app.scalekit.com](https://app.scalekit.com)** > **Developers** > **API Credentials**.

   ```sh title=".env"
   SCALEKIT_ENVIRONMENT_URL=<your-environment-url>
   SCALEKIT_CLIENT_ID=<your-client-id>
   SCALEKIT_CLIENT_SECRET=<your-client-secret>
   ```

3. ### Create the OneNote connection

   In **AgentKit > Connections**, create an OneNote connection. The name you give it is the `connection_name` your code passes. See [Configure connections](/agentkit/connections/).

   Scalekit credentials are available for OneNote, so you don't need to register an OAuth app. To show your own app on the consent screen, use your own credentials instead.

   **Use your own OAuth app:**

   Register your Scalekit environment with the Microsoft OneNote connector so Scalekit handles the authentication flow and token lifecycle for you. The connection name you create will be used to identify and invoke the connection programmatically. Then complete the configuration in your application as follows:

   1. ### Create the OneNote connection in Scalekit

      - In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections** > **Create Connection**. Search for **OneNote** and click **Create**.

        > Image: Search for OneNote and create a new connection

      - In the **Configure OneNote Connection** dialog, copy the **Redirect URI**. You will need this when registering your app in Azure.

        > Image: Copy the redirect URI from the Configure OneNote Connection dialog

   2. ### Register an application in Azure

      - Sign into [portal.azure.com](https://portal.azure.com) and go to **Microsoft Entra ID** → **App registrations**.

        > Image: App registrations page in Azure portal

      - Click **New registration**. Enter a name for your app (for example, "Scalekit_Agent_Actions").

      - Under **Supported account types**, select **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts**.

      - Under **Redirect URI**, select **Web** and paste the redirect URI you copied from the Scalekit dashboard. Click **Register**.

        > Image: Register an application with the Scalekit redirect URI in Azure

   3. ### Get your client credentials

      - From the app's **Overview** page, copy the **Application (client) ID**.

        > Image: Copy the Application (client) ID from the Azure app overview

      - Go to **Certificates & secrets** in the left sidebar, then click **+ New client secret**.

        > Image: Certificates and secrets page in Azure portal

      - Enter a description, set an expiry period, and click **Add**. Copy the secret **Value** immediately — it is only shown once.

        > Image: Add a client secret in Azure portal

   4. ### Add credentials in Scalekit

      - In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections** and open the OneNote connection you created.

      - Enter your credentials:
        - **Client ID** — the Application (client) ID from the Azure app overview
        - **Client Secret** — the secret value from Certificates & secrets
        - **Scopes** — select the permissions your app needs (for example, `Notes.ReadWrite`, `User.Read`, `email`, `openid`, `profile`, `offline_access`). See [Microsoft Graph permissions reference](https://learn.microsoft.com/en-us/graph/permissions-reference) for the full list.

      - Click **Save**.

4. ### Authorize a user and make your first call

   **Node.js** (`quickstart.mts`)

   ```typescript
   import { ScalekitClient } from '@scalekit-sdk/node'
   import 'dotenv/config'
   import { createInterface } from 'node:readline/promises'

   const scalekit = new ScalekitClient(
     process.env.SCALEKIT_ENVIRONMENT_URL,
     process.env.SCALEKIT_CLIENT_ID,
     process.env.SCALEKIT_CLIENT_SECRET,
   )
   const actions = scalekit.actions

   const connector = 'onenote'
   const identifier = 'user_123'

   // Generate an authorization link for the user
   const { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })
   console.log('Authorize OneNote:', link)
   const rl = createInterface({ input: process.stdin, output: process.stdout })
   await rl.question('Press Enter after authorizing...')
   rl.close()

   // Make your first call
   const result = await actions.executeTool({
     connector,
     identifier,
     toolName: 'onenote_list_notebooks',
     toolInput: {},
   })
   console.log(result)
   ```

   ```bash
   npx tsx quickstart.mts
   ```

   **Python** (`quickstart.py`)

   ```python
   import os
   from scalekit import ScalekitClient
   from dotenv import load_dotenv
   load_dotenv()

   scalekit_client = ScalekitClient(
       env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"),
       client_id=os.getenv("SCALEKIT_CLIENT_ID"),
       client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
   )
   actions = scalekit_client.actions

   connection_name = "onenote"
   identifier = "user_123"

   # Generate an authorization link for the user
   link_response = actions.get_authorization_link(
       connection_name=connection_name,
       identifier=identifier,
   )
   print("Authorize OneNote:", link_response.link)
   input("Press Enter after authorizing...")

   # Make your first call
   result = actions.execute_tool(
       tool_input={},
       tool_name="onenote_list_notebooks",
       connection_name=connection_name,
       identifier=identifier,
   )
   print(result)
   ```

   ```bash
   python quickstart.py
   ```

   Each user signs in once. See [Authorize a user](/agentkit/tools/authorize/) for the full flow and statuses.

## Tools

Pass the exact name to `execute_tool`, with an input like each tool's example. To ask for a tool that's missing, use the [request form](https://scalekitsupport.portal.usepylon.com/forms/request-a-connector-tool).

**Node.js**

```typescript
const result = await actions.executeTool({
  toolName: 'onenote_get_page_content',
  toolInput: {
    page_id: '<page_id>',
  },
  connector: 'onenote',
  identifier: 'user_123',
})
```

**Python**

```python
result = actions.execute_tool(
    tool_name="onenote_get_page_content",
    tool_input={
        "page_id": "<page_id>",
    },
    connection_name="onenote",
    identifier="user_123",
)
```

`result.data` is the app's response as JSON, and `result.execution_id` (`executionId` in Node.js) is the ID of the call.

### `onenote_get_page_content`

Get Page Content · Read-only

Retrieve the full HTML content of a OneNote page by page ID. Returns raw HTML (Content-Type: text/html), not JSON — the response body is the page's markup, including any embedded images as data URIs or object references. Set include_ids to true to have the server annotate elements with data-id attributes, which are required as the "target" of a subsequent onenote_update_page_content call. Requires Notes.Read, Notes.Create, or Notes.ReadWrite scope.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `page_id` (`string`, required): The unique ID of the OneNote page whose content to retrieve. Obtain page IDs from onenote_list_pages, onenote_search_pages, or onenote_create_page.
- `include_ids` (`boolean`, optional): When true, the returned HTML includes data-id attributes on elements so they can be targeted by a later onenote_update_page_content call. Default: false. Default: `false`.

Example input: `{"page_id":"<page_id>"}`

### `onenote_list_notebooks`

List Notebooks · Read-only

List all OneNote notebooks owned by or shared with the signed-in user. Returns each notebook's id, displayName, createdDateTime, lastModifiedDateTime, userRole, isShared, sectionsUrl, sectionGroupsUrl, and links (oneNoteWebUrl/oneNoteClientUrl). Default sort order is displayName ascending. Requires Notes.Create, Notes.Read, or Notes.ReadWrite scope.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `orderby` (`string`, optional): Value for the OData $orderby query parameter — the property to sort results by. Example: "displayName desc". The default sort order is "displayName asc".
- `select` (`string`, optional): Value for the OData $select query parameter — a comma-separated list of notebook properties to return. Example: "id,displayName,lastModifiedDateTime" reduces response payload.
- `top` (`integer`, optional): Value for the OData $top query parameter — the maximum number of notebooks to return per page. Accepts values 1–999.

Example input: `{}`

### `onenote_list_pages`

List Pages · Read-only

List the OneNote pages inside a specific section. Returns each page's id, title, createdByAppId, contentUrl, links, and lastModifiedDateTime. By default returns the top 20 pages ordered by lastModifiedDateTime descending; the maximum for top is 100. Use onenote_get_page_content to fetch a page's HTML body. Requires Notes.Read, Notes.Create, or Notes.ReadWrite scope.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `section_id` (`string`, required): The unique ID of the section whose pages to list. Obtain section IDs from onenote_list_sections or onenote_create_section.
- `filter` (`string`, optional): Value for the OData $filter query parameter — an expression to narrow results. Example: "contains(tolower(title),'standup')".
- `orderby` (`string`, optional): Value for the OData $orderby query parameter — the property to sort results by. Example: "title asc". The default sort order is "lastModifiedDateTime desc".
- `select` (`string`, optional): Value for the OData $select query parameter — a comma-separated list of page properties to return. Example: "id,title,lastModifiedDateTime" reduces response payload.
- `top` (`integer`, optional): Value for the OData $top query parameter — the maximum number of pages to return per page of results (default: 20). The server-enforced maximum is 100. Default: `20`.

Example input: `{"section_id":"<section_id>"}`

### `onenote_list_section_groups`

List Section Groups · Read-only

List the OneNote section groups (sectionGroup objects) inside a specific notebook. A section group is a folder-like container that can hold its own sections and nested section groups. Returns each section group's id, displayName, sectionsUrl, sectionGroupsUrl, createdDateTime, and lastModifiedDateTime. The default sort order is displayName asc. Requires Notes.Create, Notes.Read, or Notes.ReadWrite scope.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `notebook_id` (`string`, required): The unique ID of the notebook whose section groups to list. Obtain notebook IDs from onenote_list_notebooks or onenote_create_notebook.
- `filter` (`string`, optional): Value for the OData $filter query parameter — an expression to narrow results. Example: "displayName eq 'Archived'".
- `orderby` (`string`, optional): Value for the OData $orderby query parameter — the property to sort results by. Example: "lastModifiedDateTime desc". The default sort order is "displayName asc".
- `select` (`string`, optional): Value for the OData $select query parameter — a comma-separated list of section group properties to return. Example: "id,displayName,sectionsUrl" reduces response payload.
- `top` (`integer`, optional): Value for the OData $top query parameter — the maximum number of section groups to return per page. Accepts values 1–999.

Example input: `{"notebook_id":"<notebook_id>"}`

### `onenote_list_sections`

List Sections · Read-only

List the OneNote sections (onenoteSection objects) inside a specific notebook. Returns each section's id, displayName, isDefault, pagesUrl, createdDateTime, and lastModifiedDateTime. The default response expands parentNotebook. Requires Notes.Create, Notes.Read, or Notes.ReadWrite scope.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `notebook_id` (`string`, required): The unique ID of the notebook whose sections to list. Obtain notebook IDs from onenote_list_notebooks or onenote_create_notebook.
- `filter` (`string`, optional): Value for the OData $filter query parameter — an expression to narrow results. Example: "displayName eq 'Meeting Notes'".
- `orderby` (`string`, optional): Value for the OData $orderby query parameter — the property to sort results by. Example: "displayName asc" or "lastModifiedDateTime desc". The default sort order is "displayName asc".
- `select` (`string`, optional): Value for the OData $select query parameter — a comma-separated list of section properties to return. Example: "id,displayName,pagesUrl" reduces response payload.
- `top` (`integer`, optional): Value for the OData $top query parameter — the maximum number of sections to return per page. Accepts values 1–999.

Example input: `{"notebook_id":"<notebook_id>"}`

### `onenote_search_pages`

Search Pages by Title · Read-only

Search all of the signed-in user's OneNote pages (across every notebook and section) for pages whose title contains the given text. Implemented as an OData $filter using contains(tolower(title),'...'), so matching is case-insensitive as long as the query is passed in lowercase. To list pages within one specific section instead, use onenote_list_pages. Requires Notes.Read, Notes.Create, or Notes.ReadWrite scope.

Read only: yes. Destructive: no. Idempotent (safe to retry): yes.

Inputs:

- `query` (`string`, required): Text to search for in page titles. Pass lowercase for reliable matching, since the filter compares against a lowercased title (e.g. "standup" matches "Weekly Standup Notes").
- `select` (`string`, optional): Value for the OData $select query parameter — a comma-separated list of page properties to return. Example: "id,title,parentSection" reduces response payload.
- `top` (`integer`, optional): Value for the OData $top query parameter — the maximum number of matching pages to return. The server-enforced maximum is 100.

Example input: `{"query":"standup"}`

### `onenote_copy_page`

Copy Page · Write

Copy an existing OneNote page into a different section (including a section in a different notebook). This is an asynchronous Graph operation: a successful call returns 202 Accepted immediately with an Operation-Location header rather than the copied page itself; the copy completes shortly afterward in the background. Requires Notes.Create or Notes.ReadWrite scope.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `page_id` (`string`, required): The unique ID of the OneNote page to copy. Obtain page IDs from onenote_list_pages, onenote_search_pages, or onenote_create_page.
- `target_section_id` (`string`, required): The unique ID of the destination section to copy the page into. Obtain section IDs from onenote_list_sections or onenote_create_section.
- `group_id` (`string`, optional): The ID of the Microsoft 365 group that owns the destination section, if the destination section belongs to a group notebook rather than the signed-in user's own notebooks.

Example input: `{"page_id":"<page_id>","target_section_id":"<target_section_id>"}`

### `onenote_create_notebook`

Create Notebook · Write

Create a new OneNote notebook for the signed-in user. Notebook names must be unique within the user's OneNote, cannot exceed 128 characters, and cannot contain the characters ?*/:<>|'". Returns the new notebook object including its id and sectionsUrl. Requires Notes.Create or Notes.ReadWrite scope.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `display_name` (`string`, required): The display name for the new notebook. Must be unique among the user's notebooks, 128 characters or fewer, and cannot contain the characters ?*/:<>|'".

Example input: `{"display_name":"<display_name>"}`

### `onenote_create_page`

Create Page · Write

Create a new OneNote page in the specified section by posting well-formed HTML directly as the request body. Content-Type is text/html (application/xhtml+xml is also accepted by the Graph API) — the body must be valid XHTML-compliant markup (properly closed/nested tags), not JSON. Use a <title> element inside <head> to set the page title, and a <meta name="created" content="..."/> tag to set the creation date. This tool only supports plain HTML (including remote image URLs); pages that embed binary image/file data require a multipart/form-data request, which is not supported by this tool. Requires Notes.Create or Notes.ReadWrite scope.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `html_content` (`string`, required): Well-formed XHTML-compliant HTML for the new page, including the <html>, <head>, and <body> elements. Example: "<!DOCTYPE html><html><head><title>Meeting Notes</title></head><body>Agenda items...
</body></html>". Remote image URLs are allowed in <img src="https://...">; embedded binary data is not supported by this tool.
- `section_id` (`string`, required): The unique ID of the section in which to create the new page. Obtain section IDs from onenote_list_sections or onenote_create_section.

Example input: `{"html_content":"<!DOCTYPE html><html><head><title>Meeting Notes</title></head><body><p>Agenda items...</p></body></html>","section_id":"<section_id>"}`

### `onenote_create_section`

Create Section · Write

Create a new OneNote section inside the specified notebook. Section names must be unique within the same hierarchy level, cannot exceed 50 characters, and cannot contain the characters ?*/:<>|'%~. Returns the new onenoteSection object including its id and pagesUrl. Requires Notes.Create or Notes.ReadWrite scope.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `display_name` (`string`, required): The display name for the new section. Must be unique among the notebook's other sections, 50 characters or fewer, and cannot contain the characters ?*/:<>|'%~.
- `notebook_id` (`string`, required): The unique ID of the notebook in which to create the new section. Obtain notebook IDs from onenote_list_notebooks or onenote_create_notebook.

Example input: `{"display_name":"<display_name>","notebook_id":"<notebook_id>"}`

### `onenote_create_section_group`

Create Section Group · Write

Create a new section group directly inside the specified notebook. A section group is a folder-like container that can hold its own sections and nested section groups — useful for organizing many sections under one notebook. Section group names must be unique within the same hierarchy level, cannot exceed 50 characters, and cannot contain the characters ?*/:<>|'%~. Returns the new sectionGroup object including its id, sectionsUrl, and sectionGroupsUrl. Requires Notes.Create or Notes.ReadWrite scope.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `display_name` (`string`, required): The display name for the new section group. Must be unique among the notebook's other section groups, 50 characters or fewer, and cannot contain the characters ?*/:<>|'%~.
- `notebook_id` (`string`, required): The unique ID of the notebook in which to create the new section group. Obtain notebook IDs from onenote_list_notebooks or onenote_create_notebook.

Example input: `{"display_name":"<display_name>","notebook_id":"<notebook_id>"}`

### `onenote_update_page_content`

Update Page Content · Write

Apply a single patchContentCommand to an existing OneNote page's content, per the Graph OneNote page-update semantics (a JSON array containing one command object with target/action/position/content). target must be the #<data-id> or generated <id> of an element from a onenote_get_page_content call made with include_ids=true, or the literal keyword "body" or "title". action is one of replace, append, delete, insert, or prepend. content must be well-formed HTML and is required for every action except delete. Binary image/file data in content is not supported by this tool (it would require a multipart/form-data request). On success, returns 204 No Content. Requires Notes.ReadWrite scope.

Read only: no. Destructive: no. Idempotent (safe to retry): no.

Inputs:

- `action` (`string`, required): The action to perform on the target element. One of: `replace`, `append`, `delete`, `insert`, `prepend`.
- `page_id` (`string`, required): The unique ID of the OneNote page to update. Obtain page IDs from onenote_list_pages, onenote_search_pages, or onenote_create_page.
- `target` (`string`, required): The element to update: the #<data-id> or generated <id> of an element (from a onenote_get_page_content call with include_ids=true), or the literal keyword "body" or "title".
- `content` (`string`, optional): A string of well-formed HTML to add to the page. Required for the replace, append, insert, and prepend actions; ignored for delete.
- `position` (`string`, optional): The location to add the supplied content, relative to the target element. Possible values: after (default) or before. One of: `after`, `before`. Default: `after`.

Example input: `{"action":"replace","page_id":"<page_id>","target":"<target>"}`

### `onenote_delete_page`

Delete Page · Destructive

Permanently delete a OneNote page by page ID. This action cannot be undone through the API. On success, returns 204 No Content. Requires Notes.ReadWrite scope.

Read only: no. Destructive: yes. Idempotent (safe to retry): no.

Inputs:

- `page_id` (`string`, required): The unique ID of the OneNote page to delete. Obtain page IDs from onenote_list_pages, onenote_search_pages, or onenote_create_page.

Example input: `{"page_id":"<page_id>"}`

## Workflows

**Proxy API call**

  **Node.js**

  ```typescript
  const result = await actions.request({
    connectionName: 'onenote',
    identifier: 'user_123',
    path: '/v1.0/me/onenote/notebooks',
    method: 'GET',
  });
  console.log(result);
  ```

  **Python**

  ```python
  result = actions.request(
      connection_name='onenote',
      identifier='user_123',
      path="/v1.0/me/onenote/notebooks",
      method="GET"
  )
  print(result)
  ```

## Related

Other Files & Documents connectors ([all 33](/agentkit/connectors/?category=files-documents)):

- [Google Drive](/agentkit/connectors/googledrive/): Scalekit connector, OAuth, 47 tools
- [Google Forms](/agentkit/connectors/googleforms/): Scalekit connector, OAuth, 10 tools
- [Microsoft 365](/agentkit/connectors/microsoft365/): Scalekit connector, OAuth, 317 tools


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
