# DS Studio MCP — 생성형 AI의 DSLText 작성·검증 안내 > 실행 엔드포인트: `https://dualsoft.ai/mcp` · channel: `stable`. 실제 버전과 buildCommit은 initialize 응답 및 X-Build-Commit 헤더에서 확인하세요. 사용자 요구를 **완전한 `.ds2` 원문으로 작성하는 주체는 연결된 AI**입니다. MCP는 공식 문서, 컴파일, 실행 추적과 증거를 제공합니다. `dsdx.start`는 공식 시작 예제를 반환하며 사용자 공정을 생성하거나 채택하지 않습니다. `dsdx.ai.probe`는 작성한 원문을 검사합니다. 존재하지 않는 생성 도구를 만들지 마세요. > 작업 순서: **실제 도구 발견 → 시작 예제 → 공식 본문 → 요구·기대값 → 전체 원문 → 컴파일 → 실행 대조 → 원문과 증거 반환.** 원문을 고칠 때마다 다시 검사합니다. ## 1. 지금 사용할 수 있는 연결을 확인한다 - **연결된 MCP 클라이언트**: 실제 `tools/list` 결과에서 사용할 도구와 `inputSchema`를 읽습니다. 이 문서의 JSON은 호출 예시이며, 실제 도구 응답은 아닙니다. - **URL을 읽기만 하는 웹 AI**: [공식 작성 본문](https://dualsoft.ai/ai-start) 또는 [일반 텍스트](https://dualsoft.ai/ai-start.txt)를 읽고 원문을 작성할 수 있습니다. 도구를 호출할 수 없다면 `MCP 연결 UNCONFIRMED`, 작성 원문은 `UNVERIFIED_DRAFT`로 표시하고 [웹 원문 입력](https://dualsoft.ai/play#source)에 붙여 넣어 실제 컴파일하도록 안내합니다. URL을 읽었다는 이유로 컴파일·검증 성공을 선언하지 않습니다. 비공개 원문을 URL 쿼리에 넣지 않습니다. 직접 HTTP 클라이언트를 구현할 때는 Stable `POST https://dualsoft.ai/mcp`, Experimental `POST https://dualsoft.ai/mcp-exp`에 JSON-RPC 2.0을 보냅니다. `Content-Type: application/json`, `Accept: application/json, text/event-stream`을 사용합니다. 초기화 예: ```json {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"dsl-author","version":"1.0"}}} ``` 서버 응답의 협상 버전·instructions·build 정보를 확인하고 `notifications/initialized`, `tools/list` 순서로 진행합니다. 지원 MCP 버전은 `2025-06-18`, `2025-03-26`, `2024-11-05`이며 Host 계약 버전 `DSDX-MCP/1.0`과 구별합니다. 초기화 뒤 모든 HTTP 요청에는 협상한 버전의 헤더(예: `MCP-Protocol-Version: 2025-06-18`)를 보내고, 반환된 세션 ID도 `Mcp-Session-Id` 헤더에 전달합니다. [공식 전송 계약](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#protocol-version-header)을 따릅니다. 초기화 뒤의 도구 호출은 다음 형태입니다: ```json {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"dsdx.start","arguments":{}}} ``` 이후 JSON 블록은 반복을 줄이기 위해 **`tools/call.params`만** 적습니다. `arguments`는 평면 객체이며 `payload`로 감싸지 않습니다. 실제 스키마에 없는 필드는 보내지 않습니다. `content` 안의 결과와 `structuredContent`, `isError`를 확인하고 원응답을 보존합니다. ## 2. 시작 예제와 공식 본문을 먼저 읽는다 ```json {"name":"dsdx.start","arguments":{}} ``` 반환된 `source`, 컴파일 영수증, `nextCalls`를 확인합니다. 선택 인자 `goal`은 500자 이내의 힌트입니다. 시작 예제의 영수증을 새로 작성한 사용자 공정에 재사용하지 않습니다. ```json {"name":"docs_search","arguments":{"query":"ST 조건식 when while 이전 입력 펄스","version":"DS2-SPEC-V1.2"}} ``` ```json {"name":"docs_read","arguments":{"document_id":"AI-ST-KIT","version":"DS2-SPEC-V1.2"}} ``` ```json {"name":"docs_read","arguments":{"document_id":"MCP-START","version":"DS2-SPEC-V1.1"}} ``` 검색 결과의 `document_id`로 문법·실행 의미·진단의 관련 **본문**도 읽습니다. `docs_read`와 `docs_search`에서 `version`을 생략하면 각 문서의 정본 프로필(`AI-ST-KIT`·`ST-EXPR-SPEC`는 `DS2-SPEC-V1.2`/`ds2/v2`, `SPEC-00`~`SPEC-05`·`MCP-START`는 `DS2-SPEC-V1.1`/`ds2/v1`)을 자동으로 선택하며, 명시적으로 다른 버전을 지정한 경우에만 프로필 불일치로 거절합니다. API/MCP 계약은 `SPEC-03`, 진단 카탈로그는 `contracts/diagnostics.json`입니다. 문서의 `specVersion`, `document_id`, 적용 절, 원문 해시, `buildCommit`을 기록합니다. 검색 요약이나 목차만으로 의미를 정하지 않습니다. 문서가 충돌하면 조항을 제시하고 미결정 상태를 남깁니다. `DS2-SPEC-V1.2` 개발, 새 언어 헤더 `ds2 v2;` (기존 `DS2-SPEC-V1.1`/`ds2 v1;`은 유지), 서버 소스 SHA, 실행 `buildCommit`은 서로 다른 식별자입니다. 개발 결정이나 최신 저장소만 보고 배포 서버가 지원한다고 추정하지 않습니다. 지원 프로필은 실제 응답에서 확인합니다. ## 3. 요구와 독립 기대값을 먼저 정한다 원문 작성 전에 다음을 짧게 정리합니다. 결과에 영향을 주는 미확정 조건만 사용자에게 확인하고, 모델용 가정은 명시합니다. | 항목 | 정할 내용 | |---|---| | 동작 | 순서·분기·합류·상호배제, 실패·중단·복귀 조건 | | 호출 횟수 | 한 번만 실행할지, 매 사이클 새 실행이 필요한지 | | 완료 재사용 | 동일한 API·인자·장치 상태에서 어떤 완료 증거까지 유효한지 | | 제품 범위 | 제품 ID·시도·레시피가 바뀌면 완료 증거를 무효화할지 | | 시간과 입력 | MODEL duration, 실제 센서·출력·외부 명령, 스캔 주기 | | 인수 기대값 | 예: 명령 3회 → 검사 실제 시작/완료 각 3회 → 배출 3회, 호출 완료 전 후속 시작 금지 | **일회 실행, 완료 재사용, 매번 새 실행은 별도 요구입니다.** 현재 유효한 완료를 재사용할 수 있다는 판단을 “영구적으로 한 번만 실행”과 같게 취급하지 않습니다. 다른 제품 검사에 이전 제품의 완료를 재사용하지 않습니다. 유효수명·무효화 조건을 나타내는 새 DSL 키워드를 발명하지 않습니다. 현재 문법으로 표현되지 않는 요구는 한계를 적습니다. 반복 호출되는 Passive 장치는 공식 작성 패턴에 따라 **명시적인 재준비 경로**를 둡니다. 반대 동작은 `<|>`와 양쪽 호출로 모델링하고, 단일 동작은 `검사 =|> 재준비; work 재준비;`처럼 선언합니다. 재준비 보조 Work에는 duration·센서·출력·Call을 넣지 않습니다. 이 보조 Work는 논리 상태를 재준비하며 물리 복귀나 Homing을 수행하지 않습니다. 완료 장치를 자동 Reset하거나 `finished`만으로 실제 물리 완료가 입증된다고 가정하지 않습니다. 또한 Active 공정에서 **외부 명령 1회당 정확히 1사이클만 수행하고 대기**하려면 2-Work는 `A =|> B;`, 3개 이상 직렬 체인은 아래 예제처럼 `투입 => 품질검사 =|> 배출;`로 마지막 링크에 `=|>`를 사용합니다(`배출 =|> 투입;`을 추가하면 외부 명령 없이 자체 무한 반복되며, `품질검사 => 배출; 배출 |> 투입;`만 쓰면 `배출`이 `Finish`에 고착되어 2회차부터 실행되지 않습니다). ## 4. 전체 DSLText를 작성한다 새 ST 조건식의 편집 정본은 `ds2 v2;`로 시작하는 `.ds2`입니다. 기존 `ds2 v1;` 파일은 명시적 이전 없이 재해석하지 않습니다. SDF·IR은 컴파일러의 파생 산출물이며 직접 고쳐서 오류를 숨기지 않습니다. 아래는 **MODEL 실행용 작은 예제**입니다. 실제 제품·센서·PLC·3D 장치를 포함하지 않습니다. ```ds2 ds2 v2; project 생성형_검사라인 { active 라인제어; system 검사기 { flow 동작 { work 검사 { duration 30ms; } work 재준비; 검사 =|> 재준비; } api 검사 = 동작.검사; } system 라인제어 { flow 생산 { work 투입 { duration 10ms; } work 품질검사 { 검사기.검사; } work 배출 { duration 10ms; } 투입 => 품질검사 =|> 배출; } api 한사이클 { command 생산.투입; observe 생산.배출; } } } ``` 사용자 공정은 요구에 맞춰 새로 작성하고 모든 Call의 대상·재준비·시간·완료 조건을 점검합니다. HTML 애니메이션, JSON 모델, 그럴듯한 상태명은 `.ds2` 원문이나 프로젝트 채택 증거가 아닙니다. ## 5. 같은 전체 원문을 실제 컴파일한다 이하 **`${SOURCE}`는 템플릿 표식**입니다. 위 예제 또는 작성한 전체 `.ds2` 문자열로 JSON 인코딩하여 치환합니다. 표식 자체, 파일명, 일부 발췌, 다른 예제를 보내지 않습니다. 비교를 쉽게 하려면 원문을 UTF-8·LF로 유지합니다. ```json {"name":"dsdx.compile","arguments":{"source":"${SOURCE}","scanPeriodMs":10,"view":"full"}} ``` 반환된 diagnostics, `sourceSha256`, 해시 정책, 컴파일 상태와 서버 `buildCommit`을 확인합니다. 컴파일은 `UTF8_EXACT`, 일부 실행 영수증은 `CRLF_TO_LF_UTF8` 정책을 사용하므로 **각 영수증의 정책에 따라 전송한 동일 원문을 해시**합니다. 서로 다른 정책의 해시를 무조건 같다고 비교하지 않습니다. 정규화 산출물의 `canonicalDs2Sha256`도 입력 원문 해시와 구별합니다. ```json {"name":"dsdx.lint","arguments":{"source":"${SOURCE}","includeSealedSdf":false}} ``` 오류는 진단의 코드·위치·원인을 확인하고 원문에서 수정합니다. 변경 후 같은 절차를 다시 실행합니다. 컴파일 성공은 해당 빌드의 문법·정적 검사 통과이며 요구 충족·실행 완료·프로젝트 채택·물리 인수와 구별합니다. `activate` 호환 인자는 채택을 수행하지 않습니다. ## 6. 실행 추적을 독립 기대값과 비교한다 앞 예제의 명령을 0·30·60번 스캔에 넣는 MODEL 시험입니다. `externalStimulus` 키는 밀리초가 아닌 **스캔 번호**입니다. 이 예제는 토큰 없는 MODEL이며 `initialTokens`를 모두 0으로 두고 외부 명령을 명시합니다. `initialTokens`는 기동 허가가 아닌 토큰 루트 ID의 초기값입니다. `externalStimulus`의 0번 스캔 항목이 기본 기동 일정을 대체합니다. ```json {"name":"dsdx.verify.run","arguments":{"source":"${SOURCE}","scans":100,"rtScans":100,"initialTokens":{"투입":0,"품질검사":0,"배출":0,"검사":0,"재준비":0},"externalStimulus":{"0":["투입"],"30":["투입"],"60":["투입"]},"verbosity":"full","view":"full","runMutationHarness":true}} ``` 이 입력은 위 예제 전용입니다. 다른 공정에는 실제 Work ID·기동·센서 시나리오와 충분한 스캔 예산을 정합니다. 확인할 독립 기대값은 **투입→검사 Call→배출 순서, 검사 시작/완료 각 3회, 배출 완료 3회, 매 회차 검사 30ms의 MODEL 시간, 자식 호출 완료를 기다리는 부모**입니다. 기본 `verbosity:"summary"` 응답의 `traceSummary.workGoingEntries`·`traceSummary.workFinishEntries`·`traceSummary.finalPhases`만으로도 대용량 `irTrace` 전체를 받지 않고 각 Work의 전 스캔 시작·완료 횟수를 즉시 확인할 수 있으며, 스캔별 상세 파형이 필요할 때만 `verbosity:"full"` 또는 `fromScan`/`toScan`/`workIds` 슬라이스를 요청합니다. 중간 Reset 때문에 최종 완료 비트만으로 횟수를 세지 않습니다. `VERIFIED_PASS`, `goalSatisfied`, IR/ST 상호 동치, 변이 검출 수만으로 사용자 요구가 맞다고 선언하지 않습니다. 원문에 정한 순서·금지 조건·횟수·시간·제품 영향을 별도로 대조합니다. 실행되지 않은 변이·RT·센서·물리 검사는 `NOT_RUN`으로 남깁니다. RT 부하 측정의 불확실성을 논리 의미 오류와 분리합니다. 호출 회차를 지원하는 빌드는 `apiAdmission` 등 실제 반환 증거를 읽습니다. `TOKENLESS_API_ROUND_1` 같은 프로필, 기본 3회 시험, 대기·busy·stall의 지원 여부를 응답으로 확인합니다. 기본 3회는 재기동 구조가 있고 스캔·외부 입력을 생략했을 때의 해당 빌드 정책입니다. 위처럼 입력을 지정하면 그 시나리오를 검사하며 임의로 회차가 추가된다고 가정하지 않습니다. 외부 센서·가드 입력을 기다리는 상태를 곧바로 데드락으로 판정하지 않습니다. 검증은 job·캐시를 사용할 수 있으므로 공유 사용자의 진행 작업을 보존합니다. 오래 걸리는 실행이나 새 프로젝트 반영은 사용자가 선택한 작업 공간·환경과 해당 도구 계약을 따릅니다. ## 7. `ai.probe`는 작성된 원문의 검사에 쓴다 ```json {"name":"dsdx.ai.probe","arguments":{}} ``` 이 호출은 작성 지침과 공식 예제를 읽습니다. 선택 인자 `guidanceProfile`(`"compact"` · `"standard"` · `"reasoning"`)을 지정하면 경량·표준·심층추론 모델 계층에 맞춘 핵심 구문 카드(`quickCard.syntaxTemplates`)를 함께 받을 수 있습니다. 예제 실행은 `NOT_RUN`이며 새 공정 생성이나 검수 완료가 아닙니다. ```json {"name":"dsdx.ai.probe","arguments":{"source":"${SOURCE}","runVerify":true,"view":"full"}} ``` 원문을 넣으면 컴파일·지원 범위의 검증을 요청할 수 있습니다. 현재 `ai.probe`는 `view:"full"`이어도 원시 `irTrace`·`stTrace` 대신 내부 검증 요약과 `check.verify.traceSummary`(`workGoingEntries`/`workFinishEntries`)를 반환합니다. 외부 명령 스케줄(`externalStimulus`)을 지정한 횟수·순서·시간 대조는 6절처럼 `dsdx.verify.run`으로 따로 확인합니다. probe의 요약만으로 그 목표가 확인됐다고 선언하지 않습니다. `runVerify:false`라면 실행 검증은 `NOT_RUN`입니다. `COMPILE_FAILED`는 원문 진단을 고치고, `COMPILED_UNVERIFIED`는 원문을 보존한 채 미지원 실행 프로필·입력 부족·측정 환경을 구별합니다. 동일 실패를 근거 없이 반복 호출하지 않습니다. ## 8. 3D·채택·배포는 별도 증거와 권한으로 진행한다 공개 3D 라이브러리(`/ui/library/`)의 전체 모델 개수·분류별 개수·설비 검색·메타데이터·`.ds2` 동작 정의·GLB/ZIP 다운로드 정보는 키 없이 다음 MCP 읽기 전용 도구로 즉시 조회합니다: ```json {"name":"dsdx.library.search","arguments":{"q":"","category":"","limit":20,"offset":0}} ``` - `dsdx.library.search`에 `{}`를 전달하면 전체 승인 모델 개수(`modelCount`), 분류별 집계(`categories`), 검색 결과(`items`, 각 항목 최상위 `package_id`/`source_sha256`/`delivery_sha256` 해시 핀 포함) 및 고정 URL(`links`)을 반환합니다. - `dsdx.library.get`에 `{"id":"a01-01-six-axis-robot"}`를 전달하면 외곽 치수(`size`/`bounds`), 단위(`m`/`rad`), 관절(`joints`), 연결 포트(`ports`/`portFrames`), 라이선스(`rights`), 최상위 해시 핀(`package_id`/`source_sha256`/`delivery_sha256`), 검증된 `.ds2` 원문(`ds2Source`)을 반환합니다. - `dsdx.library.download`에 `{"id":"a01-01-six-axis-robot","format":"glb"}`(`glb` | `archive` | `ds2` | `source`)를 전달하면 불변 `?v=` 다운로드 URL과 바이트 수·SHA-256 핀을 반환합니다(`lib3d.assets.search`·`lib3d.assets.get`·`lib3d.assets.download_info` 호환 별칭 지원). 프로젝트 장면 배치와 3D 엔진 카탈로그가 필요하면 `dsdx.scene.catalog` 등 **실제 발견한 도구**의 스키마로 제공 자산을 찾고 출처·버전·단위·포트·기구학을 확인합니다. 공개 3D 라이브러리와 `dsdx.scene.render`의 미리보기는 실제 센서·제품·물리 동작의 인수 결과가 아닙니다. `DISPLAY_PREVIEW`, `NOT_RUN_INPUTS_REQUIRED`이면 정적 배치와 실행 미측정을 그대로 표시합니다. 도형이 움직이는 것만으로 Call·센서·출력·장치 자세가 올바르다고 선언하지 않습니다. 컴파일·검증·렌더는 프로젝트 채택을 대신하지 않습니다. 채택을 요청받으면 `dsdx.project.patch`·`dsdx.project.commit`의 실제 스키마, 수정 대상과 revision을 확인한 뒤 해당 작업 공간에 반영합니다. 내보내기·PLC·공개 링크·배포도 각각의 요청과 권한을 확인합니다. `dsdx.plc.connect/write/deploy`의 원격 호출에는 검증된 소유자 자격이 필요합니다. 같은 소유자 제한을 받는 `dsdx.artifact.publish_link/revoke_link`는 현재 MCP 발견 목록에 없는 Host 연산입니다. 미발견 이름을 MCP 도구로 추정·호출하지 않습니다. 자격이 없거나 거절되면 해당 작업을 멈추고 가짜 토큰·무한 재시도를 하지 않습니다. 외부 생성 모델의 인증 실패, 컴파일 실패, 실행 입력 부족을 구별합니다. 요청한 모델을 다른 모델로 바꾸어 성공으로 보고하지 않습니다. 공개 문서·시작·컴파일을 키 없이 쓸 수 있다는 사실이 모델·사설 라이브러리·하드웨어 접근까지 허용하지는 않습니다. 실제 MCP/PLAY 사용자 인수와 물리 설비 인수는 별도입니다. ## 9. 최종 응답은 원문과 검증 범위를 전달한다 1. 사용한 명세 버전·본문 조항과 가정, 일회/반복·완료 증거 범위. 2. 생략 없는 `.ds2` 원문 또는 사용자가 열 수 있는 원문 파일. 3. 전송 원문 해시 정책·`sourceSha256`, 실제 서버 `buildCommit`, 호출·응답 영수증. 4. 컴파일/정적 검사, MODEL 실행, RT 측정, 3D 미리보기, 사용자/물리 인수를 구분한 결과. 5. 독립 기대값의 관측 결과와 미해결 조건. 미실행 `NOT_RUN`, 근거 부족 `INCONCLUSIVE`, 일치한 컴파일 영수증이 없으면 `UNVERIFIED_DRAFT`. [사람용 연결 안내](https://dualsoft.ai/mcp-guide) · [공식 본문](https://dualsoft.ai/ai-start) · [문서 검색](https://dualsoft.ai/api/docs/search?query=DSLText) · [웹 원문 입력](https://dualsoft.ai/play#source) · [이슈 제보 안내](https://dualsoft.ai/issue-guide) ## ST 조건식 프로필 새 조건식은 `when (BOOL 식);`, `while (BOOL 식);`과 ST 연산자 `AND OR NOT`, `= <> < <= > >=`, `+ - * / MOD`를 씁니다. NOT는 비교보다 먼저이므로 `NOT (n < 2)`처럼 괄호를 씁니다. `rise()/fall()/prev()`나 `:=`는 조건식에 넣지 않습니다. 에지는 입력 계층의 선언된 BOOL 펄스로 제공하며 최초·품질 복구·재시작의 가짜 펄스를 억제합니다. while에는 레벨 허가를 사용합니다. 기존 파일은 `dsdx.project.migrate`의 `targetLanguageVersion: "ds2/v2"`로 AST 이전합니다. 기존 edge에는 정확한 guard 위치별 `guardEdgeBindings`가 필요합니다. 실제 서버가 지원하는 프로필을 먼저 확인하고 물리/동적 미지원은 NOT_RUN으로 남깁니다. `ST-EXPR-SPEC`와 `grammar/ds2-v2.ebnf`를 `DS2-SPEC-V1.2`로 읽으세요. 기본 MCP 연결 문서 `MCP-START` 등은 공통 계약의 기존 V1.1 문서로 따로 읽습니다. ## 이 빌드의 실제 도구 목록 현재 레지스트리는 MCP 도구 47개를 노출합니다: 정본 Host 연산 28개와 확장/호환 도구 19개입니다. Host 정본 연산 수와 MCP 발견 수는 서로 다른 집합입니다. 호출 가능한 이름과 인자 스키마의 정본은 실제 `tools/list` 응답입니다. 확장/호환 도구: `dsdx.start`, `dsdx.ai.probe`, `dsdx.project.inspect`, `dsdx.propose`, `dsdx.validate`, `dsdx.model.validate`, `dsdx.optimize.propose`, `dsdx.aas.promote`, `dsdx.project.migrate`, `dsdx.artifact.get`, `dsdx.library.search`, `dsdx.library.get`, `dsdx.library.download`, `dsdx.scene.catalog`, `dsdx.scene.layout`, `docs_search`, `docs_read`, `dsdx.docs.search`, `dsdx.docs.read`. 문서는 `docs_search`와 `docs_read`를 우선합니다. `dsdx.docs.search/read`는 호환 별칭이며 `docs.search/read`는 등록된 도구가 아닙니다.