obsidian-mcp-server 3.1.4 → 3.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +5 -3
- package/Dockerfile +6 -2
- package/README.md +5 -2
- package/changelog/3.1.x/3.1.5.md +17 -0
- package/changelog/3.1.x/3.1.6.md +23 -0
- package/changelog/template.md +67 -25
- package/package.json +4 -4
- package/server.json +3 -3
package/CLAUDE.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Agent Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** obsidian-mcp-server
|
|
4
|
-
**Version:** 3.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
|
|
4
|
+
**Version:** 3.1.6
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.8.20`
|
|
6
|
+
**Engines:** Bun ≥1.3.11, Node ≥24.0.0
|
|
6
7
|
|
|
7
8
|
> **Read the framework docs first:** `node_modules/@cyanheads/mcp-ts-core/CLAUDE.md` contains the full API reference — builders, Context, error codes, exports, patterns. This file covers server-specific conventions only.
|
|
8
9
|
|
|
@@ -304,8 +305,9 @@ Available skills:
|
|
|
304
305
|
| `api-errors` | McpError, JsonRpcErrorCode, error patterns |
|
|
305
306
|
| `api-linter` | MCP definition linter rule reference (`bun run lint:mcp` failures) |
|
|
306
307
|
| `api-services` | LLM, Speech, Graph services |
|
|
308
|
+
| `api-telemetry` | OTel catalog: spans, metrics, completion logs, env config, cardinality rules |
|
|
307
309
|
| `api-testing` | createMockContext, test patterns |
|
|
308
|
-
| `api-utils` | Formatting, parsing, security, pagination, scheduling |
|
|
310
|
+
| `api-utils` | Formatting, parsing, security, pagination, scheduling, telemetry helpers |
|
|
309
311
|
| `api-workers` | Cloudflare Workers runtime |
|
|
310
312
|
|
|
311
313
|
When you complete a skill's checklist, check the boxes and add a completion timestamp at the end (e.g., `Completed: 2026-03-11`).
|
package/Dockerfile
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This stage installs all dependencies (including dev), builds the TypeScript
|
|
5
5
|
# source code into JavaScript, and prepares the production assets.
|
|
6
6
|
# ==============================================================================
|
|
7
|
-
FROM oven/bun:1 AS build
|
|
7
|
+
FROM oven/bun:1.3 AS build
|
|
8
8
|
|
|
9
9
|
WORKDIR /usr/src/app
|
|
10
10
|
|
|
@@ -28,7 +28,7 @@ RUN bun run build
|
|
|
28
28
|
# application. It uses a slim base image and only includes production
|
|
29
29
|
# dependencies and build artifacts.
|
|
30
30
|
# ==============================================================================
|
|
31
|
-
FROM oven/bun:1-slim AS production
|
|
31
|
+
FROM oven/bun:1.3-slim AS production
|
|
32
32
|
|
|
33
33
|
WORKDIR /usr/src/app
|
|
34
34
|
|
|
@@ -85,6 +85,10 @@ ARG PORT
|
|
|
85
85
|
# Set runtime environment variables
|
|
86
86
|
# Note: PORT is an automatic variable in many cloud environments (e.g., Cloud Run)
|
|
87
87
|
ENV MCP_HTTP_PORT=${PORT:-3010}
|
|
88
|
+
# Bind to all interfaces inside the container so the host's `-p` mapping can reach it;
|
|
89
|
+
# loopback would be unreachable from outside the container. For deployments beyond the
|
|
90
|
+
# operator's own machine, set MCP_AUTH_MODE=jwt or oauth — the default `none` plus this
|
|
91
|
+
# bind exposes the upstream OBSIDIAN_API_KEY to any caller that can reach the port.
|
|
88
92
|
ENV MCP_HTTP_HOST="0.0.0.0"
|
|
89
93
|
ENV MCP_TRANSPORT_TYPE="http"
|
|
90
94
|
ENV MCP_SESSION_MODE="stateless"
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<div align="center">
|
|
9
9
|
|
|
10
|
-
[](https://www.npmjs.com/package/obsidian-mcp-server) [](https://www.npmjs.com/package/obsidian-mcp-server) [](./CHANGELOG.md) [](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) [](https://modelcontextprotocol.io/)
|
|
11
11
|
|
|
12
12
|
[](./LICENSE) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
13
13
|
|
|
@@ -231,7 +231,7 @@ MCP_TRANSPORT_TYPE=http OBSIDIAN_API_KEY=... bun run start:http
|
|
|
231
231
|
|
|
232
232
|
### Prerequisites
|
|
233
233
|
|
|
234
|
-
- [Bun v1.3.11](https://bun.sh/) or higher (or Node.js
|
|
234
|
+
- [Bun v1.3.11](https://bun.sh/) or higher (or Node.js v24+).
|
|
235
235
|
- The [Obsidian Local REST API](https://github.com/coddingtonbear/obsidian-local-rest-api) plugin installed and enabled in your vault. Generate an API key in **Settings → Community Plugins → Local REST API** and copy it into `OBSIDIAN_API_KEY`.
|
|
236
236
|
- This server defaults to `http://127.0.0.1:27123` for simplicity. Enable **"Non-encrypted (HTTP) Server"** in the plugin settings to use it. To use the always-on HTTPS port instead, set `OBSIDIAN_BASE_URL=https://127.0.0.1:27124`; the plugin's self-signed cert is handled by `OBSIDIAN_VERIFY_SSL=false` (the default).
|
|
237
237
|
|
|
@@ -281,6 +281,7 @@ MCP_TRANSPORT_TYPE=http OBSIDIAN_API_KEY=... bun run start:http
|
|
|
281
281
|
| `MCP_PUBLIC_URL` | Public origin override for TLS-terminating reverse-proxy deployments (landing page, Server Card, RFC 9728 metadata). | unset |
|
|
282
282
|
| `MCP_AUTH_MODE` | Auth mode: `none`, `jwt`, or `oauth`. | `none` |
|
|
283
283
|
| `MCP_AUTH_SECRET_KEY` | **Required when `MCP_AUTH_MODE=jwt`.** ≥32-char shared secret used to verify incoming JWTs. | — |
|
|
284
|
+
| `MCP_AUTH_DISABLE_SCOPE_CHECKS` | When `true`, bypasses per-tool scope enforcement after the auth-context presence check. Token signature, audience, issuer, and expiry validation remain intact. Use only when a custom claim can't be injected and combine with `OBSIDIAN_READ_PATHS` / `OBSIDIAN_WRITE_PATHS` / `OBSIDIAN_READ_ONLY` for access control. A `WARNING` is logged at startup whenever the bypass is active. | `false` |
|
|
284
285
|
| `MCP_LOG_LEVEL` | Log level (RFC 5424). | `info` |
|
|
285
286
|
| `LOGS_DIR` | Directory for log files (Node.js only). | `<project-root>/logs` |
|
|
286
287
|
| `OTEL_ENABLED` | Enable OpenTelemetry. | `false` |
|
|
@@ -320,6 +321,8 @@ docker run --rm -e OBSIDIAN_API_KEY=your-key -p 3010:3010 obsidian-mcp-server
|
|
|
320
321
|
|
|
321
322
|
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to `/var/log/obsidian-mcp-server`. OpenTelemetry peer dependencies are installed by default — build with `--build-arg OTEL_ENABLED=false` to omit them.
|
|
322
323
|
|
|
324
|
+
The image binds to `0.0.0.0` inside the container (required for Docker port mapping). For any deployment reachable beyond your own machine, set `MCP_AUTH_MODE=jwt` (with `MCP_AUTH_SECRET_KEY`) or `oauth` — otherwise the listener forwards your `OBSIDIAN_API_KEY` to the vault on behalf of every caller.
|
|
325
|
+
|
|
323
326
|
## Project structure
|
|
324
327
|
|
|
325
328
|
| Directory | Purpose |
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: Bump @cyanheads/mcp-ts-core ^0.8.15 → ^0.8.18 and document the auth requirement for HTTP deployments beyond loopback.
|
|
3
|
+
breaking: false
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 3.1.5 — 2026-05-06
|
|
7
|
+
|
|
8
|
+
Maintenance release: framework dep refresh, paired skill sync, and a documentation clarification around HTTP transport posture. No source-code changes in this server.
|
|
9
|
+
|
|
10
|
+
## Changed
|
|
11
|
+
|
|
12
|
+
- **`@cyanheads/mcp-ts-core` `^0.8.15 → ^0.8.18`.** Three upstream patch releases roll up:
|
|
13
|
+
- `0.8.16` — fixes an HTTP SSE per-request retention leak. `closePerRequestInstances` now binds to the request `AbortSignal` so ungraceful client disconnects close the per-request `McpServer` / transport pair. Affects this server when run under HTTP transport; pure framework fix, no consumer code change needed.
|
|
14
|
+
- `0.8.17` — surfaces `ctx.sessionId` on `Context` for HTTP handlers (defined in `stateful` / `auto` mode; opt-in via `createApp({ context: { exposeStatelessSessionId: true } })` under stateless). This server doesn't currently key on it.
|
|
15
|
+
- `0.8.18` — fixes `ctx.auth.token` being silently stripped in `toAuthContext`, and types `token?: string` on the public `AuthContext`. Doesn't apply here — this server forwards its own `OBSIDIAN_API_KEY` upstream, not the caller's bearer.
|
|
16
|
+
- **`skills/api-context` `1.2 → 1.3`.** Picks up the upstream skill update covering `ctx.sessionId` — defined-when matrix across transport / session / auth modes, the stateless opt-in, capability-token coherence note, and strict / lax state-keying recipes.
|
|
17
|
+
- **README + Dockerfile clarify auth requirement for non-loopback HTTP deployments.** The Docker image binds `MCP_HTTP_HOST=0.0.0.0` (required so the host's `-p` port mapping can reach the listener inside the container), and `MCP_AUTH_MODE` defaults to `none`. The README's Docker section and a new comment in the Dockerfile both now call this out and recommend `MCP_AUTH_MODE=jwt` or `oauth` for any deployment reachable beyond the operator's machine. Thanks to Ryan for surfacing the gap.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Pick up `mcp_tool_scopes` claim + `MCP_AUTH_DISABLE_SCOPE_CHECKS` bypass from `@cyanheads/mcp-ts-core` 0.8.20 — resolves [#47](https://github.com/cyanheads/obsidian-mcp-server/issues/47) for OIDC providers that can't override `scope`."
|
|
3
|
+
breaking: false
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 3.1.6 — 2026-05-09
|
|
8
|
+
|
|
9
|
+
Maintenance release. Picks up the framework-side fix for [#47](https://github.com/cyanheads/obsidian-mcp-server/issues/47) — operators behind Authentik / Keycloak < 26.5 / Zitadel can now inject per-tool scopes via the `mcp_tool_scopes` custom claim, or set `MCP_AUTH_DISABLE_SCOPE_CHECKS=true` and rely on `OBSIDIAN_READ_PATHS` / `OBSIDIAN_WRITE_PATHS` / `OBSIDIAN_READ_ONLY` for access control. No source changes in this server.
|
|
10
|
+
|
|
11
|
+
## Changed
|
|
12
|
+
|
|
13
|
+
- **`@cyanheads/mcp-ts-core` `^0.8.18` → `^0.8.20`.** Two upstream releases roll up:
|
|
14
|
+
- `0.8.19` — engines bumped to Bun ≥1.3.0 / Node ≥24.0.0; Docker base `oven/bun:1` → `oven/bun:1.3`; new `api-telemetry` skill (v1.0); changelog frontmatter `security: bool` field; `init` template substitutions resolve `{{MCP_SDK_VERSION}}` and `{{ZOD_VERSION}}` from the framework `package.json`.
|
|
15
|
+
- `0.8.20` — `mcp_tool_scopes` JWT claim parsed alongside `scp` and `scope` (granted scopes are the union); `MCP_AUTH_DISABLE_SCOPE_CHECKS` env var bypasses both `withRequiredScopes` and `checkScopes` after the auth-context presence check (signature/audience/issuer/expiry validation intact); `authFactory` logs `WARNING` at startup whenever the bypass is active under non-`none` mode. ([cyanheads/mcp-ts-core#128](https://github.com/cyanheads/mcp-ts-core/issues/128))
|
|
16
|
+
- **`engines.node` `>=22.0.0` → `>=24.0.0`** (mirroring the framework). README prerequisites line updated.
|
|
17
|
+
- **Docker base image `oven/bun:1` → `oven/bun:1.3`** for build and production stages — pins to the matching minor of the framework's published image.
|
|
18
|
+
- **`@types/node` `^25.6.0` → `^25.6.2`.**
|
|
19
|
+
- **README** — env-var table gains `MCP_AUTH_DISABLE_SCOPE_CHECKS` row covering the bypass semantics, the path-policy combination, and the startup `WARNING`.
|
|
20
|
+
- **`.env.example`** — new comment block under the auth section documents the `mcp_tool_scopes` claim union, the OIDC `authorization_code` restriction, and the bypass-flag fallback.
|
|
21
|
+
- **`CLAUDE.md`** — header version updated; skills table picks up the new `api-telemetry` row and the refreshed `api-utils` description (now scoped to the helper API; OTel catalog moved to `api-telemetry`).
|
|
22
|
+
- **Phase A skill bumps** (synced from framework): `api-telemetry` (new, v1.0), `api-auth` 1.0 → 1.1 (claims mapping table + OIDC operator setup + bypass docs), `api-config` 1.3 → 1.4 (env-var row), `api-utils` 2.1 → 2.2 (telemetry section now points to `api-telemetry`), `maintenance` 2.0 → 2.1 (Phase C resyncs pristine reference files), `report-issue-framework` 1.5 → 1.6, `report-issue-local` 1.4 → 1.5 (terser issue-writing guidance), `security-pass` 1.3 → 1.4 (Axis 2 bypass-in-production check), `setup` 1.6 → 1.7 (`bunx` examples, `release-and-publish` in progression), `tool-defs-analysis` 1.0 → 1.1 (env var names allowed in recovery hints).
|
|
23
|
+
- **Phase C reference-file sync:** `scripts/build-changelog.ts` parses the new `security` frontmatter field; `changelog/template.md` documents it.
|
package/changelog/template.md
CHANGED
|
@@ -1,41 +1,71 @@
|
|
|
1
1
|
---
|
|
2
|
-
# FORMAT REFERENCE —
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
#
|
|
8
|
-
|
|
9
|
-
#
|
|
10
|
-
#
|
|
2
|
+
# FORMAT REFERENCE — do not edit. Copy this file to
|
|
3
|
+
# `changelog/<major.minor>.x/<version>.md` (e.g. `changelog/0.8.x/0.8.6.md`)
|
|
4
|
+
# to author a new release. Set that file's H1 to `# <version> — YYYY-MM-DD`
|
|
5
|
+
# with a concrete date.
|
|
6
|
+
|
|
7
|
+
# Required. One-line GitHub Release-style headline. ~250 character soft cap.
|
|
8
|
+
# Default short and scannable. Don't pad, don't stitch unrelated changes with
|
|
9
|
+
# semicolons — pick the headline. Quotes required: unquoted YAML treats `: `
|
|
10
|
+
# inside the value as a key separator and fails GitHub's strict parser.
|
|
11
11
|
summary: ""
|
|
12
12
|
|
|
13
|
-
# Set
|
|
14
|
-
# changes, config renames,
|
|
15
|
-
# Flagged as
|
|
13
|
+
# Set `true` when consumers must change code to upgrade: API removals,
|
|
14
|
+
# signature changes, config renames, behavior changes that break existing
|
|
15
|
+
# usage. Flagged as `Breaking` in the rollup.
|
|
16
16
|
breaking: false
|
|
17
|
+
|
|
18
|
+
# Set `true` if this release contains any security fix. Pairs with the
|
|
19
|
+
# `## Security` section below. Flagged as `Security` in the rollup so
|
|
20
|
+
# users can triage upgrade urgency at a glance.
|
|
21
|
+
security: false
|
|
17
22
|
---
|
|
18
23
|
|
|
19
24
|
# <version> — YYYY-MM-DD
|
|
20
25
|
|
|
21
26
|
<!--
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
AUTHORING GUIDE — applies to the new per-version file you create from this
|
|
28
|
+
template.
|
|
29
|
+
|
|
30
|
+
Audience: someone scanning release notes to decide what affects them. Lead
|
|
31
|
+
each bullet with the symbol or concept name in **bold** so they can skip
|
|
32
|
+
what's irrelevant and zoom in on what's not.
|
|
33
|
+
|
|
34
|
+
Tone: terse, fact-dense, not verbose. Default to one sentence per bullet —
|
|
35
|
+
name the symbol, state what changed, stop. Use a second sentence only when
|
|
36
|
+
it carries weight. If a bullet feels long, it is.
|
|
37
|
+
|
|
38
|
+
Cut: mechanism walkthroughs (those belong in JSDoc, AGENTS.md, or the
|
|
39
|
+
relevant skill), ceremonial framings ("This release introduces…",
|
|
40
|
+
backwards-compat paragraphs), file-by-file test enumerations, internal
|
|
41
|
+
implementation notes. Prefer code/symbol names over English re-explanations.
|
|
42
|
+
|
|
43
|
+
Narrative intro: skip by default. Add one short sentence only when the
|
|
44
|
+
release theme genuinely needs framing the bullets can't carry.
|
|
45
|
+
|
|
46
|
+
Sections: Keep a Changelog order — Added, Changed, Deprecated, Removed,
|
|
47
|
+
Fixed, Security. Include only sections with entries; delete the rest
|
|
48
|
+
(including the commented-out scaffolding below). Don't ship empty headers.
|
|
25
49
|
|
|
26
|
-
|
|
50
|
+
Include: every distinct fact a reader needs to adopt or audit the release —
|
|
51
|
+
new exports, signatures, lint rule IDs, env vars, breaking changes, version
|
|
52
|
+
bumps on shipped skills. Nothing more.
|
|
27
53
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
54
|
+
Links: link issues, PRs, docs, or skills where they help a reader jump to
|
|
55
|
+
context. Once per item per entry — don't re-link the same issue in summary,
|
|
56
|
+
narrative, and bullet. Skip links for inline symbol names; code spans speak
|
|
57
|
+
for themselves.
|
|
31
58
|
|
|
32
|
-
|
|
33
|
-
|
|
59
|
+
Issue/PR URLs: use full URLs. GitHub's bare `#NN` auto-link only resolves
|
|
60
|
+
inside its own UI, not in npm reads or local editors.
|
|
34
61
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
62
|
+
[#38](https://github.com/cyanheads/mcp-ts-core/issues/38) ← issue
|
|
63
|
+
[#42](https://github.com/cyanheads/mcp-ts-core/pull/42) ← PR
|
|
64
|
+
|
|
65
|
+
Verify numbers exist before linking (`gh issue view NN`, `gh pr view NN`).
|
|
66
|
+
Never speculate on a future number — `#42` for an upcoming PR silently
|
|
67
|
+
resolves to whatever real item already owns 42, and timeline previews pull
|
|
68
|
+
in that unrelated item's metadata.
|
|
39
69
|
-->
|
|
40
70
|
|
|
41
71
|
## Added
|
|
@@ -46,6 +76,18 @@ breaking: false
|
|
|
46
76
|
|
|
47
77
|
-
|
|
48
78
|
|
|
79
|
+
<!-- ## Deprecated
|
|
80
|
+
|
|
81
|
+
- -->
|
|
82
|
+
|
|
83
|
+
<!-- ## Removed
|
|
84
|
+
|
|
85
|
+
- -->
|
|
86
|
+
|
|
49
87
|
## Fixed
|
|
50
88
|
|
|
51
89
|
-
|
|
90
|
+
|
|
91
|
+
<!-- ## Security
|
|
92
|
+
|
|
93
|
+
- -->
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "obsidian-mcp-server",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.6",
|
|
4
4
|
"mcpName": "io.github.cyanheads/obsidian-mcp-server",
|
|
5
5
|
"description": "MCP server for Obsidian vaults — read, write, search, and surgically edit notes, tags, and frontmatter via the Local REST API plugin. STDIO or Streamable HTTP.",
|
|
6
6
|
"type": "module",
|
|
@@ -69,14 +69,14 @@
|
|
|
69
69
|
"license": "Apache-2.0",
|
|
70
70
|
"engines": {
|
|
71
71
|
"bun": ">=1.3.11",
|
|
72
|
-
"node": ">=
|
|
72
|
+
"node": ">=24.0.0"
|
|
73
73
|
},
|
|
74
74
|
"packageManager": "bun@1.3.11",
|
|
75
75
|
"publishConfig": {
|
|
76
76
|
"access": "public"
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
|
-
"@cyanheads/mcp-ts-core": "^0.8.
|
|
79
|
+
"@cyanheads/mcp-ts-core": "^0.8.20",
|
|
80
80
|
"@types/js-yaml": "^4.0.9",
|
|
81
81
|
"js-yaml": "^4.1.1",
|
|
82
82
|
"pino-pretty": "^13.1.3",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
86
|
"@biomejs/biome": "^2.4.14",
|
|
87
|
-
"@types/node": "^25.6.
|
|
87
|
+
"@types/node": "^25.6.2",
|
|
88
88
|
"depcheck": "^1.4.7",
|
|
89
89
|
"ignore": "^7.0.5",
|
|
90
90
|
"tsc-alias": "^1.8.17",
|
package/server.json
CHANGED
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
"url": "https://github.com/cyanheads/obsidian-mcp-server",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "3.1.
|
|
9
|
+
"version": "3.1.6",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
14
14
|
"identifier": "obsidian-mcp-server",
|
|
15
15
|
"runtimeHint": "node",
|
|
16
|
-
"version": "3.1.
|
|
16
|
+
"version": "3.1.6",
|
|
17
17
|
"packageArguments": [
|
|
18
18
|
{
|
|
19
19
|
"type": "positional",
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
96
96
|
"identifier": "obsidian-mcp-server",
|
|
97
97
|
"runtimeHint": "node",
|
|
98
|
-
"version": "3.1.
|
|
98
|
+
"version": "3.1.6",
|
|
99
99
|
"packageArguments": [
|
|
100
100
|
{
|
|
101
101
|
"type": "positional",
|