diff --git a/.cursor/mcp.json b/.cursor/mcp.json deleted file mode 100644 index 59efc243e2..0000000000 --- a/.cursor/mcp.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "mcpServers": { - "fluree-memory": { - "type": "stdio", - "command": "fluree", - "args": [ - "mcp", - "serve", - "--transport", - "stdio" - ], - "env": { - "FLUREE_HOME": "${workspaceFolder}/.fluree" - } - } - } -} \ No newline at end of file diff --git a/.cursor/rules/fluree_rules.md b/.cursor/rules/fluree_rules.md deleted file mode 100644 index 638979b048..0000000000 --- a/.cursor/rules/fluree_rules.md +++ /dev/null @@ -1,48 +0,0 @@ -# Fluree Developer Memory — Agent Rules - -You have access to a persistent project memory system via MCP tools. Use it to maintain context across sessions. - -## When to Recall - -Call `memory_recall` at the start of each task with a query describing what you're about to do. This surfaces relevant facts, decisions, and constraints from previous sessions. - -Examples: -- Starting a new feature: `memory_recall("building ")` -- Debugging: `memory_recall("error in ")` -- Refactoring: `memory_recall("architecture of ")` - -## When to Store - -Call `memory_add` when you discover or decide something worth remembering: - -| Kind | When to use | Example | -|------|------------|---------| -| `fact` | You learn how something works | "The index format uses postcard encoding with delta compression" | -| `decision` | A design choice is made (with rationale) | "Chose keyword matching over embeddings for Phase 1 to avoid cloud dependency" | -| `constraint` | A rule that must always be followed | "Never suppress dead code warnings with underscore prefix" | - -Use `rationale` on any kind to explain *why* something is true, was decided, or must be followed. - -## Tag Conventions - -**Tags are required.** Every memory must include at least one tag. Tags are the primary recall signal — memories without tags are hard to surface later. - -Use consistent, lowercase tags. Common tags: -- Module names: `indexer`, `query`, `transact`, `api`, `cli`, `memory` -- Topics: `testing`, `errors`, `performance`, `storage`, `schema` -- Actions: `debugging`, `refactoring`, `migration` - -## When to Update - -Call `memory_update` when a previously stored fact or decision changes. Only provide the fields you want to change — the memory keeps its ID. History is tracked via git. - -## When to Forget - -Call `memory_forget` only when a memory is clearly incorrect or permanently obsolete. Prefer `memory_update` for evolving information. - -## Severity for Constraints - -When storing constraints, set severity: -- `must` — Violation is a bug. Example: "Must use thiserror, not anyhow" -- `should` — Strong preference. Example: "Should keep functions under 50 lines" -- `prefer` — Soft preference. Example: "Prefer impl Trait over Box" diff --git a/.gitignore b/.gitignore index c4426893e9..29c90405b4 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,6 @@ __pycache__/ # Internal analysis scratch — not part of the published docs BI_QUERY_ANALYSIS.md SEPARATION_PLAN.md + +# Cursor editor config — local only +/.cursor/ diff --git a/docs/README.md b/docs/README.md index 53e90c9b3f..00752ac342 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,11 +2,11 @@ A semantic graph database with time travel, branching, and verifiable data — built on W3C standards. -Fluree DB is a single binary that stores your data as an RDF knowledge graph, queryable with SPARQL or JSON-LD Query, with every commit immutably recorded so you can travel back to any prior state. It supports git-style branching and merging, signed and policy-gated transactions, SHACL validation, OWL/RDFS reasoning, and full-text and vector search — over local files, S3, or IPFS — without bolting on external services. +Fluree DB is a single binary that stores your data as an RDF knowledge graph, queryable with SPARQL, JSON-LD Query, or Cypher, with every commit immutably recorded so you can travel back to any prior state. It supports git-style branching and merging, signed and policy-gated transactions, SHACL validation, OWL/RDFS reasoning, and full-text and vector search — over local files, S3, or IPFS — without bolting on external services. ## What you get -- **Semantic by default.** Your data is RDF. IRIs, JSON-LD `@context`, named graphs, and typed values are first-class. Queries are SPARQL 1.1 or the equivalent JSON-LD Query, both compiling to the same execution engine. +- **Semantic by default.** Your data is RDF. IRIs, JSON-LD `@context`, named graphs, and typed values are first-class. Queries are SPARQL 1.1, the equivalent JSON-LD Query, or openCypher — all compiling to the same execution engine. - **Property graphs and statement-level metadata.** Attach properties to a *relationship*, not just a node — `role` and `since` on a `worksFor` edge, `source` and `confidence` on a claim — with RDF 1.2 / SPARQL 1.2 edge annotations. Labeled-property-graph edges, parallel relationships between the same two nodes, and RDF-star provenance all live on one surface, and plain triple queries are left undisturbed. See [Edge annotations](concepts/edge-annotations.md). - **Time travel.** Every transaction is a commit on an immutable chain. Query the state of the graph at any past moment with a single `t` parameter — no snapshots to restore, no separate audit log to consult. - **Branching and merging.** Create a branch off any commit, transact against it in isolation, then merge it back. Useful for staging changes, running what-if analyses, or maintaining environment-specific overlays. @@ -22,7 +22,7 @@ Fluree DB is a single binary that stores your data as an RDF knowledge graph, qu - **New to Fluree?** → [Getting started](getting-started/) - **Run the server** → [Quickstart: run the server](getting-started/quickstart-server.md) - **Create a ledger and write data** → [Quickstart: create a ledger](getting-started/quickstart-ledger.md) → [Quickstart: write data](getting-started/quickstart-write.md) -- **Query data** → [Quickstart: query (JSON-LD + SPARQL)](getting-started/quickstart-query.md) +- **Query data** → [Quickstart: query (JSON-LD, SPARQL, Cypher)](getting-started/quickstart-query.md) - **End-to-end walkthrough** → [Tutorial: search, time travel, branching, policies](getting-started/tutorial-end-to-end.md) - **Coming from SQL?** → [Fluree for SQL developers](getting-started/fluree-for-sql-developers.md) - **Embedding in Rust?** → [Using Fluree as a Rust library](getting-started/rust-api.md) @@ -33,7 +33,7 @@ Fluree DB is a single binary that stores your data as an RDF knowledge graph, qu - [Guides (cookbooks)](guides/) — query patterns, search, time travel, branching, policies, SHACL, edge annotations — task-oriented recipes - [CLI reference](cli/) — every `fluree` command, flag by flag - [HTTP API](api/) — endpoints, headers, signed requests, error model -- [Query](query/) — JSON-LD Query, SPARQL, output formats, CONSTRUCT, explain plans, reasoning +- [Query](query/) — JSON-LD Query, SPARQL, Cypher, output formats, CONSTRUCT, explain plans, reasoning - [Transactions](transactions/) — insert, upsert, update, conditional updates, signed transactions - [Security and policy](security/) — authentication, encryption, commit signing, policy model - [Indexing and search](indexing-and-search/) — background indexing, BM25, vector search, geospatial diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index cf1073e6c4..8f77d8b3e9 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -103,7 +103,7 @@ - [Query](query/README.md) - [JSON-LD Query](query/jsonld-query.md) - [SPARQL](query/sparql.md) - - [Cypher (openCypher subset)](query/cypher.md) + - [Cypher (openCypher)](query/cypher.md) - [Output formats (JSON-LD / SPARQL JSON / typed JSON / Agent JSON)](query/output-formats.md) - [Datasets, FROM/FROM NAMED, and multi-graph execution](query/datasets.md) - [CONSTRUCT](query/construct.md) diff --git a/docs/api/endpoints.md b/docs/api/endpoints.md index 4c65608ba5..d967744306 100644 --- a/docs/api/endpoints.md +++ b/docs/api/endpoints.md @@ -45,7 +45,7 @@ This endpoint is intended for debugging and operator support. See also [Admin, h ### POST /update -Submit an **update** transaction (WHERE/DELETE/INSERT JSON-LD or SPARQL UPDATE) to write data to a ledger. +Submit an **update** transaction (WHERE/DELETE/INSERT JSON-LD, SPARQL UPDATE, or Cypher `CREATE`/`MERGE`/`SET`/`DELETE`) to write data to a ledger. **URL:** ``` @@ -71,6 +71,17 @@ Content-Type: application/sparql-update Accept: application/json ``` +For Cypher writes (`CREATE`/`MERGE`/`SET`/`DELETE`): +```http +Content-Type: application/cypher +Accept: application/json +``` + +Note: Cypher targets a ledger directly and must use the path form +(`POST /update/{ledger-id}`); it has no `FROM`/dataset clause. The body may be +raw Cypher or the JSON envelope `{"cypher": "...", "params": {...}}`. See the +[Cypher reference](../query/cypher.md) for details. + Note: Turtle/TriG are not accepted on `/update`. Use `/insert` (Turtle) or `/upsert` (Turtle/TriG). **Request Body (JSON-LD):** @@ -1207,6 +1218,16 @@ FROM WHERE { ?commit f:t ?t }' ``` +Cypher (`Content-Type: application/cypher` — ledger-scoped only, no `FROM`/dataset clause): + +```bash +curl -X POST "http://localhost:8090/v1/fluree/query/mydb:main" \ + -H "Content-Type: application/cypher" \ + --data 'MATCH (p:Person) RETURN p.name' +``` + +Cypher responses default to `cypher-json`; request RDF JSON-LD with `Accept: application/ld+json`. The body may be raw Cypher or the JSON envelope `{"cypher": "...", "params": {...}}`. See the [Cypher reference](../query/cypher.md). + ### History Queries via POST /query Query the history of entities using the standard `/query` endpoint with `from` and `to` keys specifying the time range. @@ -2805,7 +2826,7 @@ This section summarizes the contract that third-party server implementations (e. |----------|-------------| | `GET /info/{ledger}` | `info`, `push`, `pull`, `clone` | | `GET /show/{ledger}?commit=` | `show --remote` | -| `POST /query/{ledger}` | `query` (JSON-LD and SPARQL) | +| `POST /query/{ledger}` | `query` (JSON-LD, SPARQL, and Cypher) | | `POST /insert/{ledger}` | `insert` | | `POST /upsert/{ledger}` | `upsert` | | `GET /exists/{ledger}` | `clone` (pre-create check) | diff --git a/docs/api/overview.md b/docs/api/overview.md index d99abfd6ff..821d0b472b 100644 --- a/docs/api/overview.md +++ b/docs/api/overview.md @@ -82,7 +82,7 @@ defaults to `/v1/fluree`. ### Transaction Endpoints **POST /update** -- Submit update transactions (WHERE/DELETE/INSERT JSON-LD or SPARQL UPDATE) +- Submit update transactions (WHERE/DELETE/INSERT JSON-LD, SPARQL UPDATE, or Cypher `CREATE`/`MERGE`/`SET`/`DELETE`) - Parameters: `ledger`, `context` - Returns: Transaction receipt with commit info @@ -92,7 +92,7 @@ defaults to `/v1/fluree`. ### Query Endpoints **POST /query** -- Execute queries (JSON-LD Query or SPARQL) +- Execute queries (JSON-LD Query, SPARQL, or Cypher — Cypher on the ledger-scoped `/query/{ledger}` route with `Content-Type: application/cypher`) - Parameters: None (ledger specified in query body) - Returns: Query results - Supports history queries via time range in `from` clause (see [Time Travel](../concepts/time-travel.md)) diff --git a/docs/cli/README.md b/docs/cli/README.md index 4f6b7adb36..35dc62629f 100644 --- a/docs/cli/README.md +++ b/docs/cli/README.md @@ -148,7 +148,9 @@ Input is resolved in this priority order: `-e` flag > positional inline > `-f` f The CLI auto-detects data format based on content: - Lines starting with `@prefix` or `@base` → Turtle - Content starting with `{` or `[` → JSON-LD +- Leading `MATCH`/`MERGE`/`CREATE (`/`DETACH`, or a `.cypher`/`.cyp`/`.cql` file → Cypher +- SPARQL query/update keywords (`SELECT`/`INSERT`/`DELETE`/`PREFIX`) → SPARQL - Files with `.ttl` extension → Turtle - Files with `.json` or `.jsonld` extension → JSON-LD -You can override with `--format turtle` or `--format jsonld`. +You can override with `--format turtle`, `--format jsonld`, `--format sparql`, or `--format cypher` (see the per-command docs for the exact set each accepts). diff --git a/docs/cli/query.md b/docs/cli/query.md index 2e360036d0..5d86b13adf 100644 --- a/docs/cli/query.md +++ b/docs/cli/query.md @@ -26,10 +26,11 @@ the positional auto-detection (e.g. `fluree query --ledger mydb:main 'SELECT … | `-l, --ledger ` | Ledger name (defaults to active ledger); explicit alternative to the positional ledger argument | | `-e, --expr ` | Inline query expression (alternative to positional) | | `-f, --file ` | Read query from a file | -| `--format ` | Output format: `json`, `typed-json`, `table`, `csv`, `tsv`, or `ndjson` (default: `table`) | +| `--format ` | Output format: `json`, `jsonld`, `typed-json`, `cypher-json`, `table`, `csv`, `tsv`, or `ndjson` (default: `table`; Cypher defaults to `cypher-json`) | | `--envelope` | With `--format ndjson`, emit the full streaming record protocol verbatim instead of bare binding objects | | `--sparql` | Force SPARQL query format | | `--jsonld` | Force JSON-LD query format | +| `--cypher` | Force openCypher query format (local ledgers only) | | `--at