Skip to main content
Glama
leonardows1

SAP B1 ServiceLayer MCP Server

by leonardows1

SAP B1 ServiceLayer MCP 서버

SAP Business One 10.0의 ServiceLayer를 로컬 네트워크에서 AI 어시스턴트(opencode, Claude 등)에 연결하기 위한 MCP(Model Context Protocol) 서버입니다. 이 GitHub 저장소에서 npx로 실행할 수 있으며, PC에 아무것도 설치할 필요가 없습니다.

특징

  • 기본 읽기 전용: SAP_B1_READONLY=true(기본값)로 설정하면 조회(GET) 도구만 등록됩니다. 쓰기(POST/PATCH/DELETE) 도구는 서버에 존재하지 않으며 호출할 수 없습니다.

  • 전체 검색: sap_list_entities, sap_get_entity_schema, sap_list_actionsGET /$metadata(프로세스당 한 번만 다운로드하여 캐시)를 조회하여 ServiceLayer의 ~140개 CRUD 엔티티(사용자 테이블 @ 및 UDO 포함)와 수백 개의 서비스 메서드를 노출합니다.

  • 선택적 쓰기 모드: SAP_B1_READONLY=false로 설정하면 ServiceLayer 엔티티에 대한 sap_create, sap_update, sap_delete와 서비스 메서드에 대한 sap_call_action이 활성화됩니다(부작용이 있을 수 있음).

  • npx github:로 실행: 수동 설치 없이 실행할 수 있습니다.

  • 세션 관리: CompanyDB/사용자/비밀번호로 암시적 로그인, B1SESSION + ROUTEID 쿠키를 메모리에 유지(멀티 노드 ServiceLayer 지원), 401 발생 시 자동 재로그인, 프로세스 종료 시 로그아웃 보장(sap_logout 도구 외에도).

  • 자체 서명 TLS: 로컬 환경에서 흔한 ServiceLayer의 자체 서명 인증서를 SAP_B1_VERIFY_TLS=false로 지원합니다.

  • 원격 측정 없음, 외부 호출 없음: HTTP 클라이언트는 설정된 URL(SAP_B1_SERVER_URL)만 가리킵니다.

  • 보안 제한: top은 쿼리당 200개 레코드로 제한됩니다.

Related MCP server: BTP MCP Server

도구

읽기(항상 사용 가능)

도구

설명

sap_query

select, filter, top(≤200), skip, orderby, expand를 사용한 모든 OData 엔티티에 대한 일반 GET

sap_list_entities

ServiceLayer가 노출하는 모든 OData 엔티티 나열($metadata에서 캐시됨); 사용자 테이블(@) 및 UDO 포함. filter로 범위를 좁힐 수 있음

sap_get_entity_schema

엔티티 스키마: 속성(유형/키) 및 navigationProperties($expand에 유효); EntityType을 공유하는 엔티티 집합 해결

sap_list_actions

서비스 메서드(function imports, 예: CompanyService_GetCompanyInfo)와 해당 매개변수 나열

sap_sql_query

POST /sql_query를 통한 읽기 전용 SQL(SELECT/WITH; INSERT/UPDATE/DELETE/DDL은 거부됨) — 최신 ServiceLayer v2/FP에서만; 이전 v1에서는 명확한 오류 응답

sap_get_business_partners

비즈니스 파트너(고객/공급업체), card_type으로 필터링

sap_get_items

카탈로그의 항목

sap_get_sales_orders

판매 주문; v1에서는 라인(DocumentLines)이 expand 없이 포함됨(expand는 v2 전용)

sap_get_stock

ItemCode(+ 선택적 WarehouseCode)로 항목의 재고; ServiceLayer에 ItemStock이 없으면 명확한 오류(구버 v1)

sap_session_status

활성 세션 상태

sap_logout

세션 명시적 종료

쓰기(SAP_B1_READONLY=false인 경우에만)

도구

설명

sap_create

엔티티에 레코드 생성(POST)

sap_update

키로 레코드 업데이트(PATCH)

sap_delete

키로 레코드 삭제(DELETE)

sap_call_action

서비스 메서드 호출(POST); 부작용 발생 가능(Cancel, UpdateCompanyInfo, Import...)

요구 사항

  • Node.js 18+

  • ServiceLayer가 활성화된 SAP Business One 10.0(일반 경로 https://<host>:50000/b1s/v1)

  • opencode(또는 모든 MCP 클라이언트)

구성(환경 변수)

변수

필수

기본값

설명

SAP_B1_SERVER_URL

-

ServiceLayer 기본 URL(예: https://<host>:50000/b1s/v1)

SAP_B1_DATABASE

-

CompanyDB 이름(예: SBODEMO_XX)

SAP_B1_USERNAME

-

ServiceLayer 사용자

SAP_B1_PASSWORD

-

사용자 비밀번호

SAP_B1_READONLY

아니요

true

false로 설정하면 쓰기 도구 활성화

SAP_B1_VERIFY_TLS

아니요

true

false로 설정하면 자체 서명 인증서 허용

SAP_B1_MAX_TOP

아니요

200

쿼리당 top 최대 한도

opencode와 함께 사용

프로젝트의 opencode.json에서:

{
  "mcp": {
    "sap-b1-servicelayer": {
      "type": "local",
      "command": ["npx", "-y", "github:leonardows1/sap-b1-servicelayer-mcp"],
      "environment": {
        "SAP_B1_SERVER_URL": "https://<host>:50000/b1s/v1",
        "SAP_B1_DATABASE": "<CompanyDB>",
        "SAP_B1_USERNAME": "<usuario>",
        "SAP_B1_PASSWORD": "<password>",
        "SAP_B1_SESSION_TIMEOUT": "30",
        "SAP_B1_VERIFY_TLS": "false",
        "SAP_B1_READONLY": "true"
      },
      "enabled": true
    }
  }
}

구성 저장 후 opencode를 다시 시작하세요.

보안

  • 자격 증명 및 세션 쿠키는 로그에 기록되지 않습니다.

  • 프로세스는 SAP_B1_SERVER_URL과만 통신합니다.

  • READONLY=true 모드에서는 쓰기 도구가 등록되지 않습니다. 즉, 레코드를 생성/업데이트/삭제하는 것이 설계상 불가능합니다.

  • 시작 시 구성 검증: SAP_B1_SERVER_URL, SAP_B1_DATABASE, SAP_B1_USERNAME 또는 SAP_B1_PASSWORD가 없으면 프로세스가 명확한 메시지와 함께 중단됩니다.

  • 엔티티 이름 검증(^[A-Za-z][A-Za-z0-9_]*$): 경로 주입 불가(예: BusinessPartners/...).

  • 키 값 및 필터는 OData에서 이스케이프 처리(작은따옴표 두 번): '가 포함된 id 또는 ItemCode는 URL이나 $filter를 깨뜨리지 않습니다.

  • 비밀번호는 MCP 클라이언트 구성에 평문으로 저장됩니다. 저장소를 공유하는 경우 비밀 관리자를 고려하세요.

  • npx github:는 semver 버전 관리가 없습니다. 각 실행은 main 브랜치의 최신 버전을 가져옵니다. 저장소를 업데이트한 후 npm cache clean --force를 사용하여 강제로 다시 로드하세요.

구조

실용적인 헥사고날 아키텍처(ESM, 프레임워크 없음): 도메인과 사용 사례는 MCP 전송이나 HTTP를 알지 못합니다. 인프라가 ServiceLayerPort(DIP)를 구현하고 MCP 도구는 얇은 컨트롤러입니다.

sap-b1-servicelayer-mcp/
├── package.json                  # Definición del paquete npm (bin: server.js)
├── server.js                     # Composition root: cablea dependencias y arranca stdio
├── src/
│   ├── config/
│   │   └── config.js             # Configuración desde env, validada e inmutable
│   ├── domain/
│   │   ├── errors.js             # Excepciones tipadas (Configuration/InvalidArgument/ServiceLayer)
│   │   ├── oData.js              # Helpers puros: query string, filtros, clamp de $top, validación de entidad
│   │   └── edmx.js               # Parseo puro de $metadata: entity sets, esquemas, function imports
│   ├── application/
│   │   ├── ports.js              # Puerto ServiceLayerPort (contrato, DIP)
│   │   ├── helpers.js            # ensureOk / ensureSuccess / unwrapValue
│   │   └── services/
│   │       ├── queryService.js   # Consulta GET genérica a entidades OData
│   │       ├── catalogService.js # Socios de negocio y artículos (compone QueryService)
│   │       ├── salesService.js   # Pedidos de venta y stock
│   │       ├── sessionService.js # Estado y cierre de sesión
│   │       ├── writeService.js   # create / update / delete
│   │       ├── metadataService.js # Descubrimiento: $metadata cacheado, entidades, esquemas y actions
│   │       └── sqlService.js     # SQL de solo lectura (SELECT/WITH) vía POST /sql_query
│   └── infrastructure/
│       ├── http/
│       │   ├── httpClient.js     # Cliente HTTP mínimo (http/https)
│       │   ├── cookies.js        # Manipulación pura de cookies de sesión
│       │   └── serviceLayerClient.js # Adaptador del puerto: login, 401, logout
│       └── mcp/
│           ├── result.js         # ok / err / serialize / handle (controladores delgados)
│           └── tools.js          # Registro de tools MCP
├── test/                         # node:test (sin dependencias externas)
│   ├── config.test.js
│   ├── oData.test.js
│   ├── edmx.test.js              # parseo EDMX v3/v4 (entity sets, esquemas, function imports)
│   ├── cookies.test.js
│   ├── client.test.js
│   ├── fakePort.js               # fake tipado del puerto ServiceLayerPort (compartido)
│   ├── services.test.js          # casos de uso con cliente fake (anti-inyección)
│   ├── metadataService.test.js   # descubrimiento y acciones con fake
│   ├── sqlService.test.js        # SQL solo-lectura (rechazos, Service Not Found)
│   └── tools.test.js             # integración MCP in-memory (registro y llamadas)
├── .gitignore
└── README.md

실제 스키마에 대한 적응(ServiceLayer 10.0 v1에서 검증됨)

서버는 각 인스턴스의 $metadata에 동적으로 적응하며, 하드코딩된 것이 없습니다. 실제 인스턴스(v1, OData v3)에서 검증된 사실:

  • EntityType을 공유하는 EntitySet: Orders/Invoices/DeliveryNotesSAPB1.Document. sap_get_entity_schema는 실제 유형을 자동으로 해결합니다.

  • 문서 라인: v1에서는 복합 컬렉션(DocumentLines, DocumentInstallments)으로 응답에 인라인으로 포함됩니다. $expand는 navigationProperties에만 적용됩니다(스키마가 나열, 예: BusinessPartner, Currency).

  • 재무 필드: v1에서 BusinessPartners에는 Balance가 없습니다. CurrentAccountBalance, OpenOrdersBalance, OpenDeliveryNotesBalance를 사용하세요. 송장에는 BalanceDue가 없습니다. 미결 잔액은 DocTotal − PaidToDate입니다.

  • 구버전 v1에는 ItemStock/sql_query 없음: sap_get_stock은 발견된 실제 재고 엔티티로 알림; sap_sql_query는 명확한 오류 반환.

  • v3 function imports에서 IsBindable="true"인 것은 bound로 나열되어(독립적으로 호출 불가) sap_list_actions를 오염시키지 않습니다.

레시피: 잔액 연령 보고서(30/60/90)

SQL 없이 sap_query만으로(모든 v1/v2에서 작동):

  1. 열린 송장(많은 경우 skip으로 200개 이하 배치로 페이지 매김):

    sap_query('Invoices',
      filter='PaidToDate lt DocTotal',
      select='CardCode,CardName,DocNum,DocDate,DocDueDate,DocTotal,PaidToDate,DocumentStatus,ControlAccount')
  2. 각 송장에 대해: 잔액 = DocTotal − PaidToDate; 일수 = 오늘 − DocDueDate.

  3. 범위 0-30 / 31-60 / 61-90 / 90+ 및 고객별(또는 계정 보기용 ControlAccount별)로 그룹화.

  4. 고객/계정별 합계: sap_get_business_partners에서 CurrentAccountBalance(현재 잔액) 및 CreditLimit 사용.

sap_sql_query(v2)를 사용하면 동일한 보고서가 OINV/OINV3/OFRJ/OCRD에 대한 단일 쿼리입니다.

개발

npm install     # dependencias
npm test        # tests (node:test)
npm run typecheck  # verificación de tipos estricta (tsc --noEmit sobre JSDoc)
npm start       # arranque local (requiere variables de entorno)

모든 JS 코드는 JSDoc(checkJs + strict + noUncheckedIndexedAccess)을 통한 엄격한 TypeScript로 검증됩니다. tsconfig.json은 빌드 단계 없이, 서버는 node로 직접 실행됩니다.

수동 검증(stdio를 통한 JSON-RPC)

echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | \
  SAP_B1_SERVER_URL=... SAP_B1_DATABASE=... SAP_B1_USERNAME=... SAP_B1_PASSWORD=... \
  npx -y github:leonardows1/sap-b1-servicelayer-mcp
F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to integrate with SAP systems via OData REST APIs for querying entity sets, performing CRUD operations, and executing function imports. It features automatic service discovery, CSRF token management, and smart connection handling without requiring the SAP RFC SDK.
    11
    12
  • F
    license
    A
    quality
    C
    maintenance
    Enables interaction with SAP S/4HANA systems via OData, allowing service discovery, metadata exploration, field value retrieval, and CRUD operations through natural language.
    4
    5
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables interaction with SAP Business One via Service Layer REST API to retrieve and create business data such as partners, orders, invoices, items, and stock levels through natural language.
    1

View all related MCP servers

Related MCP Connectors

  • Self-hosted MCP gateway: turn any API, database or MCP server into AI connectors — no code.

  • Odoo ERP for AI agents: hosted OAuth endpoint, gated writes, one endpoint for every instance.

  • Connect your AI assistants to Keboola and expose your data, transformations, SQL queries, ...

View all MCP Connectors

Latest Blog Posts

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/leonardows1/sap-b1-servicelayer-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server