Skip to content

Commit 7e254df

Browse files
authored
feat: Add retrieve database endpoint to OpenAPI spec (#195)
1 parent f4a87aa commit 7e254df

File tree

5 files changed

+144
-8
lines changed

5 files changed

+144
-8
lines changed

CLAUDE.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance for Claude Code when working with this repository.
4+
5+
## Project Overview
6+
7+
This is the Notion MCP Server - an [MCP (Model Context Protocol)](https://spec.modelcontextprotocol.io/) server that exposes the [Notion API](https://developers.notion.com/reference/intro) as MCP tools. It auto-generates tools from an OpenAPI specification.
8+
9+
## Architecture
10+
11+
```
12+
scripts/notion-openapi.json # OpenAPI spec (source of truth for all tools)
13+
14+
src/init-server.ts # Loads & validates spec, creates MCPProxy
15+
16+
src/openapi-mcp-server/
17+
├── openapi/parser.ts # Converts OpenAPI → MCP tools
18+
├── mcp/proxy.ts # Registers tools with MCP server
19+
└── client/http-client.ts # Executes API calls
20+
```
21+
22+
## Key Patterns
23+
24+
### Adding New Endpoints
25+
26+
Only modify `scripts/notion-openapi.json`. Tools are auto-generated from the spec - no code changes needed elsewhere.
27+
28+
### Tool Generation Flow
29+
30+
1. `OpenAPIToMCPConverter.convertToMCPTools()` iterates all paths/operations
31+
2. Each operation becomes an MCP tool (name = `operationId`)
32+
3. Parameters + requestBody → `inputSchema`
33+
4. Response schema → `returnSchema`
34+
5. `MCPProxy.setupHandlers()` registers tools with the MCP SDK
35+
36+
### Naming Conventions
37+
38+
- Tool names come from OpenAPI `operationId` (e.g., `retrieve-a-database`)
39+
- Names are truncated to 64 chars and converted to title case for display
40+
41+
## Common Commands
42+
43+
```bash
44+
npm run build # TypeScript compilation + CLI bundling
45+
npm test # Run vitest tests
46+
npm run dev # Start dev server with hot reload
47+
```
48+
49+
## File Structure
50+
51+
- `scripts/notion-openapi.json` - OpenAPI 3.1.0 spec defining all Notion API endpoints
52+
- `scripts/start-server.ts` - Entry point
53+
- `src/init-server.ts` - Server initialization
54+
- `src/openapi-mcp-server/` - Core MCP server implementation
55+
- `openapi/parser.ts` - OpenAPI to MCP conversion (529 lines)
56+
- `mcp/proxy.ts` - MCP tool registration and execution (209 lines)
57+
- `client/http-client.ts` - HTTP request execution (198 lines)
58+
59+
## Testing
60+
61+
Tests are in `__tests__` directories adjacent to source files. Run with `npm test`.
62+
63+
## API Version
64+
65+
Uses Notion API version `2025-09-03` (Data Source Edition). The spec includes both:
66+
- `/v1/databases/{database_id}` - Traditional database endpoints
67+
- `/v1/data_sources/{data_source_id}` - New data source endpoints

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,21 @@ This project implements an [MCP server](https://spec.modelcontextprotocol.io/) f
2929

3030
### What changed
3131

32-
**Removed tools (4):**
32+
**Removed tools (3):**
3333

3434
- `post-database-query` - replaced by `query-data-source`
35-
- `retrieve-a-database` - replaced by `retrieve-a-data-source`
3635
- `update-a-database` - replaced by `update-a-data-source`
3736
- `create-a-database` - replaced by `create-a-data-source`
3837

39-
**New tools (6):**
38+
**New tools (7):**
4039

4140
- `query-data-source` - Query a data source (database) with filters and sorts
4241
- `retrieve-a-data-source` - Get metadata and schema for a data source
4342
- `update-a-data-source` - Update data source properties
4443
- `create-a-data-source` - Create a new data source
4544
- `list-data-source-templates` - List available templates in a data source
4645
- `move-page` - Move a page to a different parent location
46+
- `retrieve-a-database` - Get database metadata including its data source IDs
4747

4848
**Parameter changes:**
4949

@@ -60,11 +60,12 @@ If you have hardcoded tool names or prompts that reference the old database tool
6060
| Old Tool (v1.x) | New Tool (v2.0) | Parameter Change |
6161
| -------------- | --------------- | ---------------- |
6262
| `post-database-query` | `query-data-source` | `database_id``data_source_id` |
63-
| `retrieve-a-database` | `retrieve-a-data-source` | `database_id``data_source_id` |
6463
| `update-a-database` | `update-a-data-source` | `database_id``data_source_id` |
6564
| `create-a-database` | `create-a-data-source` | No change (uses `parent.page_id`) |
6665

67-
**Total tools now: 21** (was 19 in v1.x)
66+
> **Note:** `retrieve-a-database` is still available and returns database metadata including the list of data source IDs. Use `retrieve-a-data-source` to get the schema and properties of a specific data source.
67+
68+
**Total tools now: 22** (was 19 in v1.x)
6869

6970
---
7071

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"mcp",
77
"server"
88
],
9-
"version": "2.0.0",
9+
"version": "2.1.0",
1010
"license": "MIT",
1111
"type": "module",
1212
"scripts": {

scripts/notion-openapi.json

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@
268268
}
269269
],
270270
"tags": [
271+
{
272+
"name": "Databases",
273+
"description": "Database endpoints for retrieving database metadata"
274+
},
271275
{
272276
"name": "Data sources",
273277
"description": "Data source endpoints for querying and managing databases"
@@ -2063,6 +2067,70 @@
20632067
"security": []
20642068
}
20652069
},
2070+
"/v1/databases/{database_id}": {
2071+
"get": {
2072+
"summary": "Retrieve a database",
2073+
"description": "Retrieves a database object using the ID specified. Returns database metadata including the list of data source IDs contained in the database.",
2074+
"operationId": "retrieve-a-database",
2075+
"tags": [
2076+
"Databases"
2077+
],
2078+
"parameters": [
2079+
{
2080+
"name": "database_id",
2081+
"in": "path",
2082+
"description": "Identifier for a Notion database",
2083+
"schema": {
2084+
"type": "string"
2085+
},
2086+
"required": true
2087+
},
2088+
{
2089+
"$ref": "#/components/parameters/notionVersion"
2090+
}
2091+
],
2092+
"responses": {
2093+
"200": {
2094+
"description": "Successful response",
2095+
"content": {
2096+
"application/json": {
2097+
"schema": {
2098+
"type": "object"
2099+
}
2100+
}
2101+
}
2102+
},
2103+
"400": {
2104+
"description": "Bad request",
2105+
"content": {
2106+
"application/json": {
2107+
"schema": {
2108+
"type": "object",
2109+
"properties": {
2110+
"object": {
2111+
"type": "string",
2112+
"example": "error"
2113+
},
2114+
"status": {
2115+
"type": "integer",
2116+
"example": 400
2117+
},
2118+
"code": {
2119+
"type": "string"
2120+
},
2121+
"message": {
2122+
"type": "string"
2123+
}
2124+
}
2125+
}
2126+
}
2127+
}
2128+
}
2129+
},
2130+
"deprecated": false,
2131+
"security": []
2132+
}
2133+
},
20662134
"/v1/pages/{page_id}/move": {
20672135
"post": {
20682136
"summary": "Move a page",

0 commit comments

Comments
 (0)