Skip to main content
Glama
newgepard

opensheet

by newgepard

OpenSheet

데이터베이스 없는 데이터베이스 UI.

테이블은 디스크에 있는 평범한 .jsonl 파일입니다. 셀 하나를 수정하면 — git diff에 한 줄만 표시됩니다. OpenSheet를 닫아도 jq, DuckDB, Excel, pandas, 그리고 AI 에이전트가 모든 것을 그대로 읽을 수 있습니다.

License: MIT Runtime dependencies: 0 Tests: 329 Network calls: 0

中文文档


이것이 무엇인가

스프레드시트-데이터베이스 도구는 행을 어딘가에 저장해야 합니다. 일반적인 해답은 직접 실행해야 하는 데이터베이스, 앱에 포함된 스토리지 엔진, 또는 앱 자체 형식의 단일 바이너리 파일입니다. 세 가지 모두 작동합니다. 세 가지 모두 도구가 사용자와 데이터 사이에 위치한다는 뜻입니다.

OpenSheet의 진실의 원천은 이미 읽는 방법을 알고 있는 텍스트 파일입니다. 폴더 하나가 라이브러리이고, 그 안의 각 .jsonl이 테이블이며, 한 줄이 레코드입니다. 데이터베이스도, 계정도, 서버도, 동기화도 없습니다. OpenSheet를 삭제해도 데이터는 한 치도 움직이지 않습니다.

$ cat my-library/campaigns.jsonl
{"id":"KS-001","project":"Modular Mechanical Keyboard","raised_usd":412870,"rating":5}
{"id":"KS-002","project":"Solar Camp Lantern","raised_usd":88250,"rating":4}

$ jq -r 'select(.rating == 5) | .project' my-library/campaigns.jsonl
Modular Mechanical Keyboard

이것이 저장 형식의 전부입니다. 스프레드시트 UI는 이를 감싸는 래퍼가 아니라 그 위에 놓인 뷰입니다.

Related MCP server: Universal JSON Agent MCP

빠른 시작

Python 3.9+ 필요. pip install도, Docker도, 빌드 단계도 없습니다.

git clone https://github.com/newgepard/opensheet
cd opensheet
PYTHONPATH=src python3 -m opensheet ~/my-library/

브라우저에서 http://127.0.0.1:<사용 가능한 포트>를 엽니다. .jsonl 파일이 있는 폴더, 단일 .jsonl 파일, 또는 빈 폴더를 가리키면 처음부터 시작할 수 있습니다.

macOS 데스크톱 앱 — 860 KB 네이티브 셸(Swift + WKWebView, 시스템 WebKit 사용):

bash shell/build.sh
open shell/build/OpenSheet.app

충실도 약속

다른 모든 것이 이 약속을 중심으로 구축되어 있으며, 단언이 아니라 테스트로 검증됩니다.

1. 건드리지 않은 행은 바이트 단위로 그대로 다시 쓰입니다. 10,000행 테이블에서 셀 하나를 수정하면 git diff에 정확히 한 줄만 변경된 것으로 표시됩니다. 건드리지 않은 행은 다시 직렬화되지 않습니다 — 재정렬도, 재포맷도, 재이스케이프도 없습니다.

2. 비-ASCII 텍스트는 절대 이스케이프되지 않습니다. {"名前":"甲"}은 정확히 그대로 유지됩니다. json.dumps가 기본적으로 수행하고 JSON 파서가 아닌 모든 도구에서 파일을 읽을 수 없게 만드는 {"\u540d\u524d":"\u7532"}로 절대 변하지 않습니다.

3. 희소 파일은 희소하게 유지됩니다. 행에 키가 없으면 OpenSheet는 그 행을 위해 키를 만들어내지 않습니다. 기존 50,000행이 있는 테이블에 필드를 추가해도 그중 어떤 행도 다시 쓰지 않습니다.

실행 취소는 스냅샷 롤백이 아닌 역명령으로 구축되어 있으며, 특히 약속 1이 실행 취소 후에도 유지되도록 하기 위함입니다: 셀을 수정하고 ⌘Z를 누르고 저장하면 — git diff는 비어 있습니다. 스냅샷 복원 구현은 화면에서는 올바르게 보이지만, 건드린 모든 행을 조용히 다시 직렬화할 것입니다.

Editing one cell; git diff shows a single changed line

이를 뒷받침하는 것: 지문 검사가 OpenSheet가 모르는 사이에 이루어진 변경 사항을 덮어쓰는 것을 거부하고, 쓰기는 임시 파일과 os.replace()를 통해 이루어지며, 모든 저장은 열기 시점 스냅샷과 함께 .bak을 유지합니다.

기능

  • 데이터는 사용자가 소유한 파일입니다jq, DuckDB, pandas, Excel, git으로 읽을 수 있는 평범한 .jsonl

  • 모든 것을 실행 취소⌘Z / ⇧⌘Z; 일괄 삭제는 단일 실행 취소 단계로 축소됩니다

  • 13가지 필드 유형 — 텍스트, 숫자, 선택, 다중 선택, 날짜, 체크박스, URL, 첨부 파일, 수식, 테이블 간 조회, 생성/수정 시간, 자동 번호. 숫자는 저장된 값을 변경하지 않고 진행률 표시줄, 통화, 평점 또는 백분율로 렌더링됩니다

  • 4가지 뷰 유형 — 그리드, 칸반, 갤러리, 그리고 뷰별 필터, 정렬, 그룹화, 통계, 행 높이, 열 고정, 열 순서

  • 10,000행도 매끄럽게 유지 — 가상 스크롤링; 7.5 MB 테이블 로드에 57 ms, 저장에 59 ms로 측정됨

  • 가져오기 및 내보내기 — CSV, XLSX, JSON, SQLite, .grist에서 가져오기; CSV, XLSX, JSON, JSONL, Markdown, Parquet로 내보내기

  • 첨부 파일은 로컬에 유지 — 파일은 <library>/assets/에 저장되고, 셀은 상대 경로를 보유하며, 어디에도 업로드되지 않습니다

AI로 장식된 것이 아니라 에이전트를 위해 구축됨

스프레드시트에 AI 버튼을 추가하는 것은 기능입니다. 에이전트가 어댑터 없이 읽고 쓸 수 있는 저장 형식을 선택하는 것은 아키텍처입니다. OpenSheet는 후자를 선택했고, 다른 모든 것은 그로부터 따라옵니다: 파일이 줄 단위라서 추가가 >>로 가능하고, 형식이 텍스트라서 grep이 작동하며, 작성자가 단일이라서 동시 접근에도 바이트 충실도가 유지됩니다.

MCP 서버는 HTTP 서버와 같은 프로세스에서 실행되며 하나의 Store 인스턴스를 공유합니다:

{
  "mcpServers": {
    "opensheet": {
      "command": "python3",
      "args": ["-m", "opensheet", "/path/to/libraries", "--mcp", "--mcp-root", "/path/to/libraries"],
      "env": { "PYTHONPATH": "/path/to/opensheet/src" }
    }
  }
}

도구: list_libraries, list_tables, get_schema, query, upsert_rows. upsert_rows는 영수증 — inserted / updated / unchanged 개수와 각각의 기본 키 — 을 반환하며 dry_run을 지원합니다. 디스크에 이미 있는 것과 동일한 행은 unchanged로 간주되며 파일은 건드리지 않습니다.

같은 프로세스는 구현 세부 사항이 아닙니다. 바이트 충실도는 프로세스 내 상태, 즉 각 행이 어떤 바이트로 도착했는지에 의존합니다. 각자 자신의 복사본을 보유한 두 프로세스는 서로의 쓰기를 "변경"으로 결론내리고 다음 저장 시 전체 파일을 다시 직렬화할 것입니다. 두 번째 프로세스는 잠금 파일을 감지하고 첫 번째 프로세스로 전달하므로, 항상 정확히 하나의 작성자만 존재합니다.

에이전트는 OpenSheet를 건너뛰고 파일에 직접 추가할 수도 있습니다. 그렇게 할 때 충실도를 유지하는 규칙은 직접 쓰기 가이드에 문서화되어 있습니다.

아키텍처

graph TD
    A["my-library/"] --> B["campaigns.jsonl<br/>source of truth"]
    A --> C["suppliers.jsonl"]
    A --> D[".opensheet/<br/>schema · views · links"]
    B --> E["store.py<br/>row passthrough · atomic write"]
    C --> E
    E --> F["single process"]
    F --> G["HTTP + browser UI"]
    F --> H["MCP over stdio"]
    G --> I["native macOS shell"]

.opensheet/는 필드 유형, 열 너비, 뷰 정의, 테이블 간 링크를 보관합니다. 삭제하면 서식만 잃고 데이터는 잃지 않습니다 — 필드 유형은 추론으로 대체됩니다.

작게 유지되는 이유

백엔드는 Python 표준 라이브러리만 사용합니다. 프론트엔드는 순수 JavaScript입니다 — 프레임워크도, 빌드 단계도 없습니다. macOS 셸은 번들 브라우저가 아닌 시스템 WebKit 위의 184 KB Swift입니다.

DuckDB는 선택 사항이며 읽기 전용으로, SQL 패널과 Parquet 내보내기를 담당합니다. 필터링, 정렬, 그룹화에는 절대 참여하지 않으며 절대 쓰지 않습니다. 모든 쓰기는 store.py를 통해 이루어집니다.

구조적으로 네트워크 없음

텔레메트리도, 업데이트 확인도, CDN 자산도, 온라인 데모도 없습니다. 브라우저는 동일 출처의 /api/* 경로만 요청하고, 서버는 IPv4 루프백에만 바인딩하며, 데스크톱 셸은 자체 TCP 연결을 전혀 보유하지 않습니다. tests/test_offline.py가 이 모든 것을 강제합니다.

검증

bash tests/opensheet-全量验收-20260815.sh

329개 테스트: JavaScript 단위 188개, Python 83개, 브라우저 종단 간(Playwright) 42개, 충실도 왕복 8개, 라이브러리 왕복 8개. 충실도 테스트는 필드별이 아니라 바이트 단위로 파일을 비교합니다 — 값만 확인하는 테스트는 약속 1이 조용히 깨져도 통과할 것입니다.

브라우저 테스트는 Playwright의 Chromium을 위해 web/ 안에서 npm install이 필요합니다.

OpenSheet가 하지 않을 것

댓글, 권한, 실시간 협업, 자동화, 호스팅 버전, 온라인 데모. 이 각각은 계정 시스템이나 공개 주소가 필요하며, 이는 첫 번째 설계 제약과 모순됩니다: 데이터는 절대 사용자 머신을 떠나지 않는다.

이것은 의도적인 경계이지 로드맵의 공백이 아닙니다.

상태

매일 사용 중이며 작동하지만, 시도하기 전에 알아둘 만한 두 가지 거친 부분이 있습니다:

  • UI는 현재 중국어 전용입니다. 코드, 주석, 인터페이스 문자열이 모두 중국어입니다. 영어 현지화는 아직 완료되지 않았습니다.

  • 데스크톱 셸은 macOS 전용입니다. 웹 버전은 Python이 실행되는 모든 곳에서 작동합니다.

기여

이슈와 PR을 환영합니다. 저장 계층을 건드리기 전에 알아야 할 두 가지:

  1. store.py의 행 통과 로직 자체가 제품입니다. 이를 변경한다는 것은 충실도 테스트를 통과하게 유지한다는 뜻이며, 그 테스트는 필드가 아닌 바이트를 비교합니다.

  2. 코드 주석은 현재 중국어입니다. 번역 도움을 매우 환영합니다.

라이선스

MIT — LICENSE 참조.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

0Releases (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 Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Provides AI agents with database-like operations over LanceDB with automatic BGE-M3 multilingual embedding generation, enabling semantic search, CRUD operations, and safe schema migrations across structured data.
  • A
    license
    A
    quality
    B
    maintenance
    Turns a folder of CSV, Parquet, and JSON files into a single SQL-queryable source for AI agents, supporting JOINs across files with read-only sandboxed access.
    6
    2
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to read, write, query, and manage JSON data files with automatic ID and timestamp generation.
    6
    20
    1
    MIT

View all related MCP servers

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/newgepard/opensheet'

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