A universal MCP server that gives agents direct access to any API through OpenAPI specifications.
Most MCP servers are built per-API: custom code for GitHub, custom code for Stripe, custom filtering logic hardcoded for each endpoint. This takes a different approach, where you can load any OpenAPI spec and agents explore it like a file system: categories, resources, or search, then operation details. They request only the endpoint details they need at runtime. No custom integration code. No hardcoded integrations. One server works with any API that has a spec.
load_openapi_spec- load any OpenAPI spec by URLsearch_operations- find API endpoints with fuzzy searchget_operation_details- get full parameter info for any endpointexecute_http_request- make authenticated API calls with optional response filteringexecute_chained_http_request- execute a sequence of API calls where each step can use data from previous stepsget_categories- browse APIs by organized categoriesget_resources_in_category- get resources/endpoints within a specific categoryget_service_info- get API metadata and stats
Load any OpenAPI spec and your agent can navigate it. Works with GitHub, Stripe, Notion, your internal APIs, anything with a spec. Handles authentication, denylists, response filtering, and request chaining.
git clone https://github.com/philippe-page/openapi-mcp
cd openapi-mcp
npm install
npm run dev:httpAdd a .env file with your API tokens:
GITHUB_TOKEN=ghp_your_token_here
STRIPE_SECRET_KEY=sk_your_stripe_key
OPENAI_API_KEY=sk-your_openai_keyConnect Cursor by adding to .cursor/mcp.json:
{
"mcpServers": {
"openapi": {
"url": "http://localhost:3000/mcp"
}
}
}That's it. Your agent now has access to any API with an OpenAPI spec.
The server automatically finds your API tokens by first pulling in the security scheme from the specification to use that structure, and falls back to matching service names to environment variables. When you load the "GitHub API", it looks for GITHUB_TOKEN, GITHUB_API_KEY, etc.
Add tokens to your .env file:
GITHUB_TOKEN=ghp_your_token
STRIPE_SECRET_KEY=sk_your_key
OPENAI_API_KEY=sk-your_key
SERPER_API_KEY=your_keyRestrict which endpoints your agent can use. Access rules can be configured via a JSON file or environment variable.
Create a openapi_access_config.json file in your working directory:
{
"github": {
"allowlist": ["GET *", "HEAD *"]
},
"stripe": {
"denylist": ["DELETE *"]
}
}The server will automatically load this file if it exists. See openapi_access_config.example.json for more examples.
Alternatively, use the OPENAPI_ACCESS_RULES environment variable:
Read-only access to GitHub:
OPENAPI_ACCESS_RULES='{"github":{"allowlist":["GET *","HEAD *"]}}'Block destructive operations:
OPENAPI_ACCESS_RULES='{"github":{"denylist":["DELETE *"]}}'- File-based rules are loaded first from
openapi_access_config.json - Environment variable rules are then loaded and can override/extend file-based rules
- Rules are applied to both operation discovery (search/list) and actual HTTP request execution
- You can specify exact endpoints like
"GET /repos/{owner}/{repo}"or use wildcards like"GET *"
Agents can use the response_filter parameter when executing HTTP requests, to filter out only the fields they need from API responses, saving tokens and reducing noise. They can filter by specific fields, limit results, navigate nested data, or use JSONPath for complex queries. The agent decides what response data matters for each request.
The execute_chained_http_request tool lets you orchestrate multi-step workflows where each API call can use data from previous steps. This is useful for tasks that require combining multiple APIs or building complex flows like "search for X, then get details about the top result, then process that data with another service."
Variable Substitution
Reference data from previous steps using ${step_id.field} syntax:
{
"steps": [
{
"step_id": "search_repos",
"service_name": "github",
"method": "GET",
"url": "/search/repositories",
"parameters": {
"q": "AI agents",
"sort": "stars"
},
"response_filter": {
"jsonpath": "$.items[0]",
"fields": ["full_name", "name", "owner"]
}
},
{
"step_id": "get_readme",
"service_name": "github",
"method": "GET",
"url": "/repos/${search_repos.owner.login}/${search_repos.name}/readme",
"headers": {
"Accept": "application/vnd.github.raw+json"
}
},
{
"step_id": "summarize",
"service_name": "openai",
"method": "POST",
"url": "/chat/completions",
"parameters": {
"model": "gpt-4o-mini",
"messages": [
{
"role": "user",
"content": "Summarize this README: ${get_readme}"
}
]
}
}
]
}Why Use Chained Requests?
- Cross-API workflows: Combine GitHub + Serper + OpenAI in one operation
- Token efficiency: Filter each step's response to pass only needed data forward
- Automatic orchestration: Dependencies resolved automatically with variable substitution
- Error handling: Set
stop_on_errorto halt the chain if any step fails
Each step can filter its response before passing data to the next step, keeping your workflow focused and token-efficient.
Add these OpenAPI spec URLs to your cursor rules or use them directly with load_openapi_spec:
Open APIs (no auth required)
- Universities: http://universities.hipolabs.com/
- Open Food Facts: https://world.openfoodfacts.org/data
- REST Countries: https://restcountries.com/
Requires API tokens
- GitHub: https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json
- Stripe: https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json
- Figma: https://github.com/figma/rest-api-spec/blob/main/openapi/openapi.yaml
- Strava: https://developers.strava.com/swagger/swagger.json
Can't connect?
- Make sure server is running:
npm run dev:http - Check URL is
http://localhost:3000/mcpin.cursor/mcp.json - Restart Cursor after config changes
Authentication failing?
- Verify
.envfile is in the repo root - Check token format matches the service (GitHub:
ghp_..., Stripe:sk_...) - Check server logs for auth errors
API calls not working?
- Load the OpenAPI spec first with
load_openapi_spec - Use
get_operation_detailsto check required parameters - Check server logs for error details
This is an exploratory project and I'd love your help making it better. Whether it's:
- Adding support for more authentication schemes
- Improving the response filtering logic
- Better error handling and debugging
- Documentation improvements
- New features or tools
PRs are welcome! If you're using this with an API that doesn't quite work, or you have ideas for making the agent experience better, open an issue or submit a PR.