# How Response Schemas Are Defined and Returned in the MCP OpenAPI Server

> Learn how response schemas are defined and returned by the castrozan/tcc MCP OpenAPI server. Discover how they are derived from OpenAPI specifications and returned as JSON.

- Repository: [Lucas Zanoni⠀⠀⠀⠀⠀ ⠀╱|、 ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ (˚ˎ 。7 ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ |、˜〵 ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ じしˍ,)ノ/tcc](https://github.com/castrozan/tcc)
- Tags: how-to-guide
- Published: 2026-02-27

---

**Response schemas in the castrozan/tcc MCP server are derived directly from the OpenAPI specification, inlined during load time, and returned as JSON objects through the `GET-API-ENDPOINT-SCHEMA` meta-tool execution.**

The `castrozan/tcc` repository implements a Model Context Protocol (MCP) server that bridges OpenAPI-compliant REST APIs with AI clients. Understanding how response schemas are defined and returned is essential for developers integrating external APIs through this middleware, as it determines how tool inputs are validated and how response structures are communicated to downstream consumers.

## Loading and Inlining OpenAPI Specifications

The foundation of response schema handling begins with the `OpenAPISpecLoader` class in [`src/openapi-loader.ts`](https://github.com/castrozan/tcc/blob/main/src/openapi-loader.ts), which processes the OpenAPI specification at server startup.

### Fetching and Parsing the Spec

The `OpenAPISpecLoader.loadOpenAPISpec` method fetches the specification from various sources—URL, file path, stdin, or inline JSON. Once loaded, `parseOpenAPISpec` walks through each path-operation pair in the specification to identify available endpoints.

For each discovered operation, the system creates a corresponding tool. Meta-tools are generated via `ToolsManager.createDynamicTools`, while standard endpoint tools are created individually for each API path.

### Resolving Schema References

Before schemas can be used, all `$ref` references must be resolved. The `OpenAPISpecLoader.inlineSchema` method recursively processes the OpenAPI components, inlining external references to produce self-contained JSON Schema objects. This ensures that each tool's schema is complete and portable, without dependencies on external component definitions.

## Converting OpenAPI Schemas to MCP Tool InputSchemas

Once inlined, the schemas are integrated into the MCP tool definitions that the server exposes to clients.

### Tool Creation Process

The `ToolsManager` in [`src/tools-manager.ts`](https://github.com/castrozan/tcc/blob/main/src/tools-manager.ts) handles the conversion of OpenAPI operations into MCP tools. For each endpoint, it extracts parameter schemas and request body definitions, applying the inlined JSON Schema objects created during the loading phase. This process ensures that the `inputSchema` for each tool accurately reflects the API's expected request structure.

### Schema Storage in Tool Definitions

The processed schemas are stored in each tool's `inputSchema` property as standard JSON Schema objects. These objects specify `type: "object"` with defined `properties` and optional `required` arrays, providing MCP clients with the metadata necessary to validate arguments before executing tool calls.

## Retrieving Response Schemas via Meta-Tools

While `inputSchema` defines what goes into an API call, response schemas describing the API's output are accessed through a dedicated meta-tool mechanism.

### The GET-API-ENDPOINT-SCHEMA Tool

Defined in [`src/tools-manager.ts`](https://github.com/castrozan/tcc/blob/main/src/tools-manager.ts) (lines 34-42), the `GET-API-ENDPOINT-SCHEMA` meta-tool provides a mechanism to retrieve the JSON Schema for any specific API endpoint. Its `inputSchema` requires a single `endpoint` string parameter, which identifies the target API path.

### Execution Flow and API Client Integration

When a client invokes this meta-tool, the `OpenAPIServer` registered in [`src/server.ts`](https://github.com/castrozan/tcc/blob/main/src/server.ts) (lines 45-73) handles the `tools/execute` request. Rather than treating this as a static lookup, the server forwards the call to `ApiClient.executeApiCall` in [`src/api-client.ts`](https://github.com/castrozan/tcc/blob/main/src/api-client.ts).

Because the `endpoint` parameter maps to a real API route that returns OpenAPI component schemas (such as `/schemas/{name}`), the underlying API returns the JSON schema definition. The MCP server then wraps this response in a JSON-RPC message, returning the schema as a pretty-printed text block within the `content` array of the tool execution result.

## Practical Examples

### List All Available Tools

Retrieve the complete tool catalog, including meta-tools and endpoint-specific tools:

```bash
curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

```

*Result (truncated):*

```json
{
  "jsonrpc":"2.0",
  "id":1,
  "result":{
    "tools":[
      {"id":"LIST-API-ENDPOINTS","name":"list-api-endpoints"},
      {"id":"GET-API-ENDPOINT-SCHEMA","name":"get-api-endpoint-schema"},
      {"id":"INVOKE-API-ENDPOINT","name":"invoke-api-endpoint"}
    ]
  }
}

```

### Retrieve a Specific Endpoint Schema

Request the JSON schema for the `/users/{id}` endpoint:

```bash
curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{
        "jsonrpc":"2.0",
        "id":2,
        "method":"tools/execute",
        "params":{
          "name":"get-api-endpoint-schema",
          "arguments":{"endpoint":"/users/{id}"}
        }
      }'

```

*Result:*

```json
{
  "jsonrpc":"2.0",
  "id":2,
  "result":{
    "content":[
      {
        "type":"text",
        "text":"{\
  \"type\":\"object\",\
  \"properties\":{\
    \"id\":{\"type\":\"string\",\"description\":\"User identifier\"},\
    \"includeDetails\":{\"type\":\"boolean\",\"default\":false}\
  },\
  \"required\":[\"id\"]\
}"
      }
    ]
  }
}

```

### Invoke an API Endpoint

Execute the `/users` endpoint with parameters:

```bash
curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{
        "jsonrpc":"2.0",
        "id":3,
        "method":"tools/execute",
        "params":{
          "name":"invoke-api-endpoint",
          "arguments":{
            "endpoint":"/users",
            "params":{"name":"Alice","email":"alice@example.com"}
          }
        }
      }'

```

*Result:*

```json
{
  "jsonrpc":"2.0",
  "id":3,
  "result":{
    "content":[
      {
        "type":"text",
        "text":"{\n  \"id\": \"123\",\n  \"name\": \"Alice\",\n  \"email\": \"alice@example.com\"\n}"
      }
    ]
  }
}

```

## Summary

- Response schemas originate from the OpenAPI specification loaded at server startup via `OpenAPISpecLoader.loadOpenAPISpec`.
- The `OpenAPISpecLoader.inlineSchema` method recursively resolves all `$ref` references to create self-contained JSON Schema objects.
- Processed schemas are stored in each tool's `inputSchema` property within `ToolsManager`, defining valid inputs for API endpoints.
- The `GET-API-ENDPOINT-SCHEMA` meta-tool retrieves specific endpoint schemas by executing against the underlying API via `ApiClient.executeApiCall`.
- Schema responses are returned as pretty-printed JSON text blocks within the MCP protocol's `content` array, wrapped in standard JSON-RPC messages.

## Frequently Asked Questions

### How does the server handle circular references in OpenAPI schemas?

The `inlineSchema` method in [`src/openapi-loader.ts`](https://github.com/castrozan/tcc/blob/main/src/openapi-loader.ts) recursively resolves `$ref` references during the loading phase. While the implementation flattens schema structures to create self-contained JSON Schema objects, developers should verify that their OpenAPI specifications do not contain unresolvable circular dependencies that could cause infinite recursion during the inlining process.

### What is the difference between `inputSchema` and the response returned by `GET-API-ENDPOINT-SCHEMA`?

The `inputSchema` attached to each tool defines the parameters required to invoke that specific API endpoint—including query parameters, path parameters, and request body structures. In contrast, the `GET-API-ENDPOINT-SCHEMA` meta-tool returns the JSON Schema that describes the structure of the API's response payload, which typically differs from the input parameters and represents the data returned by the underlying REST API.

### Can I retrieve response schemas for endpoints that use complex nested objects?

Yes. Because `OpenAPISpecLoader.inlineSchema` recursively processes all schema components during the initial loading phase, nested objects, arrays, and complex types are fully expanded and preserved. When you invoke the `GET-API-ENDPOINT-SCHEMA` tool, the server returns the complete, inlined schema including all nested property definitions.

### Where is the schema execution logic handled when a meta-tool is invoked?

The execution logic resides in [`src/server.ts`](https://github.com/castrozan/tcc/blob/main/src/server.ts) (lines 45-73) where `OpenAPIServer` registers the JSON-RPC handler for `tools/execute` requests. When the `GET-API-ENDPOINT-SCHEMA` meta-tool is called, the server forwards the request to `ApiClient.executeApiCall` in [`src/api-client.ts`](https://github.com/castrozan/tcc/blob/main/src/api-client.ts), which makes the actual HTTP request to the underlying API endpoint that returns the schema definition.