Skip to main content
Glama
yeison-liscano

Demo HTTP MCP Server

test-http-mcp

http-mcp 패키지를 사용하여 Python으로 구현된 데모 MCP(Model Context Protocol) 서버입니다. HTTP(Starlette/Uvicorn) 또는 stdio를 통해 실행할 수 있으며, MCP 호환 클라이언트에 예제 도구와 프롬프트를 노출합니다. 이 프로젝트에는 NVD(National Vulnerability Database)를 통해 취약점을 쿼리하기 위한 채팅 인터페이스를 제공하는 React 프론트엔드가 포함되어 있습니다.

Chat UI

프로젝트 구조

test-http-mcp/
├── backend/                 # Python backend (FastAPI + MCP server)
│   ├── app/                 # Application source code
│   │   ├── app.py           # FastAPI app, routes, MCP mount
│   │   ├── main.py          # Entry points (HTTP / stdio)
│   │   ├── agen_memory.py   # SQLite message persistence
│   │   ├── config.py        # Settings via pydantic-settings
│   │   ├── auth0/           # Auth0 integration
│   │   │   ├── __init__.py  # JWT token validator
│   │   │   └── client_store.py # Dynamic client registration (RFC 7591)
│   │   ├── tools/           # MCP tools (CPE/CVE search via NVD)
│   │   └── prompts/         # MCP prompt templates
│   ├── pyproject.toml       # Python deps & scripts
│   ├── uv.lock              # Locked dependencies
│   ├── ruff.toml            # Linter config
│   ├── mypy.ini             # Type-checker config
│   └── .envrc               # direnv auto-activation
├── frontend/                # React + TypeScript frontend (Vite)
│   ├── src/
│   │   ├── components/      # ChatApp, ChatInput, MessageList, MessageBubble
│   │   ├── api.ts           # API client (fetch history, stream messages)
│   │   ├── types.ts         # Shared TypeScript types
│   │   ├── App.tsx          # Root component
│   │   └── App.css          # Styles
│   ├── vite.config.ts       # Vite config with dev proxy
│   └── package.json         # Node dependencies
├── AGENTS.md
├── LICENSE
└── README.md

인증 (Auth0)

MCP 엔드포인트(/mcp/)는 Auth0 OAuth2 인증으로 보호됩니다. 도구를 사용하려면 액세스 토큰에 범위(tool:search_cpe, tool:search_cve)가 포함되어 있어야 합니다.

필수 환경 변수

변수

설명

AUTH0_DOMAIN

Auth0 테넌트 도메인 (예: your-tenant.auth0.com)

AUTH0_AUDIENCE

토큰 검증을 위한 API 식별자

AUTH0_MCP_APP_CLIENT_ID

MCP 앱을 위한 Auth0 애플리케이션 클라이언트 ID

AUTH0_MGMT_CLIENT_ID

관리 API 클라이언트 ID (동적 등록용)

AUTH0_MGMT_CLIENT_SECRET

관리 API 클라이언트 시크릿

AUTH0_ENABLED

범위 강제 적용을 비활성화하려면 false로 설정 (기본값: true)

이 변수들을 backend/.env (git-ignored)에 배치하세요.

앱 마운트 구조

경로

앱

인증

/mcp/

보호된 MCP 서버

Auth0 Bearer 토큰 필요

/register

동적 클라이언트 등록 (RFC 7591)

인증되지 않음

/.well-known/

OAuth/리소스 메타데이터

인증되지 않음

/api/chat/

채팅 인터페이스 엔드포인트

인증되지 않음 (참고 사항 참조)

/api/

프론트엔드 정적 파일

인증되지 않음

참고: 채팅 엔드포인트는 로컬 개발을 위해 의도적으로 인증되지 않은 상태입니다. localhost 외부로 노출하기 전에 인증을 추가하세요.

요구 사항

  • Python 3.13

  • Node.js 18+ 및 npm

  • uv (권장) 또는 pip

설치

백엔드 (using uv):

cd backend
uv run python -V            # creates a venv and syncs deps from pyproject

백엔드 (using pip):

cd backend
python3.13 -m venv .venv
source .venv/bin/activate
pip install .

프론트엔드:

cd frontend
npm install

실행

개발 (프론트엔드 + 백엔드 별도)

백엔드 시작:

cd backend
uv run run-app
# → API on http://localhost:8000
# → MCP endpoint on http://localhost:8000/mcp/

프론트엔드 개발 서버 시작 (별도의 터미널에서):

cd frontend
npm run dev
# → UI on http://localhost:5173 (proxies /api/* → backend)

프로덕션 (백엔드가 빌드된 프론트엔드를 서빙)

프론트엔드를 빌드하고 백엔드를 시작:

cd frontend && npm run build && cd ..
cd backend && uv run run-app
# → Everything on http://localhost:8000

실행 (stdio 모드)

Cursor 또는 기타 MCP 클라이언트와 함께 사용

Auth0이 활성화된 경우, 클라이언트는 OAuth2 액세스 토큰을 획득해야 합니다. 서버는 /register에서 RFC 7591 동적 클라이언트 등록을 지원하므로, 인증 사양을 구현하는 MCP 클라이언트는 자동으로 등록됩니다.

HTTP 모드용 예제 .cursor/mcp.json:

{
  "mcpServers": {
    "test-http-mcp": {
      "type": "http",
      "url": "http://localhost:8000/mcp/"
    }
  }
}

Gemini와 함께 사용:

{
  "mcpServers": {
    "test": {
      "httpUrl": "http://localhost:8000/mcp/",
      "timeout": 5000
    }
  }
}

stdio를 통해 연결하기 위한 예제 .cursor/mcp.json 항목:

{
  "mcpServers": {
    "test_studio": {
      "command": "uv",
      "args": ["run", "--project", "backend", "run-stdio"],
      "env": { "AUTHORIZATION_TOKEN": "Bearer TEST_TOKEN" }
    }
  }
}

이 서버가 노출하는 기능

  • 도구 (참조 backend/app/tools/):

    • search_cpe(product, version, vendor) — NVD를 통해 공통 플랫폼 열거(CPE) 검색

    • search_cve(cpe_name) — 주어진 CPE에 대한 공통 취약점 및 노출(CVE) 검색

  • 프롬프트 (참조 backend/app/prompts/):

    • sync_nvd_search(dependency, version) — 간단한 취약점 검색 프롬프트

    • async_nvd_search(dependency, version) — 미리 가져온 CVE 데이터가 포함된 고급 프롬프트

프로젝트 스크립트

backend/pyproject.toml에 두 개의 콘솔 진입점이 정의되어 있습니다:

  • run-app → app.main:run_http

  • run-stdio → app.main:run_stdio

  • run-app-local → app.app:main (자동 리로드 포함)

개발

일반적인 작업 (backend/ 디렉토리에서 실행):

uv run ruff check .           # lint
uv run mypy .                 # type check
uv run pytest                 # tests
uv run mdformat .             # format markdown

프론트엔드 작업 (frontend/ 디렉토리에서 실행):

npm run dev                   # start dev server
npm run build                 # production build
npm run lint                  # lint with ESLint
npx tsc --noEmit              # type check

구현 참고 사항

  • 루트 ASGI 앱은 auth_mcp에 의해 생성된 Auth0 보호 MCP 앱이며, /api에 FastAPI 하위 앱을 마운트합니다.

  • /mcp/의 MCP 엔드포인트는 적절한 도구 범위가 포함된 유효한 Auth0 Bearer 토큰을 요구합니다.

  • /register에서의 동적 클라이언트 등록은 미리 생성된 Auth0 애플리케이션으로 프록시되며, 허용된 콜백 URL을 업데이트합니다. 리다이렉트 URI는 검증됩니다 (HTTPS 필수; localhost에 대해서만 HTTP 허용).

  • 채팅 인터페이스는 취약점을 검색하기 위해 MCP 도구를 호출할 수 있는 Ollama 에이전트와 함께 pydantic-ai를 사용합니다.

  • 채팅 기록은 agen_memory.py를 통해 로컬 SQLite 데이터베이스에 유지됩니다.

  • React 프론트엔드는 줄바꿈으로 구분된 JSON으로 응답을 스트리밍하고 marked 라이브러리로 마크다운을 렌더링합니다.

  • 프로덕션 환경에서 백엔드는 SPA 폴백 라우팅(경로 탐색 보호됨)과 함께 frontend/dist/에서 빌드된 프론트엔드를 서빙합니다.

  • 개발 환경에서 Vite는 /api/* 요청을 8000 포트의 백엔드로 프록시합니다.

라이선스

MIT — LICENSE를 참조하세요.

Available Tools

4 tools
get_called_toolsGet Called ToolsA
Idempotent

Get the list of called tools.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
called_toolsYesThe list of called tools

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description doesn't contradict annotations and adds some context by specifying 'list of called tools' (implying retrieval of historical tool usage data). However, annotations already provide rich behavioral information: readOnlyHint=false (potentially confusing for a 'get' operation), openWorldHint=true, idempotentHint=true, destructiveHint=false. The description doesn't add significant behavioral details beyond what annotations already cover, but it doesn't contradict them either.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, clear sentence with zero wasted words. It's front-loaded with the essential information and perfectly sized for a simple tool. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (0 parameters, rich annotations, output schema exists), the description is reasonably complete. The annotations cover safety and behavioral traits, and the output schema will document return values. The description could be more specific about what 'called tools' means in context, but for a simple retrieval tool, it's mostly adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0 parameters and 100% schema description coverage, the schema already fully documents the lack of inputs. The description doesn't need to explain parameters, and it correctly doesn't mention any. The baseline for 0 parameters is 4, as the description appropriately focuses on the tool's purpose rather than nonexistent parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Get the list of called tools' clearly states the verb ('Get') and resource ('list of called tools'), making the purpose understandable. However, it doesn't distinguish this tool from its siblings (get_time, get_weather, tool_that_access_request) - all are 'get' operations but for different data. The description is adequate but lacks sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. There's no mention of context, prerequisites, or comparison with sibling tools. The agent must infer usage from the tool name alone, which offers minimal guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_timeGet TimeA
Idempotent

Get the current time.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
timeYesThe current time

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide key behavioral hints (readOnlyHint=false, openWorldHint=true, idempotentHint=true, destructiveHint=false), so the description doesn't need to repeat these. The description adds minimal context about what 'current time' means, but doesn't elaborate on format, timezone, or other behavioral details beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description 'Get the current time' is a single, efficient sentence that front-loads the core purpose with zero wasted words. It's appropriately sized for a simple tool with no parameters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (0 parameters, annotations covering key behaviors, and an output schema that presumably handles return values), the description is reasonably complete. However, it could slightly improve by hinting at the output format (e.g., timestamp vs. string) since sibling tools suggest varied contexts.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0 parameters and 100% schema description coverage, the schema fully documents the lack of inputs. The description doesn't need to add parameter information, so it appropriately avoids redundancy. A baseline of 4 is justified since no parameters exist to explain.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Get the current time' clearly states the verb ('Get') and resource ('current time'), making the purpose immediately understandable. However, it doesn't distinguish this tool from potential sibling tools like 'get_called_tools' or 'get_weather', which prevents a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. There are sibling tools like 'get_weather' that might serve related time/weather queries, but the description doesn't mention any context, prerequisites, or exclusions for usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_weatherGet WeatherB
Idempotent

Get the current weather in a given location.

ParametersJSON Schema
NameRequiredDescriptionDefault
locationYesThe location to get the weather for
unitNoThe unit of temperaturecelsius

Output Schema

ParametersJSON Schema
NameRequiredDescription
weatherYesThe weather in the given location

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide key behavioral hints (readOnlyHint=false, openWorldHint=true, idempotentHint=true, destructiveHint=false), so the description doesn't need to repeat these. It adds minimal context by implying real-time data retrieval, but doesn't disclose additional traits like rate limits, error handling, or authentication needs, which would elevate the score.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that front-loads the core purpose without unnecessary details. Every word earns its place, making it highly concise and well-structured for quick understanding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (2 parameters, 100% schema coverage, annotations provided, and an output schema exists), the description is reasonably complete. It states what the tool does, though it could benefit from slight enhancements like mentioning the output includes current conditions, but the output schema likely covers return values, reducing the burden.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents the parameters (location and unit). The description mentions 'location' but adds no extra meaning beyond what the schema provides, such as format examples or usage nuances, meeting the baseline for high coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb ('Get') and resource ('current weather'), and it specifies the scope ('in a given location'). However, it doesn't distinguish this tool from potential siblings like 'get_forecast' or 'get_historical_weather', which would require explicit differentiation for a score of 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It lacks any mention of prerequisites, exclusions, or comparisons with sibling tools (e.g., 'get_time' or 'get_called_tools'), leaving the agent without context for tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

tool_that_access_requestTool That Access RequestC
Idempotent

Access the request.

ParametersJSON Schema
NameRequiredDescriptionDefault
usernameYesThe username of the user

Output Schema

ParametersJSON Schema
NameRequiredDescription
messageYesThe message to the user

TDQS

C2.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations provide significant behavioral information: readOnlyHint=false (implies mutation), openWorldHint=true (handles unknown inputs), idempotentHint=true (safe to retry), and destructiveHint=false (non-destructive). The description adds no behavioral context beyond these annotations—it doesn't explain what 'access' entails operationally, potential side effects, or any constraints like rate limits. However, it doesn't contradict the annotations, so it meets the lower bar with annotations present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise at just three words ('Access the request.'), with no wasted language or unnecessary elaboration. It is front-loaded and efficiently communicates the core idea, though this brevity contributes to its vagueness in other dimensions.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (1 parameter, annotations provide behavioral hints, output schema exists), the description is minimally adequate but incomplete. It lacks context on what the tool actually does, usage scenarios, or output expectations. The presence of an output schema means return values needn't be explained, but the description should still clarify purpose and guidelines better to be fully helpful.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage, with the 'username' parameter fully documented in the schema. The description adds no parameter semantics beyond what the schema provides—it doesn't explain why the username is needed, how it relates to the request, or any contextual details about parameter usage. With high schema coverage, the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose2/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Access the request' is a tautology that essentially restates the tool name 'tool_that_access_request' without adding meaningful specificity. It doesn't clarify what type of request is being accessed, what resource is involved, or what 'access' means in this context (read, modify, submit?). While it includes a verb ('access') and resource ('request'), it remains vague about the actual purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. There are sibling tools like 'get_called_tools', 'get_time', and 'get_weather', but the description doesn't explain how this tool differs from them or in what context it should be selected. No prerequisites, exclusions, or comparative context are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv1.0.0
    • First observedget_called_tools
    • First observedget_time
    • First observedget_weather
    • First observedtool_that_access_request

TDQS

B3.2/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: get_called_tools retrieves internal server usage data, get_time provides current time, get_weather fetches location-based weather, and tool_that_access_request handles request metadata. There is no overlap in functionality, making tool selection unambiguous.

Naming Consistency3/5

Three tools follow a consistent 'get_*' verb_noun pattern, but tool_that_access_request deviates with a noun_verb structure and uses 'that' as a connector. This mixed convention reduces predictability, though the names remain readable.

Tool Count4/5

With 4 tools, the count is reasonable for a demo HTTP server, covering basic utilities like time, weather, and request handling. It is slightly thin for broader HTTP operations but appropriate for a limited scope.

Completeness3/5

The server covers basic utilities but lacks core HTTP operations like making requests (GET, POST) or handling responses, which are expected for an HTTP server. The tools are standalone utilities rather than a cohesive HTTP interface, leaving notable gaps in functionality.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A minimal Model Context Protocol server demo that exposes tools through HTTP API, including greeting, weather lookup, and HTTP request capabilities. Demonstrates MCP server implementation with stdio communication and HTTP gateway functionality.
    9 npm
    ISC
  • A
    license
    A
    quality
    D
    maintenance
    A minimal MCP server example demonstrating Tools, Resources, and Prompts. It enables calculations, time queries, note management, and code review prompts via stdio transport.
    3
    8 npm
    MIT