#
tokens: 6000/50000 9/9 files
lines: on (toggle) GitHub
raw markdown copy reset
# Directory Structure

```
├── .auto-committer
│   └── config.yaml
├── .gitignore
├── .npmignore
├── .vscode
│   └── tasks.json
├── build
│   ├── index.d.ts
│   ├── index.js
│   └── index.js.map
├── Dockerfile
├── LICENSE
├── package-lock.json
├── package.json
├── README.md
├── smithery.yaml
├── src
│   └── index.ts
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------

```
 1 | # Source files
 2 | src/
 3 | 
 4 | # Config files
 5 | tsconfig.json
 6 | .env
 7 | .env.*
 8 | *.log
 9 | 
10 | # Node modules (should not be included)
11 | node_modules/
12 | 
13 | # OS / Editor specific
14 | .DS_Store
15 | *.pem
16 | *.tgz
```

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
  1 | # Logs
  2 | logs
  3 | *.log
  4 | npm-debug.log*
  5 | yarn-debug.log*
  6 | yarn-error.log*
  7 | lerna-debug.log*
  8 | .pnpm-debug.log*
  9 | 
 10 | # Diagnostic reports (https://nodejs.org/api/report.html)
 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
 12 | 
 13 | # Runtime data
 14 | pids
 15 | *.pid
 16 | *.seed
 17 | *.pid.lock
 18 | 
 19 | # Directory for instrumented libs generated by jscoverage/JSCover
 20 | lib-cov
 21 | 
 22 | # Coverage directory used by tools like istanbul
 23 | coverage
 24 | *.lcov
 25 | 
 26 | # nyc test coverage
 27 | .nyc_output
 28 | 
 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
 30 | .grunt
 31 | 
 32 | # Bower dependency directory (https://bower.io/)
 33 | bower_components
 34 | 
 35 | # node-waf configuration
 36 | .lock-wscript
 37 | 
 38 | # Compiled binary addons (https://nodejs.org/api/addons.html)
 39 | build/Release
 40 | 
 41 | # Dependency directories
 42 | node_modules/
 43 | jspm_packages/
 44 | 
 45 | # Snowpack dependency directory (https://snowpack.dev/)
 46 | web_modules/
 47 | 
 48 | # TypeScript cache
 49 | *.tsbuildinfo
 50 | 
 51 | # Optional npm cache directory
 52 | .npm
 53 | 
 54 | # Optional eslint cache
 55 | .eslintcache
 56 | 
 57 | # Optional stylelint cache
 58 | .stylelintcache
 59 | 
 60 | # Microbundle cache
 61 | .rpt2_cache/
 62 | .rts2_cache_cjs/
 63 | .rts2_cache_es/
 64 | .rts2_cache_umd/
 65 | 
 66 | # Optional REPL history
 67 | .node_repl_history
 68 | 
 69 | # Output of 'npm pack'
 70 | *.tgz
 71 | 
 72 | # Yarn Integrity file
 73 | .yarn-integrity
 74 | 
 75 | # dotenv environment variable files
 76 | .env
 77 | .env.development.local
 78 | .env.test.local
 79 | .env.production.local
 80 | .env.local
 81 | 
 82 | # parcel-bundler cache (https://parceljs.org/)
 83 | .cache
 84 | .parcel-cache
 85 | 
 86 | # Next.js build output
 87 | .next
 88 | out
 89 | 
 90 | # Nuxt.js build / generate output
 91 | .nuxt
 92 | dist
 93 | 
 94 | # Gatsby files
 95 | .cache/
 96 | # Comment in the public line in if your project uses Gatsby and not Next.js
 97 | # https://nextjs.org/blog/next-9-1#public-directory-support
 98 | # public
 99 | 
100 | # vuepress build output
101 | .vuepress/dist
102 | 
103 | # vuepress v2.x temp and cache directory
104 | .temp
105 | .cache
106 | 
107 | # vitepress build output
108 | **/.vitepress/dist
109 | 
110 | # vitepress cache directory
111 | **/.vitepress/cache
112 | 
113 | # Docusaurus cache and generated files
114 | .docusaurus
115 | 
116 | # Serverless directories
117 | .serverless/
118 | 
119 | # FuseBox cache
120 | .fusebox/
121 | 
122 | # DynamoDB Local files
123 | .dynamodb/
124 | 
125 | # TernJS port file
126 | .tern-port
127 | 
128 | # Stores VSCode versions used for testing VSCode extensions
129 | .vscode-test
130 | 
131 | # yarn v2
132 | .yarn/cache
133 | .yarn/unplugged
134 | .yarn/build-state.yml
135 | .yarn/install-state.gz
136 | .pnp.*
137 | 
138 | # Auto Committer environment file
139 | .auto-committer/.env
140 | 
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
  1 | [![MseeP.ai Security Assessment Badge](https://mseep.net/pr/kunihiros-google-patents-mcp-badge.png)](https://mseep.ai/app/kunihiros-google-patents-mcp)
  2 | 
  3 | # Google Patents MCP Server (`google-patents-mcp`)
  4 | 
  5 | [![smithery badge](https://smithery.ai/badge/@KunihiroS/google-patents-mcp)](https://smithery.ai/server/@KunihiroS/google-patents-mcp)
  6 | [![npm version](https://badge.fury.io/js/%40kunihiros%2Fgoogle-patents-mcp.svg)](https://badge.fury.io/js/%40kunihiros%2Fgoogle-patents-mcp)
  7 | 
  8 | This project provides a Model Context Protocol (MCP) server that allows searching Google Patents information via the [SerpApi Google Patents API](https://serpapi.com/google-patents-api).
  9 | 
 10 | ### Installing via Smithery
 11 | 
 12 | To install Google Patents MCP Server for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@KunihiroS/google-patents-mcp):
 13 | 
 14 | ```bash
 15 | npx -y @smithery/cli install @KunihiroS/google-patents-mcp --client claude
 16 | ```
 17 | 
 18 | ## Changelog
 19 | 
 20 | ### v0.2.0 (2025-04-17)
 21 | 
 22 | *   **Fix:** Implemented empty handlers for `resources/list` and `prompts/list` MCP methods.
 23 | *   **Fix:** Declared `prompts` capability in server initialization.
 24 | *   **Chore:** Updated dependencies.
 25 | 
 26 | These changes aim to improve compatibility with MCP clients like Claude Desktop which may require these standard endpoints, though direct testing with Claude Desktop has not yet been performed.
 27 | 
 28 | ## Features
 29 | 
 30 | *   Provides an MCP tool `search_patents` to search Google Patents.
 31 | *   Uses SerpApi as the backend.
 32 | *   Can be run directly using `npx` without local installation.
 33 | 
 34 | ## Prerequisites
 35 | 
 36 | *   **Node.js:** Version 18 or higher is recommended.
 37 | *   **npm:** Required to run the `npx` command.
 38 | *   **SerpApi API Key:** You need a valid API key from [SerpApi](https://serpapi.com/) to use the Google Patents API.
 39 | 
 40 | ## Quick Start (Using npx)
 41 | 
 42 | The easiest way to run this server is using `npx`. This command downloads (if necessary) and runs the server directly.
 43 | 
 44 | ```bash
 45 | npx @kunihiros/google-patents-mcp
 46 | ```
 47 | 
 48 | **Note:** Replace `@kunihiros/google-patents-mcp` with the actual published package name if it differs.
 49 | 
 50 | The server will start and listen for MCP requests on standard input/output.
 51 | 
 52 | ## Configuration
 53 | 
 54 | The server requires your SerpApi API key. You can provide it in one of the following ways:
 55 | 
 56 | 1.  **Environment Variable (Recommended for MCP Hosts):**
 57 |     Set the `SERPAPI_API_KEY` environment variable when running the server. MCP Host configurations often allow setting environment variables for servers.
 58 | 
 59 |     Example MCP Host configuration snippet (`config.json` or similar):
 60 |     ```json
 61 |     {
 62 |       "mcpServers": {
 63 |         "google-patents-mcp": {
 64 |           "command": "npx",
 65 |           "args": [
 66 |             "-y", // Skips confirmation if the package isn't installed locally
 67 |             "@kunihiros/google-patents-mcp" // Use the correct package name
 68 |           ],
 69 |           "env": {
 70 |             "SERPAPI_API_KEY": "YOUR_ACTUAL_SERPAPI_KEY"
 71 |             // Optional: Set log level
 72 |             // "LOG_LEVEL": "debug"
 73 |           }
 74 |         }
 75 |       }
 76 |     }
 77 |     ```
 78 | 
 79 | 2.  **.env File:**
 80 |     Create a `.env` file in the directory where you run the `npx` command (for local testing or if not using an MCP Host), or in your home directory (`~/.google-patents-mcp.env`), with the following content:
 81 | 
 82 |     ```dotenv
 83 |     SERPAPI_API_KEY=YOUR_ACTUAL_SERPAPI_KEY
 84 |     # Optional: Set log level (e.g., debug, info, warn, error)
 85 |     # LOG_LEVEL=debug
 86 |     ```
 87 |     **Note:** While using a `.env` file is convenient for local testing, for production or integration with MCP Hosts, setting the environment variable directly via the host configuration is the recommended and more secure approach. The primary intended use case is execution via `npx`, where environment variables are typically managed by the calling process or MCP Host.
 88 | 
 89 | The server searches for `.env` files in the following order:
 90 |     *   `./.env` (relative to where `npx` is run)
 91 |     *   `~/.google-patents-mcp.env` (in your home directory)
 92 | 
 93 | ## Provided MCP Tool
 94 | 
 95 | ### `search_patents`
 96 | 
 97 | Searches Google Patents via SerpApi.
 98 | 
 99 | **Input Schema:**
100 | 
101 | ```json
102 | {
103 |   "type": "object",
104 |   "properties": {
105 |     "q": {
106 |       "type": "string",
107 |       "description": "Search query (required). Although optional in SerpApi docs, a non-empty query is practically needed. Use semicolon (;) to separate multiple terms. Advanced syntax like '(Coffee) OR (Tea);(A47J)' is supported. See 'About Google Patents' for details."
108 |     },
109 |     "page": {
110 |       "type": "integer",
111 |       "description": "Page number for pagination (default: 1).",
112 |       "default": 1
113 |     },
114 |     "num": {
115 |       "type": "integer",
116 |       "description": "Number of results per page (default: 10). **IMPORTANT: Must be 10 or greater (up to 100).**",
117 |       "default": 10,
118 |       "minimum": 10,
119 |       "maximum": 100
120 |     },
121 |     "sort": {
122 |       "type": "string",
123 |       "enum": ["relevance", "new", "old"],
124 |       "description": "Sorting method. 'relevance' (default), 'new' (newest by filing/publication date), 'old' (oldest by filing/publication date).",
125 |       "default": "relevance"
126 |     },
127 |     "before": {
128 |       "type": "string",
129 |       "description": "Maximum date filter (e.g., 'publication:20231231', 'filing:20220101'). Format: type:YYYYMMDD where type is 'priority', 'filing', or 'publication'."
130 |     },
131 |     "after": {
132 |       "type": "string",
133 |       "description": "Minimum date filter (e.g., 'publication:20230101', 'filing:20220601'). Format: type:YYYYMMDD where type is 'priority', 'filing', or 'publication'."
134 |     },
135 |     "inventor": {
136 |       "type": "string",
137 |       "description": "Filter by inventor names. Separate multiple names with a comma (,)."
138 |     },
139 |     "assignee": {
140 |       "type": "string",
141 |       "description": "Filter by assignee names. Separate multiple names with a comma (,)."
142 |     },
143 |     "country": {
144 |       "type": "string",
145 |       "description": "Filter by country codes (e.g., 'US', 'WO,JP'). Separate multiple codes with a comma (,)."
146 |     },
147 |     "language": {
148 |       "type": "string",
149 |       "description": "Filter by language (e.g., 'ENGLISH', 'JAPANESE,GERMAN'). Separate multiple languages with a comma (,). Supported: ENGLISH, GERMAN, CHINESE, FRENCH, SPANISH, ARABIC, JAPANESE, KOREAN, PORTUGUESE, RUSSIAN, ITALIAN, DUTCH, SWEDISH, FINNISH, NORWEGIAN, DANISH."
150 |     },
151 |     "status": {
152 |       "type": "string",
153 |       "enum": ["GRANT", "APPLICATION"],
154 |       "description": "Filter by patent status: 'GRANT' or 'APPLICATION'."
155 |     },
156 |     "type": {
157 |       "type": "string",
158 |       "enum": ["PATENT", "DESIGN"],
159 |       "description": "Filter by patent type: 'PATENT' or 'DESIGN'."
160 |     },
161 |     "scholar": {
162 |       "type": "boolean",
163 |       "description": "Include Google Scholar results (default: false).",
164 |       "default": false
165 |     }
166 |   },
167 |   "required": ["q"]
168 | }
169 | ```
170 | 
171 | **Output:**
172 | 
173 | Returns a JSON object containing the search results from SerpApi. The structure follows the SerpApi response format.
174 | 
175 | **Example Usage (MCP Request):**
176 | 
177 | ```json
178 | {
179 |   "mcp_version": "1.0",
180 |   "type": "CallToolRequest",
181 |   "id": "req-123",
182 |   "server_name": "google-patents-mcp",
183 |   "params": {
184 |     "name": "search_patents",
185 |     "arguments": {
186 |       "q": "organic light emitting diode",
187 |       "num": 10,
188 |       "language": "ENGLISH",
189 |       "status": "GRANT",
190 |       "after": "publication:20230101"
191 |     }
192 |   }
193 | }
194 | ```
195 | 
196 | ## Development
197 | 
198 | 1.  **Clone the repository (if needed for development):**
199 |     ```bash
200 |     # git clone <repository-url>
201 |     # cd google-patents-mcp
202 |     ```
203 | 2.  **Install dependencies:**
204 |     ```bash
205 |     npm install
206 |     ```
207 | 3.  **Create `.env` file:**
208 |     Copy `.env.example` to `.env` and add your `SERPAPI_API_KEY`.
209 | 4.  **Build:**
210 |     ```bash
211 |     npm run build
212 |     ```
213 | 5.  **Run locally:**
214 |     ```bash
215 |     npm start
216 |     ```
217 |     Or for development with auto-rebuild:
218 |     ```bash
219 |     npm run dev
220 |     ```
221 | 
222 | ## Logging
223 | 
224 | *   Logs are output to standard error.
225 | *   Log level can be controlled via the `LOG_LEVEL` environment variable (`error`, `warn`, `info`, `http`, `verbose`, `debug`, `silly`). Defaults to `info`.
226 | *   A log file is attempted to be created in the project root (`google-patents-server.log`), user's home directory (`~/.google-patents-server.log`), or `/tmp/google-patents-server.log`.
227 | 
228 | ## License
229 | 
230 | MIT License (See LICENSE file)
231 | 
```

--------------------------------------------------------------------------------
/.auto-committer/config.yaml:
--------------------------------------------------------------------------------

```yaml
1 | # Auto Committer Configuration File
2 | 
3 | commitIntervalSeconds: 180
4 | llm:
5 |   provider: openai
6 |   model: gpt-4o-mini
7 | commitPrefix: '[Auto commit]'
8 | autoPush: true
9 | 
```

--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "version": "2.0.0",
 3 |   "tasks": [
 4 |     {
 5 |       "label": "Start Auto Committer",
 6 |       "type": "shell",
 7 |       "command": "node \"/home/kunihiros/.nvm/versions/node/v22.14.0/bin/auto-committer\" start",
 8 |       "isBackground": true,
 9 |       "problemMatcher": [],
10 |       "presentation": {
11 |         "reveal": "silent",
12 |         "panel": "dedicated",
13 |         "showReuseMessage": false,
14 |         "clear": true
15 |       },
16 |       "runOptions": {
17 |         "runOn": "folderOpen"
18 |       }
19 |     }
20 |   ]
21 | }
```

--------------------------------------------------------------------------------
/smithery.yaml:
--------------------------------------------------------------------------------

```yaml
 1 | # Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml
 2 | 
 3 | startCommand:
 4 |   type: stdio
 5 |   configSchema:
 6 |     # JSON Schema defining the configuration options for the MCP.
 7 |     type: object
 8 |     required:
 9 |       - serpapiApiKey
10 |     properties:
11 |       serpapiApiKey:
12 |         type: string
13 |         description: SerpApi API key for authenticating requests
14 |     description: Configuration for Google Patents MCP Server
15 |   commandFunction:
16 |     # A JS function that produces the CLI command based on the given config to start the MCP on stdio.
17 |     |-
18 |     (config) => ({
19 |       command: 'node',
20 |       args: ['build/index.js'],
21 |       env: { SERPAPI_API_KEY: config.serpapiApiKey }
22 |     })
23 |   exampleConfig:
24 |     serpapiApiKey: YOUR_SERPAPI_API_KEY_HERE
25 | 
```

--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
 1 | # Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile
 2 | # Stage 1: Build the TypeScript source
 3 | FROM node:lts-alpine AS builder
 4 | WORKDIR /app
 5 | 
 6 | # Install dependencies
 7 | COPY package*.json tsconfig.json ./
 8 | RUN npm install
 9 | 
10 | # Copy source and build
11 | COPY src ./src
12 | RUN npm run build
13 | 
14 | # Ensure non-root ownership and set non-root user for builder stage
15 | RUN chown -R node:node /app
16 | USER node
17 | 
18 | # Stage 2: Create production image
19 | FROM node:lts-alpine
20 | WORKDIR /app
21 | 
22 | # Install only production dependencies
23 | COPY package*.json ./
24 | RUN npm install --only=production
25 | 
26 | # Copy built artifacts
27 | COPY --from=builder /app/build ./build
28 | 
29 | # Ensure non-root ownership of app files
30 | RUN chown -R node:node /app
31 | 
32 | # Expose stdio for MCP communication
33 | # Start the MCP server
34 | USER node
35 | CMD ["node", "build/index.js"]
36 | 
```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "@kunihiros/google-patents-mcp",
 3 |   "version": "0.2.0",
 4 |   "description": "MCP server for searching Google Patents via SerpApi",
 5 |   "main": "build/index.js",
 6 |   "type": "module",
 7 |   "bin": {
 8 |     "google-patents-mcp": "build/index.js"
 9 |   },
10 |   "scripts": {
11 |     "build": "tsc",
12 |     "start": "node build/index.js",
13 |     "dev": "tsc -w & node --watch build/index.js",
14 |     "test": "echo \"Error: no test specified\" && exit 1"
15 |   },
16 |   "keywords": [
17 |     "mcp",
18 |     "serpapi",
19 |     "google patents"
20 |   ],
21 |   "author": "Kunihiro Sasayama",
22 |   "license": "MIT",
23 |   "repository": {
24 |     "type": "git",
25 |     "url": "git+https://github.com/KunihiroS/google-patents-mcp.git"
26 |   },
27 |   "homepage": "https://github.com/KunihiroS/google-patents-mcp#readme",
28 |   "bugs": {
29 |     "url": "https://github.com/KunihiroS/google-patents-mcp/issues"
30 |   },
31 |   "files": [
32 |     "build",
33 |     "README.md",
34 |     "LICENSE",
35 |     "package.json"
36 |   ],
37 |   "dependencies": {
38 |     "@modelcontextprotocol/sdk": "^1.8.0",
39 |     "node-fetch": "^3.3.2",
40 |     "dotenv": "^16.4.5",
41 |     "winston": "^3.13.0"
42 |   },
43 |   "devDependencies": {
44 |     "@types/node": "^20.14.2",
45 |     "typescript": "^5.4.5",
46 |     "@types/node-fetch": "^2.6.11"
47 |   }
48 | }
49 | 
```

--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "target": "ES2022",                       /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', 'ES2022', or 'ESNEXT'. */
 4 |     "module": "NodeNext",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
 5 |     "outDir": "./build",                      /* Redirect output structure to the directory. */
 6 |     "rootDir": "./src",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
 7 |     "strict": true,                           /* Enable all strict type-checking options. */
 8 |     "esModuleInterop": true,                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
 9 |     "skipLibCheck": true,                     /* Skip type checking of declaration files. */
10 |     "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
11 |     "moduleResolution": "NodeNext",           /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
12 |     "resolveJsonModule": true,                /* Include modules imported with '.json' extension */
13 |     "declaration": true,                      /* Generates corresponding '.d.ts' file. */
14 |     "sourceMap": true                         /* Generates corresponding '.map' file. */
15 |   },
16 |   "include": ["src/**/*"],                    /* Specifies the files to include in the program. */
17 |   "exclude": ["node_modules", "**/*.spec.ts"] /* Specifies the files to exclude from the program. */
18 | }
```