Skip to main content
Glama
newgepard

opensheet

by newgepard

OpenSheet

База данных без базы данных.

Ваши таблицы — это обычные файлы .jsonl на диске. Измените одну ячейку — git diff покажет одну строку. Закройте OpenSheet, и jq, DuckDB, Excel, pandas и ваши ИИ-агенты по-прежнему смогут прочитать всё.

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

Это весь формат хранения. Интерфейс электронной таблицы — это представление, а не обёртка вокруг него.

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 КБ (Swift + WKWebView, использует системный WebKit):

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

Обещание точности

Вокруг этого построено всё остальное, и это проверяется тестами, а не просто утверждается.

1. Нетронутые строки записываются обратно байт-в-байт. Измените одну ячейку в таблице из 10 000 строк, и git diff покажет ровно одну изменённую строку. Строки, которые вы не трогали, никогда не сериализуются заново — не переупорядочиваются, не переформатируются, не переэкранируются.

2. Не-ASCII текст никогда не экранируется. {"名前":"甲"} остаётся именно таким. Он никогда не превращается в {"\u540d\u524d":"\u7532"}, что делает json.dumps по умолчанию и что делает файл нечитаемым в любом инструменте, кроме JSON-парсера.

3. Разрежённые файлы остаются разрежёнными. Если в строке нет ключа, OpenSheet не будет выдумывать его для неё. Добавление поля в таблицу с 50 000 существующих строк не перезаписывает ни одну из них.

Отмена построена как обратные команды, а не откат к снимку, специально для того, чтобы обещание 1 пережило её: измените ячейку, нажмите ⌘Z, сохраните — git diff пуст. Реализация с восстановлением снимка выглядела бы корректно на экране, но тихо пере-сериализовывала бы каждую затронутую строку.

Editing one cell; git diff shows a single changed line

Поддержка этого: проверка отпечатка отказывается перезаписывать изменения, сделанные за спиной OpenSheet, записи идут через временный файл плюс os.replace(), и каждое сохранение хранит .bak рядом со снимком на момент открытия.

Возможности

  • Ваши данные — это файл, которым вы владеете — обычный .jsonl, читаемый jq, DuckDB, pandas, Excel и git

  • Отмена всего⌘Z / ⇧⌘Z; пакетное удаление схлопывается в один шаг отмены

  • 13 типов полей — текст, число, выбор, множественный выбор, дата, флажок, URL, вложение, формула, поиск по таблице, время создания/обновления, авто-номер. Числа отображаются как индикаторы прогресса, валюта, рейтинги или проценты без изменения хранимого значения

  • 4 типа представлений — сетка, канбан, галерея, плюс фильтры, сортировки, группировки, статистика, высота строк, закреплённые столбцы и порядок столбцов для каждого представления

  • 10 000 строк остаются плавными — виртуальная прокрутка; замерено 57 мс на загрузку и 59 мс на сохранение таблицы размером 7,5 МБ

  • Импорт и экспорт — импорт из CSV, XLSX, JSON, SQLite и .grist; экспорт в CSV, XLSX, JSON, JSONL, Markdown и Parquet

  • Вложения остаются локальными — файлы попадают в <library>/assets/, ячейка хранит относительный путь, ничего никуда не загружается

Создано для агентов, а не украшено ИИ

Добавить кнопку ИИ в электронную таблицу — это функция. Выбрать формат хранения, который агент может читать и писать без адаптера, — это архитектура. 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 — это 184 КБ Swift на системном WebKit, а не встроенный браузер.

DuckDB опционален и только для чтения, обслуживает SQL-панель и экспорт в Parquet. Он никогда не участвует в фильтрации, сортировке или группировке и никогда не пишет. Каждая запись идёт через store.py.

Нет сети по построению

Никакой телеметрии, никаких проверок обновлений, никаких CDN-ресурсов, никакого онлайн-демо. Браузер запрашивает только same-origin пути /api/*, сервер привязывается только к IPv4 loopback, а настольная оболочка не держит ни одного TCP-соединения. tests/test_offline.py обеспечивает всё это.

Проверка

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

329 тестов: 188 модульных тестов JavaScript, 83 Python, 42 сквозных браузерных (Playwright), 8 тестов точности round-trip, 8 тестов библиотеки round-trip. Тесты точности сравнивают файлы байт-в-байт, а не поле-за-полем — тест, который проверял бы только значения, прошёл бы, пока обещание 1 молча нарушалось.

Для браузерных тестов нужен npm install внутри web/ для Chromium от Playwright.

Чего OpenSheet не будет делать

Комментарии, разрешения, совместная работа в реальном времени, автоматизации, хостинговая версия, онлайн-демо. Каждому из них нужна система аккаунтов или публичный адрес, что противоречит первому проектному ограничению: данные никогда не покидают вашу машину.

Это осознанная граница, а не пробел в дорожной карте.

Статус

Работает и используется ежедневно, с двумя шероховатостями, о которых стоит знать перед попыткой:

  • Интерфейс сейчас только на китайском. Код, комментарии и строки интерфейса — всё на китайском. Английская локализация ещё не сделана.

  • Только macOS для настольной оболочки. Веб-версия работает везде, где есть Python.

Вклад

Приветствуются issues и 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