mcp-mssql-server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-mssql-servershow columns of Sales.Orders"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-mssql-server
SQL Server의 메타데이터(테이블 구조·SP 정의·의존성) 와 가드가 걸린 SELECT 실행을 MCP(Model Context Protocol) 도구로 노출하는 read-only 서버. Claude Code 같은 MCP 호스트가 이 도구를 호출해 스키마와 데이터를 조회할 수 있다.
설계 목표는 LLM에게 DB를 열어주되, 열어준 만큼만 열리게 하는 것이다:
쓰기 도구를 아예 만들지 않는다 (READ ONLY)
모든 응답이 PII 마스킹을 통과한다 (우회 불가)
자유 SQL 도구에는 5중 가드와 감사 로그를 건다
접속정보는 응답·에러 어디에도 나타나지 않는다
사이트별 값(민감 객체 목록, 차단 DB, 예시 객체명)은 소스가 아니라 config.json 에 둔다.
노출 도구 (5종, 모두 조회 전용)
이름 | 입력 | 출력 | 비고 |
| (없음) | DB 키 배열 | 접속정보 비노출, 키만 |
|
| 컬럼 메타데이터 배열 (이름·타입·길이·NULL·PK) | 행 데이터 미반환 |
|
| 정의(definition) + 파라미터 + 메타 | 정의 텍스트 자동 PII 마스킹. |
|
| 참조 객체 ( | 권한 부족 시 |
|
| SELECT 결과 행 (컬럼 기반 PII 마스킹 적용) | 5중 가드 + 감사 로그. 자세한 내용 아래 |
접속 대상 정의
DB 목록은 소스에 없다. config.json 이 DB 키 → .env 변수 접두사를 정의하고, lib/db.js 가 그것을 순회한다.
// config.json
"databases": {
"primary": { "envPrefix": "DB" },
"reporting": { "envPrefix": "REPORTING_DB",
"options": { "encrypt": true, "trustServerCertificate": false } }
}# .env — 접두사 P 에 대해 P_USER / P_PASSWORD / P_SERVER / P_NAME
DB_USER=… DB_PASSWORD=… DB_SERVER=… DB_NAME=…
REPORTING_DB_USER=… REPORTING_DB_PASSWORD=… REPORTING_DB_SERVER=… REPORTING_DB_NAME=…DB 개수·이름이 배포마다 달라도 코드는 그대로다. 도구의
db인자에 쓰는 값이 곧 이 키다(소문자 정규화).databases를 생략하면primary←DB_*단일 DB 로 동작한다.options는 mssql 드라이버 옵션 override. Azure SQL 등 TLS 필수 환경은encrypt: true로 설정해야 한다 (기본값은 사내망 SQL Server 를 상정한encrypt: false,trustServerCertificate: true).정의가 잘못되면(접두사 누락·형식 오류·빈 객체) 조용히 무시하지 않고 기동을 실패시킨다. DB 하나가 말없이 사라지면 원인 추적에 시간을 버리기 때문이다.
exec_query_select로 조회를 막을 DB 는blockedDatabases에 키를 넣는다.
exec_query_select — 5중 가드
자유 SQL 도구는 위험도가 높으므로 다층 방어 적용. 모든 호출(차단·허용)은
~/.claude/logs/mcp-exec-query.log 에 JSON Lines 로 감사 기록된다 (SQL 샘플은 PII 마스킹 후 500자 한도).
# | 가드 | 거부 사유 예시 |
1 | SELECT/WITH(CTE) 만 허용 |
|
2 | 행 수 캡 | 기본 50행, |
3 | 컬럼 기반 PII 마스킹 |
|
4 | 민감 객체 denylist |
|
5 | 차단 DB |
|
- | 다중 statement 차단 | 세미콜론으로 구분된 두 개 이상의 statement 거부 (trailing semicolon 1개는 허용) |
가드의 한계 (반드시 인지):
가드 1/4는 정규식·substring 기반. 의도적 우회(예: 동적 SQL 생성, 다른 뷰를 거친 간접 조회)는 못 막는다. 모델의 우발적 실수 방어가 목적이지, 적대적 사용자 방어가 아니다.
가드 4는 SQL 텍스트 검사. 차단된 뷰를 내부 참조하는 다른 뷰가 있으면 우회 가능 (transitive 참조 추적 X).
가드 2는
recordset.slice()로 잘라낸다 — 서버는 풀 결과를 스캔할 수 있음. 성능 보호는 mssql 기본requestTimeout(15s) 에 의존.
Related MCP server: mssql-explorer-mcp
보안 노트 (3원칙)
READ ONLY — INSERT/UPDATE/DELETE/EXEC 도구는 만들지 않는다.
마스킹 강제 — 모든 응답이 PII 마스킹 wrapper를 통과.
SENSITIVE_MASK=0같은 환경변수 우회는 MCP 경로에서 지원하지 않는다 (secure default). 대상 카테고리:RRN(주민번호 패턴: 6자리-7자리, 7번째 자리 1~8)PHONE(한국 휴대폰: 010/011/016~019)EMAILStable pseudonym: 응답 1건 내에서 동일 값은 동일 placeholder (
[주민번호_1]등)
DB 접속정보 비노출 —
DB_CONFIGS의 값(user/password/server)은 응답·에러 어디에도 포함되지 않는다. 에러 메시지는sanitizeError를 통해 잠재 접속정보 substring을***로 치환.
설치 및 등록
1) 의존성 설치와 설정
npm install
cp .env.example config.json.example 2>/dev/null || true
cp .env.example .env # DB 접속정보 입력
cp config.example.json config.json # 사이트별 가드 설정.env— DB 접속정보.lib/db.js가 저장소 루트의.env를 읽는다.config.json—denylist(민감 객체 접두사),blockedDatabases(조회 금지 DB),examples(도구 설명에 쓰일 예시 표기).⚠️ 이 파일이 없으면 가드 4·5 가 동작하지 않는다. 기본값으로 막아줄 수 있는 값이 없기 때문이다 (사이트마다 객체명이 다르다). 대신 기동 시 stderr 에 경고가 출력되므로 조용히 열리지는 않는다.
둘 다
.gitignore처리되어 있다.
2) MCP 호스트에 등록
프로젝트 루트(<프로젝트>/.mcp.json)에 등록 예:
{
"mcpServers": {
"mssql": {
"command": "node",
"args": ["<이 저장소 절대경로>/server.js"]
}
}
}
.env와config.json은server.js기준 상대경로로 찾으므로cwd를 따로 잡을 필요가 없다. 다른 위치의 설정을 쓰려면MCP_CONFIG환경변수로 경로를 지정한다.
등록 후 Claude Code를 재시작하면 tools/list에 5개 도구가 잡힌다.
3) 동작 검증
npm test # 또는 node smoke_test.js스모크 테스트는 stdio JSON-RPC로 서버를 직접 호출해 검증하고, 실패가 있으면 종료 코드 1로 끝난다. 두 가지 모드로 자동 전환된다:
모드 | 조건 | 검증 범위 |
오프라인 |
| 프로토콜 핸드셰이크, |
전체 |
| 위 + 도구 4종 실제 조회 + 가드 2(행 캡)·3(마스킹) |
보안 가드는 getPool() 호출 이전에 평가되므로, DB에 접근할 수 없는 환경에서도 가드 회귀를 잡을 수 있다.
대상 객체는 TEST_DB / TEST_TABLE / TEST_SP / TEST_SAFE_TABLE 등 환경변수로 바꿀 수 있다.
알려진 한계
PII 마스킹은 정규식 기반. 자유 텍스트 패턴은
lib/mask-patterns.js한 곳에만 정의된다. 이 패턴은 L2 hook(sensitive-prompt-scan.js)의VALUE_PATTERNS와 동일해야 하는데, 훅은 이 저장소 밖에 있어import로 묶을 수 없다. 대신npm test가 훅 파일을 읽어 정규식을 대조하고 어긋나면 실패시킨다(훅이 없는 환경에서는 SKIP). 즉 동기화는 여전히 수동이지만, 어긋난 상태가 조용히 유지되지는 않는다.13자리 BIGINT가 RRN 패턴(7번째 자리 1~8)에 우연히 일치하면
[주민번호_N]으로 마스킹된다. SP 정의 안 하드코딩된 큰 ID에서 발생 가능. 발생 시 운영상 부작용 없음(가독성만 저하).이름 라벨 기반 마스킹(성명/학번/주소 등)은 자유 텍스트 경로에 미적용. L2 훅에는
LABEL_PATTERNS(성명: 홍길동형태)가 있으나 이 서버에는 의도적으로 옮기지 않았다 — 훅 소스 주석이 지적하듯 오탐이 알려져 있기 때문이다. 따라서get_sp_definition이 반환하는 SP 원문 주석에-- 담당자: 홍길동같은 표기가 있으면 마스킹되지 않는다.경로별 차이에 주의: 레코드셋(
exec_query_select)은lib/sensitive-mask.js의 컬럼 기반PERSON규칙이 적용되어 이름이 마스킹된다. 마스킹되지 않는 것은 자유 텍스트 경로다.⚠️ 이전 판 README는 "본 MCP는 raw 데이터 행을 반환하지 않으므로 위험이 낮다"고 적었으나, 이는 도구가 4종이던 v0.1.0 기준 서술이다. v0.2.0의
exec_query_select는 실제로 행을 반환한다. 위험을 낮추는 것은 "행을 반환하지 않음"이 아니라 컬럼 기반 마스킹이다.
get_sp_dependency의sys.dm_sql_referenced_entities는 권한이 필요. 권한 부족 시 referencesError 필드에 메시지가 담기고 빈 결과가 반환된다.
get_sp_definition 의 원본 백업 (backup=true)
SP 수정 전 원본 보존이 필요할 때 backup: true 로 호출하면 .sql 파일을 저장한다.
// 호출
{ "db": "mydb", "sp": "dbo.usp_GetUser", "backup": true }
// 응답 (추가 필드)
{
"backedUp": true,
"backupPath": "<SP_BACKUP_DIR>/mydb_dbo_usp_GetUser.sql",
"backupError": null,
"definition": "...(마스킹본)..."
}핵심 동작:
디스크엔 raw(마스킹 전) 원본을 저장한다. 모델 응답의
definition만 마스킹된다. → 마스킹본을 저장하면 placeholder가 코드 자리에 박힌 깨진 백업이 되므로, 원본 보존 목적상 raw 필수.저장 위치:
SP_BACKUP_DIR환경변수, 기본값은 저장소 안의./backup(.gitignore처리됨).파일명:
{db}_{스키마}_{SP명}.sql(점→언더스코어, 파일명 불가문자/경로구분자는_치환 — path traversal 방지).같은 SP를 다시 백업하면 덮어쓴다 (
current= 현재 DB 버전). **원본 보존은 SP 수정 전에 호출하는 것으로 보장**.백업 실패는 도구를 막지 않는다 —
backedUp:false,backupError로 사유 전달.
보안 노트: 이 기능은 DB를 변경하지 않는다(여전히 read-only). 로컬 파일 1개 쓰기뿐이다. 다만 디스크에 저장되는 것은 마스킹 전 raw 원본이므로,
SP_BACKUP_DIR은 접근 통제된 경로여야 한다. 모델이 받는 것은 마스킹본과 백업 경로 문자열뿐이다.
감사 로그
exec_query_select 호출은 모두 ~/.claude/logs/mcp-exec-query.log (JSON Lines) 에 기록된다.
엔트리 형태:
// 허용
{"ts":"...","db":"mydb","sqlSample":"SELECT … (마스킹 후 500자)","blocked":false,
"rowsAvailable":3,"rowsReturned":3,"truncated":false,"maskingCategories":["PERSON","STUDENT_NUM"]}
// 차단
{"ts":"...","db":"mydb","sqlSample":"INSERT INTO …","blocked":true,
"reason":"SELECT 또는 WITH(CTE)로 시작하는 단일 쿼리만 허용됩니다."}운영 활용:
차단 사유별 빈도 분석 → 모델 호출 패턴 분포 파악
마스킹 카테고리 빈도 → 어떤 종류 PII가 자주 회수되는지 → denylist 보강 근거
변경 이력
0.4.0 (2026-07-20) — 사이트별 값을
config.json으로 분리. DB 목록(databases)·민감 객체denylist·차단 DB(blockedDatabases)·도구 설명 예시가 더 이상 소스에 하드코딩되지 않는다.lib/db.js는 설정을 순회해 접속정보를 구성하므로 DB 개수·이름이 배포마다 달라도 코드 수정이 필요 없다. 설정 누락 시 가드는 비활성이며 기동 시 stderr 경고를 출력한다(조용히 열리지 않음). 잘못된 설정은 기본값으로 흐르지 않고 기동 실패. 자유 텍스트 PII 패턴을lib/mask-patterns.js단일 출처로 추출하고, L2 훅과 어긋나면 테스트가 실패하도록 대조 검사 추가.0.3.1 (2026-07-20) — 독립 저장소로 분리.
package.json에 누락돼 있던mssql·dotenv의존성 선언(원본에선 상위node_modules로 해결되던 것). 서버 identity 를mcp-mssql-server0.3.0으로 정정(기존ijis-db0.1.0과 드리프트).SP_BACKUP_DIR기본값을 절대경로에서./backup으로 변경. 스모크 테스트를 단언·종료코드 기반으로 재작성하고 오프라인 모드 추가.0.3.0 (2026-05-21) —
get_sp_definition에backup옵션 추가 (raw 원본을 current 폴더에 백업, SP 수정 전 보존용). 디스크엔 raw / 모델엔 마스킹본 분리.0.2.0 (2026-05-20) —
exec_query_select도구 추가. 5중 가드 + 감사 로그. 자유 텍스트 마스커 명명 정리 (createFreeTextMasker).0.1.0 (2026-05-19) — 초기 작성. 4개 read-only 도구, 마스킹 wrapper, .env 격리.
Available Tools
2 toolsget_sp_definitionA
Stored Procedure(또는 함수/뷰)의 원본 정의(definition)와 파라미터 목록을 반환. 응답 텍스트는 PII(주민번호·휴대폰·이메일)가 자동 마스킹된다. backup=true 시 마스킹 전 raw 원본을 current 폴더에 .sql 파일로 백업한다(SP 수정 전 원본 보존용). 응답의 backedUp/backupPath 로 결과 확인.
| Name | Required | Description | Default |
|---|---|---|---|
| db | Yes | DB 키 | |
| sp | Yes | 스키마.SP명 (예: dbo.usp_GetUser) | |
| backup | No | true면 raw 원본을 current 폴더(SP_BACKUP_DIR)에 .sql 백업. SP 수정 전 원본 보존용. 기본 false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses PII masking and optional backup behavior with response fields, providing good transparency beyond the input schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single paragraph covering multiple points efficiently; could benefit from clearer separation but not overly verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Describes response fields and PII masking, compensating for lack of output schema; complete for a 3-param tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%; description adds usage context for backup parameter and an example for sp parameter, adding value beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool returns original definition and parameter list of a stored procedure/function/view, distinguishing it from sibling tool get_table_metadata for tables.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies usage for retrieving definitions and for backup before modification, but does not explicitly state when not to use or compare to alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_table_metadataA
테이블/뷰의 컬럼 메타데이터(이름·타입·길이·NULL허용·PK여부)를 반환. 실제 행 데이터는 반환하지 않음.
| Name | Required | Description | Default |
|---|---|---|---|
| db | Yes | DB 키 (예: primary) | |
| table | Yes | 스키마.테이블명 (예: dbo.Users) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It correctly states the tool is read-only (no row data returned). However, it omits details like authentication, error behavior, or response structure beyond listing metadata fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core action, followed by a clarifying exclusion. Every word serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Adequate for a simple metadata retrieval tool. Includes key info (what is returned and what is not). Could be improved by specifying the exact structure of metadata fields or error handling, but sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema covers both parameters with descriptions (100% coverage). Description adds no additional parameter information beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool returns column metadata for tables/views and explicitly excludes row data. Distinguishes from sibling get_sp_definition by specifying the resource type (table/view vs stored procedure).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool vs alternatives (e.g., get_sp_definition). Does not mention prerequisites, exclusions, or context for usage.
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. Dates show when Glama detected each change.
2 tool updates
v0.4.0- First observed
get_sp_definition - First observed
get_table_metadata
TDQS
The two tools have clearly distinct purposes: one retrieves column metadata for tables/views, the other retrieves stored procedure definitions. There is no overlap in functionality.
Both tool names follow a consistent `get_<object>_metadata` pattern with snake_case and descriptive verbs (get). The naming is predictable and clear.
With only two tools for a server named 'mssql-server', the surface is extremely thin. A typical database server would need many more tools (e.g., query, list objects, DDL operations) to be useful. The count is far too low for the implied scope.
The tool set covers only metadata retrieval for tables and stored procedures. Missing are fundamental operations like executing queries, listing all objects, or modifying schema. Agents will face dead ends when trying to interact with the database beyond these two narrow tasks.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP server for detecting and redacting PII (Personally Identifiable Information) in PDF documents.
An MCP server that provides read access to your cloud storage providers, bank accounts and more.
Guarded MCP server for agent-readable business truth, provenance, readiness, and discovery.
Read-only MCP server for The Quiet Protocol's engines, benchmarks, proof, and business data.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceRead-only SQL Server MCP server enabling safe database queries, table listing, and schema inspection with built-in security protections.MIT
- AlicenseNot gradedqualityCmaintenanceA read-only MCP server for exploring on-premises, multi-instance Microsoft SQL Server estates from AI clients, with read-only enforcement and Windows authentication support.Apache 2.0
- FlicenseAqualityCmaintenanceA read-only MCP server for browsing and querying SQL Server databases, providing tools to list schemas, tables, describe columns, and execute safe SELECT queries with validated parameters.15-
- AlicenseNot gradedqualityAmaintenanceA read-only MCP server for Microsoft SQL Server that enables metadata discovery, parameterized queries, and query analysis with profile-based configuration and strict no-DML/DDL enforcement.7MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/hyunjongmoon/mcp-mssql-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server