{"_id":"@asobacloud/odse-mcp","_rev":"2-177fc747a2c23b385d91c4c98e78d44a","name":"@asobacloud/odse-mcp","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@asobacloud/odse-mcp","version":"1.0.0","keywords":["mcp","odse","ods-e","energy","telemetry","transformer","model-context-protocol"],"author":{"name":"Asoba","email":"support@asoba.co"},"license":"MIT","_id":"@asobacloud/odse-mcp@1.0.0","maintainers":[{"name":"asoba","email":"shingai@asoba.co"}],"homepage":"https://github.com/AsobaCloud/odse-mcp","bugs":{"url":"https://github.com/AsobaCloud/odse-mcp/issues"},"bin":{"odse-mcp":"bin/cli.js"},"dist":{"shasum":"c45f251106d2040b5ae23bd164dd3cfd8061afd5","tarball":"https://registry.npmjs.org/@asobacloud/odse-mcp/-/odse-mcp-1.0.0.tgz","fileCount":28,"integrity":"sha512-CKCHMdwkaat2hGv0xebQ0bI8Xk449jSZ47GX6e/MwsnnwqMnWuEZ7owsbV4Gdh7LaO2tN2sTU0eAPQf105D60A==","signatures":[{"sig":"MEUCIEwfHu6HjYxq9ZgNV9x6lksTaLitahgnx4Qe8CkivRyaAiEAgQvQ8MbC4XXrDlT2HD+wlCoQG25kULD+ZEADmN+l2ww=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":48670},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.0.0"},"gitHead":"a9d60e6dc8d1c797c0acc3d6af56d81d46b19c7c","scripts":{"dev":"node --watch dist/index.js","test":"node tests/mcp-server.test.mjs","build":"tsc","start":"node dist/index.js","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"asoba","email":"shingai@asoba.co"},"repository":{"url":"git+https://github.com/AsobaCloud/odse-mcp.git","type":"git"},"_npmVersion":"12.0.2","description":"MCP server that converts OEM energy telemetry to ODS-E records and validates them via the published odse Python package.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@modelcontextprotocol/sdk":"^1.0.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/odse-mcp_1.0.0_1786150177466_0.6347049203782014","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@asobacloud/odse-mcp","version":"1.0.1","description":"MCP server that converts OEM energy telemetry to ODS-E records and validates them via the published odse Python package.","keywords":["mcp","odse","ods-e","energy","telemetry","transformer","model-context-protocol"],"author":{"name":"Asoba","email":"support@asoba.co"},"license":"MIT","homepage":"https://github.com/AsobaCloud/odse-mcp","repository":{"type":"git","url":"git+https://github.com/AsobaCloud/odse-mcp.git"},"type":"module","main":"dist/index.js","bin":{"odse-mcp":"bin/cli.js"},"scripts":{"build":"tsc","start":"node dist/index.js","dev":"node --watch dist/index.js","test":"node tests/mcp-server.test.mjs","prepublishOnly":"npm run build && npm test"},"dependencies":{"@modelcontextprotocol/sdk":"^1.0.0"},"devDependencies":{"@types/node":"^22.0.0","typescript":"^5.4.0"},"engines":{"node":">=22.0.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"gitHead":"74fd15448e7688422cbb8bab000c75c6ab0f3e41","types":"./dist/index.d.ts","_id":"@asobacloud/odse-mcp@1.0.1","bugs":{"url":"https://github.com/AsobaCloud/odse-mcp/issues"},"_nodeVersion":"24.18.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-BpNen/jcEnJZiiFt7YzdpbXzX1XGwfPsF8OYLdsq58FcBwoHeiwKdrOKnHMSA/u33XbpVm2kbvIk9U4d1Epg/w==","shasum":"ea5e0b0e428b1bb8ea722aed55d0d44b634fb367","tarball":"https://registry.npmjs.org/@asobacloud/odse-mcp/-/odse-mcp-1.0.1.tgz","fileCount":28,"unpackedSize":48805,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDwfu+iAP33r8CRMniZ8wDaUwXOZfufZ92AV8/VJow8uwIgQpkyD7iji4Aeqrn6iCLp4JiNX41L8KAUS0x4LoTNvwQ="}]},"_npmUser":{"name":"asoba","email":"shingai@asoba.co"},"directories":{},"maintainers":[{"name":"asoba","email":"shingai@asoba.co"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/odse-mcp_1.0.1_1786171612329_0.4923300575395222"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-08T00:49:37.298Z","modified":"2026-08-08T06:46:52.613Z","1.0.0":"2026-08-08T00:49:37.630Z","1.0.1":"2026-08-08T06:46:52.475Z"},"bugs":{"url":"https://github.com/AsobaCloud/odse-mcp/issues"},"author":{"name":"Asoba","email":"support@asoba.co"},"license":"MIT","homepage":"https://github.com/AsobaCloud/odse-mcp","keywords":["mcp","odse","ods-e","energy","telemetry","transformer","model-context-protocol"],"repository":{"type":"git","url":"git+https://github.com/AsobaCloud/odse-mcp.git"},"description":"MCP server that converts OEM energy telemetry to ODS-E records and validates them via the published odse Python package.","maintainers":[{"name":"asoba","email":"shingai@asoba.co"}],"readme":"# <img src=\"https://raw.githubusercontent.com/AsobaCloud/odse-mcp/master/docs/odse.svg\" alt=\"ODS-E\" width=\"36\" height=\"36\" align=\"bottom\" /> ODS-E Conversion\n\nMCP server for [ODS-E](https://github.com/AsobaCloud/odse) energy telemetry conversion. AI coding/data agents call its tools over the [Model Context Protocol](https://modelcontextprotocol.io/) to convert OEM payloads into ODS-E records and validate them via the published [`odse`](https://pypi.org/project/odse/) Python package.\n\n[![npm](https://img.shields.io/npm/v/@asobacloud/odse-mcp.svg)](https://www.npmjs.com/package/@asobacloud/odse-mcp)\n[![CI](https://github.com/AsobaCloud/odse-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/AsobaCloud/odse-mcp/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n\nThe installed **`odse`** package is the source of truth for OEM support, transform behavior, and validation semantics.\n\n## Quick start\n\nSet `ODSE_WORKSPACE` to an absolute path used when resolving relative `payload_file` values. If omitted, the server uses its process working directory. The server speaks MCP over **stdio** (no HTTP port).\n\n**Prerequisite:** `python3` on `PATH` must be able to `import odse` (`pip install odse`).\n\n### Cursor\n\nAdd to `~/.cursor/mcp.json` or the project `.cursor/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"odse\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@asobacloud/odse-mcp\"],\n      \"env\": {\n        \"ODSE_WORKSPACE\": \"/absolute/path/to/your/data\"\n      }\n    }\n  }\n}\n```\n\nRestart Cursor (or reload MCP servers), then ask the agent to convert or validate ODS-E data.\n\n### Claude Code\n\nCLI (user scope):\n\n```bash\nclaude mcp add --transport stdio --scope user \\\n  --env ODSE_WORKSPACE=/absolute/path/to/your/data \\\n  odse -- npx -y @asobacloud/odse-mcp\n```\n\nOr put the same JSON under `mcpServers` in project `.mcp.json` (team-shared) or `~/.claude.json` (user-wide):\n\n```json\n{\n  \"mcpServers\": {\n    \"odse\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@asobacloud/odse-mcp\"],\n      \"env\": {\n        \"ODSE_WORKSPACE\": \"/absolute/path/to/your/data\"\n      }\n    }\n  }\n}\n```\n\nVerify with `claude mcp list`. Project `.mcp.json` servers need approval the first time you open the repo in Claude Code.\n\n### Codex\n\nCLI:\n\n```bash\ncodex mcp add odse --env ODSE_WORKSPACE=/absolute/path/to/your/data -- npx -y @asobacloud/odse-mcp\n```\n\nOr edit `~/.codex/config.toml` (or project `.codex/config.toml` in a trusted project):\n\n```toml\n[mcp_servers.odse]\ncommand = \"npx\"\nargs = [\"-y\", \"@asobacloud/odse-mcp\"]\n\n[mcp_servers.odse.env]\nODSE_WORKSPACE = \"/absolute/path/to/your/data\"\n```\n\nCodex CLI, the IDE extension, and the ChatGPT desktop Codex host share this config.\n\n### Run directly\n\n```bash\npip install odse\nnpx -y @asobacloud/odse-mcp\n```\n\n## Tools\n\n| Tool | Runtime | What it does |\n|------|---------|----------------|\n| `ListSupportedOEMs` | `python3` | Returns OEM source keys from the installed `odse` transformer registry, plus `odse.__version__`. |\n| `ConvertToODSE` | `python3` | Calls `odse.transformer.transform` on raw CSV/JSON text or a file. Optional `source`, `asset_id`, `timezone`, `timeout`. If `source` is omitted, OEM is auto-detected from payload **content** only. |\n| `ValidateODSERecord` | `python3` | Calls `odse.validate_batch` on a JSON **array** of records. |\n\n### ConvertToODSE\n\n| Argument | Description |\n|----------|-------------|\n| `payload` | Raw telemetry text (CSV or JSON) |\n| `payload_file` | Path to a telemetry file (relative paths resolve against `ODSE_WORKSPACE`) |\n| `source` | OEM key (e.g. `huawei`); omit to auto-detect |\n| `asset_id` | Optional asset id forwarded to `odse.transform` |\n| `timezone` | Optional timezone forwarded to `odse.transform` (e.g. `+02:00`) |\n| `timeout` | Timeout in ms (default `120000`, max `600000`) |\n\nExample (explicit source):\n\n```json\n{\n  \"name\": \"ConvertToODSE\",\n  \"arguments\": {\n    \"source\": \"huawei\",\n    \"payload\": \"Time,Active Power(kW),Inverter State\\n2024-01-01 12:00:00,12.0,0\\n\"\n  }\n}\n```\n\nSuccessful responses are JSON on the tool text channel, for example:\n\n```json\n{\n  \"records\": [\n    {\n      \"timestamp\": \"2024-01-01T12:00:00Z\",\n      \"kWh\": 1.0,\n      \"error_type\": \"normal\",\n      \"error_code\": \"0\"\n    }\n  ],\n  \"count\": 1,\n  \"source\": \"huawei\",\n  \"odse_version\": \"0.8.2\"\n}\n```\n\nLive-fetch arguments (`url`, `headers`, `body`, …) are rejected: not part of this release.\n\n### ValidateODSERecord\n\nPass `records` as a **JSON string** of an array of objects. Optional `level` is forwarded to `odse.validate_batch` (default `schema`).\n\n```json\n{\n  \"name\": \"ValidateODSERecord\",\n  \"arguments\": {\n    \"records\": \"[{\\\"timestamp\\\":\\\"2024-01-01T12:00:00Z\\\",\\\"kWh\\\":1.0,\\\"error_type\\\":\\\"normal\\\"}]\"\n  }\n}\n```\n\nValidation follows **`odse.validate_batch`** package semantics (not a separate JSON Schema checker). Extra properties and numeric bounds behave as the installed `odse` version defines them.\n\nTool exit code `1` becomes `isError: true` on the MCP result. Unexpected crashes are reported as errors.\n\n## Requirements\n\n| Runtime | Required for |\n|---------|----------------|\n| Node.js ≥ 22 | MCP server |\n| Python 3 + [`odse`](https://pypi.org/project/odse/) | All tools (`pip install odse`) |\n\n## Architecture\n\n```\nrules/*.json          → tool schemas + execution specs\nscripts/*.py          → odse wrappers (list / convert / validate)\nsrc/loader.ts         → bundled rules\nsrc/runner.ts         → spawn, timeouts, exit-code → isError\nsrc/index.ts          → MCP stdio server\nbin/cli.js            → npx / bin entrypoint\n```\n\n## Development\n\n```bash\ngit clone https://github.com/AsobaCloud/odse-mcp.git\ncd odse-mcp\npython3 -m venv .venv\nsource .venv/bin/activate   # Windows: .venv\\Scripts\\activate\npip install odse\nnpm install\nnpm run build\nnpm test\n```\n\n| Script | Purpose |\n|--------|---------|\n| `npm run build` | Compile TypeScript → `dist/` |\n| `npm test` | E2E via real MCP `Client` + fixture assertions |\n| `npm start` | Run the server on stdio |\n| `npm run dev` | `node --watch` on `dist/` |\n\nLocal MCP config (instead of npx):\n\n```json\n{\n  \"mcpServers\": {\n    \"odse\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/odse-mcp/dist/index.js\"],\n      \"env\": {\n        \"ODSE_WORKSPACE\": \"/absolute/path/to/your/data\",\n        \"PATH\": \"/absolute/path/to/odse-mcp/.venv/bin:/usr/bin:/bin\"\n      }\n    }\n  }\n}\n```\n\nEnsure the `PATH` (or environment) makes `python3` resolve to an interpreter that can `import odse`.\n\n## Releasing\n\nCI runs build + E2E on every push/PR (Node 22 + `pip install odse`). To publish a new version:\n\n1. Bump `version` in `package.json`\n2. Commit, push, and create a GitHub Release (`gh release create vX.Y.Z --generate-notes`)\n3. `.github/workflows/publish.yml` publishes to npm (Trusted Publisher / OIDC, or `NPM_TOKEN` if configured)\n\n## License\n\nMIT © [Asoba](https://asoba.co)\n","readmeFilename":"README.md"}