AlexisLaporte / notion
Install for your project team
Run this command in your project directory to install the skill for your entire team:
mkdir -p .claude/skills/notion && curl -o .claude/skills/notion/SKILL.md https://fastmcp.me/Skills/DownloadRaw?id=334
Project Skills
This skill will be saved in .claude/skills/notion/ and checked into git. All team members will have access to it automatically.
Important: Please verify the skill by reviewing its instructions before using it.
Notion workspace integration. Use when user wants to read/write Notion pages, search databases, create tasks, or sync content with Notion.
0 views
0 installs
Skill Content
---
name: Notion
description: Notion workspace integration. Use when user wants to read/write Notion pages, search databases, create tasks, or sync content with Notion.
source: base
---
# Notion
Integrate with Notion workspaces to read and write content.
## When to Use
Use this skill when the user wants to:
- Read or search Notion pages
- Create or update pages and databases
- Query Notion databases
- Sync content to/from Notion
- Create tasks or notes in Notion
- Search across workspace
## Setup
### 1. Create Notion Integration
1. Go to https://www.notion.so/my-integrations
2. Click "New integration"
3. Give it a name and select workspace
4. Copy the "Internal Integration Token"
### 2. Share Pages with Integration
For each page/database you want to access:
1. Open the page in Notion
2. Click "Share" (top right)
3. Invite your integration
### 3. Store API Key
```bash
export NOTION_API_KEY="secret_xxxxx"
```
Or in `.env`:
```
NOTION_API_KEY=secret_xxxxx
```
## Installation
```bash
npm install @notionhq/client
```
Or Python:
```bash
pip install notion-client
```
## JavaScript Usage
```javascript
const { Client } = require('@notionhq/client');
const notion = new Client({ auth: process.env.NOTION_API_KEY });
// Search pages
const response = await notion.search({
query: 'Meeting Notes',
filter: { property: 'object', value: 'page' }
});
// Get page
const page = await notion.pages.retrieve({ page_id: 'PAGE_ID' });
// Create page
const newPage = await notion.pages.create({
parent: { database_id: 'DATABASE_ID' },
properties: {
Name: { title: [{ text: { content: 'New Page' } }] }
}
});
// Update page
await notion.pages.update({
page_id: 'PAGE_ID',
properties: {
Status: { select: { name: 'Done' } }
}
});
```
## Common Patterns
### Query Database
```javascript
const response = await notion.databases.query({
database_id: 'DATABASE_ID',
filter: {
property: 'Status',
select: { equals: 'In Progress' }
},
sorts: [
{ property: 'Created', direction: 'descending' }
]
});
for (const page of response.results) {
console.log(page.properties.Name.title[0].text.content);
}
```
### Read Page Content
```javascript
const blockId = 'PAGE_ID';
const response = await notion.blocks.children.list({ block_id: blockId });
for (const block of response.results) {
if (block.type === 'paragraph') {
const text = block.paragraph.rich_text[0]?.plain_text;
console.log(text);
}
}
```
### Create Page with Content
```javascript
const page = await notion.pages.create({
parent: { page_id: 'PARENT_PAGE_ID' },
properties: {
title: { title: [{ text: { content: 'Meeting Notes' } }] }
},
children: [
{
object: 'block',
type: 'heading_2',
heading_2: {
rich_text: [{ type: 'text', text: { content: 'Agenda' } }]
}
},
{
object: 'block',
type: 'bulleted_list_item',
bulleted_list_item: {
rich_text: [{ type: 'text', text: { content: 'Item 1' } }]
}
}
]
});
```
### Append Blocks
```javascript
await notion.blocks.children.append({
block_id: 'PAGE_ID',
children: [
{
object: 'block',
type: 'paragraph',
paragraph: {
rich_text: [{ type: 'text', text: { content: 'New paragraph' } }]
}
}
]
});
```
## Python Usage
```python
from notion_client import Client
notion = Client(auth=os.environ["NOTION_API_KEY"])
# Query database
results = notion.databases.query(
database_id="DATABASE_ID",
filter={"property": "Status", "select": {"equals": "Done"}}
)
# Create page
new_page = notion.pages.create(
parent={"database_id": "DATABASE_ID"},
properties={
"Name": {"title": [{"text": {"content": "New Task"}}]},
"Status": {"select": {"name": "To Do"}}
}
)
```
## Database Properties
Common property types:
```javascript
properties: {
// Text
Name: { title: [{ text: { content: 'Title' } }] },
// Rich text
Description: { rich_text: [{ text: { content: 'Text' } }] },
// Number
Count: { number: 42 },
// Select
Status: { select: { name: 'In Progress' } },
// Multi-select
Tags: { multi_select: [{ name: 'urgent' }, { name: 'bug' }] },
// Date
DueDate: { date: { start: '2024-01-15' } },
// Checkbox
Done: { checkbox: true },
// URL
Link: { url: 'https://example.com' },
// Email
Email: { email: 'user@example.com' },
// Phone
Phone: { phone_number: '+1234567890' }
}
```
## Block Types
```javascript
// Paragraph
{ type: 'paragraph', paragraph: { rich_text: [{ text: { content: 'Text' } }] } }
// Heading
{ type: 'heading_1', heading_1: { rich_text: [{ text: { content: 'Title' } }] } }
// Bulleted list
{ type: 'bulleted_list_item', bulleted_list_item: { rich_text: [{ text: { content: 'Item' } }] } }
// Code
{ type: 'code', code: { rich_text: [{ text: { content: 'code' } }], language: 'javascript' } }
// Divider
{ type: 'divider', divider: {} }
// To-do
{ type: 'to_do', to_do: { rich_text: [{ text: { content: 'Task' } }], checked: false } }
```
## Common Issues
**Unauthorized**: Integration not shared with page
```
Solution: Share page with integration via Share menu
```
**Rate limiting**: Too many requests
```javascript
// Add delays between requests
await new Promise(resolve => setTimeout(resolve, 300));
```
**Page not found**: Wrong ID or no access
```
Solution: Verify page_id and sharing permissions
```
## Best Practices
- Cache database structure to reduce API calls
- Use pagination for large result sets
- Handle rate limits with exponential backoff
- Validate property types before writing
- Use search sparingly (it's slow)
- Batch operations when possible
- Store IDs in config, not hardcoded
## Example: Sync Tasks
```javascript
async function syncTasks(tasks) {
const database_id = 'YOUR_DATABASE_ID';
for (const task of tasks) {
await notion.pages.create({
parent: { database_id },
properties: {
Name: { title: [{ text: { content: task.title } }] },
Status: { select: { name: task.status } },
DueDate: { date: { start: task.dueDate } }
}
});
// Rate limiting
await new Promise(resolve => setTimeout(resolve, 300));
}
}
```
## Resources
- Notion API: https://developers.notion.com
- JS SDK: https://github.com/makenotion/notion-sdk-js
- Python SDK: https://github.com/ramnes/notion-sdk-py
- API Reference: https://developers.notion.com/reference