NestJS MCP Server: Use OpenAPI or Build Native?
Turn a NestJS Swagger API into a hosted MCP link, or decide when a native NestJS MCP module is the better architecture for custom tools and resources.
The short answer
There are two practical ways to create a NestJS MCP server:
- Use the existing OpenAPI document. If the NestJS application already exposes a REST API through
@nestjs/swagger, datamcp can connect to that OpenAPI document and publish a hosted MCP link without adding MCP code to the application. - Build native MCP tools in NestJS. If the agent needs purpose-built tools, resources, prompts, application workflows, or behavior that is not represented by REST endpoints, use the official MCP SDK or a NestJS MCP module and operate that server yourself.
datamcp follows the first path. It is not a NestJS module and does not run inside the Node.js process. It reads the public OpenAPI 3.x contract, exposes four MCP discovery and execution tools, stores a supported upstream credential on the connection, and applies the MCP link's HTTP-method policy before forwarding a request.
NestJS OpenAPI conversion vs native MCP
| Requirement | OpenAPI through datamcp | Native NestJS MCP server |
|---|---|---|
| Existing REST controllers | Reuse their OpenAPI contract | Wrap application services in MCP tools |
| MCP tool design | Four generic discovery and call tools | Custom tools, resources, and prompts |
| Deployment | Hosted remote MCP endpoint | Build and operate the MCP runtime |
| API changes | Resync the OpenAPI connection | Update, test, and deploy MCP code |
| Upstream credentials | Supported credential stored on the connection | Implement secret handling and backend access |
| Client access policy | Read Only or Full Access per MCP link | Implement authorization in the server |
| Best fit | Existing API access | Agent-specific workflows and semantics |
The two approaches can coexist. A team can expose most stable REST operations through OpenAPI and build a small native MCP server only for workflows that need custom orchestration.
Publish OpenAPI from NestJS
NestJS provides the @nestjs/swagger module for generating an OpenAPI document from controllers, decorators, and DTO metadata.
Install it in the NestJS application:
npm install --save @nestjs/swagger
Then create the document and mount Swagger in main.ts:
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('Orders API')
.setDescription('Create and inspect customer orders')
.setVersion('1.0')
.addBearerAuth()
.build();
const documentFactory = () =>
SwaggerModule.createDocument(app, config, {
operationIdFactory: (controllerKey, methodKey) =>
`${controllerKey}_${methodKey}`,
});
SwaggerModule.setup('api', app, documentFactory);
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
With the default setup path above, NestJS serves:
- Swagger UI at
/api - OpenAPI JSON at
/api-json - OpenAPI YAML at
/api-yaml
The raw JSON URL is normally the cleanest input for an OpenAPI connection. datamcp can also attempt to extract the embedded specification from a supported Swagger UI or Redoc documentation page.
NestJS allows a custom JSON path:
SwaggerModule.setup('docs', app, documentFactory, {
jsonDocumentUrl: 'docs/openapi.json',
});
In that case, connect https://api.example.com/docs/openapi.json rather than assuming the default /api-json path.
Make the NestJS contract useful to an AI client
OpenAPI conversion can only use information present in the contract. A technically valid but poorly described document produces weak discovery.
Use stable operation IDs
An operation ID should remain stable across deployments and distinguish one controller action from another. NestJS supports an operationIdFactory when creating the document.
Avoid generic duplicate names such as find, create, or update across many controllers. Prefer identifiers that preserve the domain, such as:
OrdersController_findByCustomer
OrdersController_createDraft
InvoicesController_markPaid
Describe parameters and request bodies
Use DTOs, validation decorators, and Swagger metadata so the OpenAPI schema explains required fields, enum values, formats, and nested objects.
import { ApiProperty } from '@nestjs/swagger';
export class CreateOrderDto {
@ApiProperty({ example: 'cus_123', description: 'Customer identifier' })
customerId: string;
@ApiProperty({ example: ['sku_basic'], description: 'Product SKU list' })
items: string[];
}
An AI client should not need to guess whether id means a customer, order, project, or tenant.
Document security schemes accurately
NestJS can describe Bearer, Basic, API-key, OAuth2, and cookie schemes in the OpenAPI document. The declaration helps datamcp identify what the upstream API expects, but it does not grant access by itself.
datamcp currently supports these upstream credential patterns:
- no authentication
- API key in a header, query parameter, or cookie
- pre-issued Bearer token
- HTTP Basic authentication
- optional custom headers
datamcp does not currently run an upstream OAuth authorization flow or refresh upstream OAuth tokens. If the NestJS OpenAPI document declares OAuth2, use a supported pre-issued credential where appropriate or choose a custom integration that owns the complete OAuth lifecycle.
Connect the NestJS API to datamcp
1. Verify the schema URL
Open the raw JSON URL in a browser or with curl:
curl -fsSL https://api.example.com/api-json | jq '.openapi, .info.title, (.paths | keys | length)'
Confirm that the response is JSON, the document has an OpenAPI version, and the expected paths are present.
2. Create an OpenAPI connection
In datamcp, create a new OpenAPI connection and paste the raw JSON/YAML URL or supported documentation-page URL. datamcp validates the document and extracts its operations and component schemas.
The specification URL must be reachable by datamcp. Private-spec authentication, mutual TLS, and network-only documentation endpoints are not currently supported by the connection flow.
3. Configure upstream authentication
Select the credential type used by the NestJS API. The value is stored on the connection and injected into approved upstream requests. It is separate from the credential used by the AI client to authenticate to the MCP endpoint.
This creates two boundaries:
AI client → DataMCP API key or OAuth → MCP link policy
DataMCP → configured upstream credential → NestJS authorization
Keep the NestJS API's own authorization checks. MCP link policy narrows access but does not replace tenant checks, ownership rules, roles, or other application authorization.
4. Create the MCP link
Choose one of the current OpenAPI access presets:
| Preset | Allowed HTTP methods |
|---|---|
| Read Only | GET, HEAD |
| Full Access | Operations visible to the connection, subject to upstream authorization |
Read Only is a method gate. It does not prove that every GET is side-effect-free or safe for every user. Review endpoint semantics and use a least-privilege upstream credential.
5. Connect the AI client
Copy the hosted MCP URL and client authentication details into a compatible remote MCP client. The client discovers four tools:
| MCP tool | Purpose |
|---|---|
list_api_endpoints | List operations found in the NestJS OpenAPI document |
get_endpoint_details | Inspect parameters, request body, responses, and security metadata |
get_api_schema | Read OpenAPI component schemas |
call_endpoint | Execute one approved upstream API operation |
datamcp does not generate one MCP tool per NestJS route. The discovery tools keep the initial MCP surface stable while allowing the client to inspect the API before making a call.
Common NestJS OpenAPI problems
The Swagger UI works but /api-json returns 404
Check the path passed to SwaggerModule.setup() and whether jsonDocumentUrl was customized. If raw definitions were disabled with the Swagger setup options, expose JSON or provide a supported documentation page that contains the schema.
A global prefix changes the expected URL
NestJS can apply a global prefix such as /v1. Swagger setup has its own useGlobalPrefix option, so do not infer the document path from the application routes. Verify the deployed URL directly.
Routes or DTO fields are missing
Confirm that the controllers are included in the document and that DTO metadata is available. The NestJS Swagger CLI plugin can derive additional schema metadata from TypeScript types and class-validator decorators, but the generated document still needs review.
Calls return 401 or 403
The OpenAPI document may be public while the actual API requires a credential. Configure a supported upstream credential and verify that the NestJS guards accept it. A 403 can also mean the credential is valid but lacks the required application role or resource access.
The app sits behind a reverse proxy
Confirm that the public OpenAPI server URL, global prefix, and proxy path describe the route datamcp can actually call. A schema that points to an internal hostname or missing prefix can validate but fail during execution.
You need an API execution audit trail
OpenAPI endpoint calls do not currently appear in the datamcp activity log. Use NestJS application logs, an API gateway, or infrastructure observability to record upstream requests and outcomes.
When to build native MCP in NestJS
Choose a native NestJS MCP server when the useful capability is not already a well-designed REST operation.
Typical reasons include:
- one agent tool must coordinate several application services
- the server should expose MCP resources or prompts, not only executable API calls
- the tool needs a carefully designed input schema different from the public REST contract
- the workflow needs progress notifications, elicitation, or other MCP-specific behavior
- the application must perform an internal action that should never become a public REST endpoint
- the team wants complete control over tool names, descriptions, errors, and protocol behavior
Several community NestJS MCP modules exist, and the official Model Context Protocol TypeScript SDK can also be integrated directly. Evaluate package ownership, release activity, transport support, authentication, and supply-chain risk before adding a community module to a production application.
Production checklist
Before publishing a NestJS API through MCP:
- verify the deployed OpenAPI JSON or YAML URL
- remove operations that should not be discoverable
- use stable, descriptive operation IDs
- describe parameters, request bodies, and response schemas
- define the real security scheme in OpenAPI
- use a least-privilege upstream credential
- start with a Read Only MCP link when possible
- test an allowed call and a denied write
- confirm tenant and resource authorization inside NestJS
- record API execution in upstream logs when required
- document credential rotation and MCP-link revocation
Final recommendation
Use OpenAPI conversion when the NestJS REST API already represents the operations an AI client should perform. It avoids a second server codebase and gives the team a hosted MCP endpoint, supported credential injection, and method-level link policy.
Build native MCP in NestJS when the agent needs domain workflows, resources, prompts, or custom tool semantics that do not fit the REST contract.
To use the OpenAPI path, start with the OpenAPI to MCP product page, review the OpenAPI authentication guide, and confirm the exact connection flow in the OpenAPI documentation. Use the OpenAPI versus custom MCP server comparison when the native-module boundary is unclear, or follow the Swagger to MCP tutorial for the complete hosted conversion workflow.
Related articles
How to Turn Swagger into an MCP Server
Turn an OpenAPI 3.x or Swagger documentation URL into a hosted remote MCP endpoint. Configure auth, read-only access, and test real API calls.
TutorialFastAPI MCP Server: Turn OpenAPI into Hosted MCP
Turn a FastAPI OpenAPI schema into a hosted MCP server. Connect /openapi.json, configure API auth, restrict methods, and test the MCP link.
Already have an OpenAPI contract?
Connect the specification and publish a hosted MCP endpoint without maintaining custom server code.
Create OpenAPI MCP linkExplore OpenAPI to MCP · Questions? Read the docs or view pricing.