Skip to content

Commit 984b948

Browse files
authored
Merge branch 'main' into feat/serve-raw-markdown
2 parents 4f45aae + 5d0fd42 commit 984b948

25 files changed

Lines changed: 279 additions & 90 deletions

File tree

src/content/build/ai-agents/connect-mcp-to-your-editor.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ Permissions match those for the [`/sql`](/docs/reference/rest-api/http-protocol#
206206
| --- | --- |
207207
| Red / disconnected in MCP settings | Is `surreal` on `PATH`? Try the full path in `command`. Run `surreal mcp --user root --pass secret --ns main --db main memory` manually for errors. |
208208
| Tools list empty | Restart the editor after editing MCP config. Confirm SurrealDB version is 3.1+. |
209+
| `403 Forbidden: Host header is not allowed` (HTTP) | The `/mcp` transport only accepts loopback hosts by default. Set `SURREAL_MCP_ALLOWED_HOSTS` to your FQDN (include `localhost` if you still need it), or `SURREAL_MCP_ALLOW_ALL_HOSTS=true` behind a trusted proxy. Requires SurrealDB 3.2.1+. See [MCP configuration](/docs/build/ai-agents/mcp#configuration). |
209210
| Query timeout | Default tool timeout is 60 seconds (`SURREAL_MCP_QUERY_TIMEOUT_SECS`). Large scans may need a narrower query. |
210211
| Result truncated | Output is capped (default 256 KiB). Paginate or aggregate in SurrealQL. See [MCP configuration](/docs/build/ai-agents/mcp#configuration). |
211212
| Permission errors on HTTP | User lacks rights for the operation. Sign in with appropriate credentials or adjust `DEFINE USER` / `PERMISSIONS`. |

src/content/build/ai-agents/mcp.mdx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ surreal start --user root --pass secret --bind 127.0.0.1:8000 memory
4040
# MCP endpoint: http://127.0.0.1:8000/mcp
4141
```
4242

43+
For a non-loopback hostname (a public FQDN, Kubernetes service name, or load-balancer host), the HTTP transport's DNS-rebinding guard rejects the request with `403 Forbidden: Host header is not allowed` unless you opt in. Set `SURREAL_MCP_ALLOWED_HOSTS` to your hostnames, or `SURREAL_MCP_ALLOW_ALL_HOSTS=true` behind a trusted proxy. See [Configuration](#configuration).
44+
4345
Run behind TLS in production. The `mcp-session-id` header acts like a bearer token for the lifetime of a session — anyone who holds it can replay tool calls as the bound subject until the session expires (idle timeout defaults to five minutes).
4446

4547
### Stdio (`surreal mcp`)
@@ -81,6 +83,10 @@ MCP-specific limits are read once from the environment (prefix `SURREAL_MCP_`).
8183
| `SURREAL_MCP_MAX_RESULT_BYTES` | 256 KiB | Cap on serialised tool output (`0` disables) |
8284
| `SURREAL_MCP_RUN_MAX_ARGS` | 64 | Maximum arguments to `run` |
8385
| `SURREAL_MCP_PARAMS_MAX_KEYS` | 256 | Maximum top-level keys in parameter objects |
86+
| `SURREAL_MCP_PARAMS_MAX_QL_BYTES` | 4 KiB | Maximum byte length of a `$ql` string inside a `*_data` payload |
87+
| `SURREAL_MCP_SCHEMA_RESOURCE_MAX_TABLES` | 200 | Cap on tables enriched in the database schema resource |
88+
| `SURREAL_MCP_ALLOWED_HOSTS` <Since v="v3.2.1" /> | loopback only | Exact `Host` values accepted for HTTP `/mcp` (replaces the loopback default) |
89+
| `SURREAL_MCP_ALLOW_ALL_HOSTS` <Since v="v3.2.1" /> | `false` | Accept any `Host` (trusted proxy escape hatch; overrides the allowlist) |
8490
| `SURREAL_HTTP_MAX_MCP_BODY_SIZE` | 4 MiB | Maximum HTTP body size for `/mcp` |
8591

8692
Full tables live under [Environment variables](/docs/reference/cli/surrealdb-cli/environment-variables). [Observability metrics](/docs/manage/observability/metrics) include `surrealdb.mcp.*` counters and histograms from 3.1.0.
@@ -90,6 +96,7 @@ Full tables live under [Environment variables](/docs/reference/cli/surrealdb-cli
9096
- Prefer a least-privilege `DEFINE USER` (for example a custom role with table-level `PERMISSIONS`) instead of root credentials for agent clients.
9197
- Lock down capabilities (`--deny-funcs`, `--allow-net`, …) so a hijacked session cannot reach `http::*` or other high-risk functions.
9298
- Set `--allow-origin` explicitly for browser-based MCP clients; avoid `*` in production.
99+
- For HTTP `/mcp` on a public hostname, set `SURREAL_MCP_ALLOWED_HOSTS` (or `SURREAL_MCP_ALLOW_ALL_HOSTS` only behind a trusted proxy). The default allowlist is loopback-only.
93100
- Forward the `surrealdb::mcp::audit` tracing target to your SIEM — audit records include tool name, subject, namespace, database, and outcome, but never query text or row payloads.
94101

95102
## Next steps

src/content/build/deployment/self-hosted/azure-aks.mdx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -309,17 +309,17 @@ surrealdb-tikv LoadBalancer 10.0.38.191 20.13.45.154 80:30378/TCP 6m34
309309
4. Connect to the cluster and define the initial credentials:
310310

311311
```bash title="Connect and define credentials"
312-
$ export SURREALDB_URL=http://$(kubectl get service surrealdb-tikv -o json | jq -r .status.loadBalancer.ingress[0].ip)
313-
314-
$ surreal sql -e $SURREALDB_URL
315-
> DEFINE USER root ON ROOT PASSWORD 'StrongSecretPassword!' ROLES OWNER;
312+
export SURREALDB_URL=http://$(kubectl get service surrealdb-tikv -o json | jq -r .status.loadBalancer.ingress[0].ip)
313+
echo "DEFINE USER root ON ROOT PASSWORD 'StrongSecretPassword!' ROLES OWNER;" | surreal sql -e $SURREALDB_URL --pretty --hide-welcome
316314
```
317315

318316
5. Verify you can connect to the database with the new credentials:
319317

318+
```bash title="Connect as defined user"
319+
echo 'INFO FOR ROOT;' | surreal sql -u root -p 'StrongSecretPassword!' -e $SURREALDB_URL --pretty --hide-welcome
320+
```
321+
320322
```
321-
$ surreal sql -u root -p 'StrongSecretPassword!' -e $SURREALDB_URL
322-
> INFO FOR ROOT
323323
[{ accesses: { }, namespaces: { ns: 'DEFINE NAMESPACE ns' }, nodes: { "0e87c953-68d7-40e1-9090-3dfc404af25e": 'NODE 0e87c953-68d7-40e1-9090-3dfc404af25e SEEN 1742870304370 ACTIVE' }, system: { available_parallelism: 14, cpu_usage: 5.905298233032227f, load_average: [1.2802734375f, 1.5400390625f, 1.71484375f], memory_allocated: 13492047, memory_usage: 187547648, physical_cores: 14, threads: 32 }, users: { root: "DEFINE USER root ON ROOT PASSHASH '...' ROLES OWNER DURATION FOR TOKEN 1h, FOR SESSION NONE" } }]
324324
```
325325

src/content/build/deployment/self-hosted/google-gke.mdx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -219,16 +219,17 @@ surrealdb-tikv <none> * 34.160.82.177 80 5m
219219
4. Connect to the cluster and define the initial credentials:
220220

221221
```bash title="Connect then define user"
222-
$ export SURREALDB_URL=http://$(kubectl get ingress surrealdb-tikv -o json | jq -r .status.loadBalancer.ingress[0].ip)
223-
$ surreal sql -e $SURREALDB_URL
224-
> DEFINE USER root ON ROOT PASSWORD 'StrongSecretPassword!' ROLES OWNER;
222+
export SURREALDB_URL=http://$(kubectl get ingress surrealdb-tikv -o json | jq -r .status.loadBalancer.ingress[0].ip)
223+
echo "DEFINE USER root ON ROOT PASSWORD 'StrongSecretPassword!' ROLES OWNER;" | surreal sql -e $SURREALDB_URL --pretty --hide-welcome
225224
```
226225

227226
5. Verify you can connect to the database with the new credentials:
228227

229228
```bash title="Connect as defined user"
230-
$ surreal sql -u root -p 'StrongSecretPassword!' -e $SURREALDB_URL
231-
> INFO FOR ROOT
229+
echo 'INFO FOR ROOT;' | surreal sql -u root -p 'StrongSecretPassword!' -e $SURREALDB_URL --pretty --hide-welcome
230+
```
231+
232+
```
232233
[{ accesses: { }, namespaces: { }, nodes: { "0e87c953-68d7-40e1-9090-3dfc404af25e": 'NODE 0e87c953-68d7-40e1-9090-3dfc404af25e SEEN 1742869518357 ACTIVE' }, system: { available_parallelism: 14, cpu_usage: 4.321133613586426f, load_average: [2.2265625f, 2.2138671875f, 2.044921875f], memory_allocated: 13428527, memory_usage: 154812416, physical_cores: 14, threads: 32 }, users: { root: "DEFINE USER root ON ROOT PASSHASH '...' ROLES OWNER DURATION FOR TOKEN 1h, FOR SESSION NONE" } }]
233234
```
234235

src/content/build/deployment/surrealdb-cloud/billing-and-support/faqs.mdx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ Yes. You can move your current application built in SurrealDB to SurrealDB Cloud
3636

3737
We are working on a migration tool to help you move your existing on-premises instance to SurrealDB Cloud. In the meantime, you can use the `import` and `export` commands to move data between your on-premises instance and SurrealDB Cloud.
3838

39-
### When will SurrealDB Cloud leave beta?
40-
41-
SurrealDB Cloud is currently in beta as we continue to improve the platform and add new features.
42-
4339
### What programming languages are supported?
4440

4541
SurrealDB Cloud supports the following programming languages:
@@ -91,7 +87,7 @@ Visit our [Trust Centre](https://trust.surrealdb.com/) for more details.
9187

9288
Additionally, SurrealDB Cloud is built on top of SurrealDB, which provides powerful and flexible [security features](/docs/learn/security/authentication/summary#product) that are available to all SurrealDB Cloud customers. SurrealDB is developed and maintained following modern [security practices](/docs/learn/security/authentication/summary#process) to ensure early detection of security vulnerabilities and other security issues.
9389

94-
We are happy to discuss the security of SurrealDB Cloud with customers assessing usage of the service for their workloads during the beta phase. Please [Contact Us.](/contact)
90+
We are happy to discuss the security of SurrealDB Cloud with customers assessing usage of the service for their workloads. Please [Contact Us.](/contact)
9591

9692
### How can I report a security issue in SurrealDB Cloud?
9793

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
---
2+
position: 6
3+
title: Migrating from Snowflake
4+
description: "How to map existing data and concepts from Snowflake to SurrealDB"
5+
---
6+
7+
# Migrating from Snowflake to SurrealDB
8+
9+
This page shows how Snowflake data types map to their SurrealQL equivalents, then explains how to load Snowflake tables into SurrealDB with the [Surreal Sync](https://github.com/surrealdb/surreal-sync/) tool.
10+
11+
## Data types
12+
13+
The following chart shows Snowflake data types along with the equivalent or near-equivalent [SurrealQL data type](/docs/reference/query-language/datamodel) for each. Surreal Sync reads values through the Snowflake SQL REST API, which returns every cell as a string together with the column's logical type, and converts each one using that type.
14+
15+
| Snowflake Data Type | SurrealDB Mapping | Notes |
16+
| ------------------- | ----------------- | ----- |
17+
| **BOOLEAN** | `bool` | |
18+
| **NUMBER / INT / INTEGER / BIGINT** | `int` | Whole numbers (scale 0) that fit a 64-bit integer |
19+
| **NUMBER(p,s) / DECIMAL / NUMERIC** | `number` | Values with a scale, or larger than a 64-bit integer, keep their precision and scale as a decimal |
20+
| **FLOAT / REAL / DOUBLE** | `float` (f64) | Double-precision floating point |
21+
| **VARCHAR / STRING / TEXT / CHAR** | `string` | |
22+
| **DATE** | `datetime` | Stored as days since the Unix epoch, converted to a datetime at midnight UTC |
23+
| **TIME** | `datetime` | Seconds since midnight |
24+
| **TIMESTAMP_NTZ / DATETIME** | `datetime` | No timezone; taken as the given wall-clock instant |
25+
| **TIMESTAMP_LTZ / TIMESTAMP_TZ / TIMESTAMP** | `datetime` | Timezone-aware; the absolute instant is preserved as UTC |
26+
| **VARIANT / OBJECT** | `object` | Parsed from the stored JSON document |
27+
| **ARRAY** | `array` | Parsed from the stored JSON array |
28+
| **BINARY / VARBINARY** | `bytes` | Hex-decoded to raw bytes |
29+
30+
Any column whose logical type is not listed above is preserved as a `string` rather than failing the import.
31+
32+
## Importing from Snowflake using Surreal Sync
33+
34+
Surreal Sync can read tables from a Snowflake database and write them to SurrealDB.
35+
36+
> [!NOTE]
37+
> The Snowflake source is ingestion-only. It performs a single full snapshot of the selected tables and does not support incremental synchronisation or change data capture. There is no durable cursor, so an interrupted run cannot be resumed part-way; re-run the command to start again.
38+
39+
Rows are read one Snowflake result partition at a time and written in batches, so a large table does not need to fit in memory.
40+
41+
### Prerequisites
42+
43+
Surreal Sync connects to Snowflake through the [SQL REST API](https://docs.snowflake.com/en/developer-guide/sql-api/index) using key-pair (JWT) authentication. Before running an import:
44+
45+
1. Generate an unencrypted PKCS#8 RSA key pair. Encrypted private keys are not supported yet.
46+
2. Register the public key on the Snowflake user that Surreal Sync will authenticate as:
47+
48+
```sql
49+
ALTER USER my_user SET RSA_PUBLIC_KEY='MIIBIjANBgkq...';
50+
```
51+
52+
3. Make sure that user has a role able to read the target database and schema, and a virtual warehouse to run the queries.
53+
54+
Keep the private key file accessible to Surreal Sync and pass its path with `--private-key-path`.
55+
56+
### Usage
57+
58+
```bash
59+
surreal-sync from snowflake \
60+
--account myorg-myaccount \
61+
--user my_user \
62+
--private-key-path ./rsa_key.p8 \
63+
--warehouse COMPUTE_WH \
64+
--database MY_DB \
65+
--schema PUBLIC \
66+
--to-namespace my_namespace \
67+
--to-database my_database \
68+
--surreal-endpoint ws://localhost:8000 \
69+
--surreal-username root \
70+
--surreal-password root
71+
```
72+
73+
When `--tables` is omitted, every base table in the schema is imported (views and temporary tables are skipped). Each table becomes a table of the same name in SurrealDB, and each row becomes a record. Snowflake upper-cases unquoted identifiers, so table and column names arrive upper-cased.
74+
75+
Most connection options also read from an environment variable, which is useful for keeping credentials out of shell history.
76+
77+
### Options
78+
79+
| Option | Environment variable | Required | Description |
80+
| ------ | -------------------- | -------- | ----------- |
81+
| `--account` | `SNOWFLAKE_ACCOUNT` | Yes | Account identifier as used in the host `<account>.snowflakecomputing.com`, for example `myorg-myaccount` or `xy12345.us-east-1`. |
82+
| `--user` | `SNOWFLAKE_USER` | Yes | User whose key pair is registered for JWT authentication. |
83+
| `--private-key-path` | `SNOWFLAKE_PRIVATE_KEY_PATH` | Yes | Path to the unencrypted PKCS#8 private key PEM file. |
84+
| `--private-key-passphrase` | `SNOWFLAKE_PRIVATE_KEY_PASSPHRASE` | No | Passphrase for an encrypted key. Not supported yet; setting it returns an error. |
85+
| `--warehouse` | `SNOWFLAKE_WAREHOUSE` | Yes | Virtual warehouse used to run the queries. |
86+
| `--database` | `SNOWFLAKE_DATABASE` | Yes | Database to read from. |
87+
| `--schema` | `SNOWFLAKE_SCHEMA` | No | Schema within the database. Defaults to `PUBLIC`. |
88+
| `--role` | `SNOWFLAKE_ROLE` | No | Role to assume for the session. |
89+
| `--tables` || No | Comma-separated list of tables to import. When omitted, all base tables in the schema are imported. |
90+
| `--id-columns` || No | Comma-separated columns forming the SurrealDB record ID. See [Record IDs](#record-ids). |
91+
| `--transforms-config` || No | Path to a TOML file describing a transform pipeline. Omit to import rows unchanged. |
92+
| `--to-namespace` || Yes | Target SurrealDB namespace. |
93+
| `--to-database` || Yes | Target SurrealDB database. |
94+
95+
The `--surreal-endpoint`, `--surreal-username`, `--surreal-password`, `--batch-size`, and `--dry-run` options are shared with the other Surreal Sync sources. Use `--dry-run` to read and convert rows without writing to SurrealDB.
96+
97+
### Record IDs
98+
99+
Snowflake primary keys are optional and often absent, so the record ID for each row depends on `--id-columns`:
100+
101+
- **Omitted:** a sequential per-table integer is generated. It is deterministic within a run but not stable across re-runs, so prefer explicit ID columns when you need stable IDs.
102+
- **A single column:** the value becomes the record ID, as an integer when it parses as one and otherwise as a string.
103+
- **Several columns:** the values are joined with `:` into a string ID.
104+
105+
When ID columns are given, they are used only for the record ID and are not repeated as fields on the record. Column names are matched case-insensitively.

src/content/build/migrating/from-other-databases/overview.mdx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ All of the sources in this section of the documentation can be automatically imp
1212

1313
To migrate from other databases not yet supported, consider beginning by exporting the database as JSON which can be [imported on the command line](/docs/reference/cli/surrealdb-cli/commands/import). Alternatively, you can use [one of the many available SDKs](/docs/start) to access your existing database and transfer its content directly to a SurrealDB instance.
1414

15-
* [MongoDB](/docs/build/migrating/mongodb)
16-
* [Neo4j](/docs/build/migrating/neo4j)
17-
* [PostgreSQL](/docs/build/migrating/postgresql)
15+
* [MongoDB](/docs/build/migrating/from-other-databases/from-mongodb)
16+
* [MySQL](/docs/build/migrating/from-other-databases/from-mysql)
17+
* [Neo4j](/docs/build/migrating/from-other-databases/from-neo4j)
18+
* [PostgreSQL](/docs/build/migrating/from-other-databases/from-postgresql)
19+
* [Snowflake](/docs/build/migrating/from-other-databases/from-snowflake)

src/content/explore/tutorials/tutorials/connect-via-ngrok.mdx

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -50,34 +50,28 @@ Note the forwarding address provided by ngrok. For example, **`25f6-2402-e280-21
5050
> [!IMPORTANT]
5151
> Keep this address handy as we will use it in the next step.
5252
53-
### Connect to SurrealDB via the ngrok address
54-
55-
Now, let's [connect to your SurrealDB instance](/docs/reference/cli/surrealdb-cli/commands/sql) using the forwarding address provided by Ngrok.
56-
57-
Run the following command in a new terminal window/tab, replacing **`[ngrok-address]`** with the actual ngrok forwarding address you noted earlier:
53+
### Connect and verify
5854

55+
Connect using the forwarding address from ngrok, replacing **`[ngrok-address]`** with the address you noted earlier. You can open an interactive REPL:
56+
5957
```bash
6058
surreal sql --conn wss://[ngrok-address] --user root --pass secret --ns main --db main --pretty
6159
```
62-
63-
### Verify the connection
64-
65-
Finally, let’s ensure the connection is properly set up by running a test query.
66-
With the help of the `CREATE` statement, [create a new record](/docs/reference/query-language/statements/create).
67-
68-
```surql
69-
CREATE registration SET
70-
full_name = 'John Doe',
71-
email = 'johndoe@gmail.com',
72-
address_line1 = 'Room number 1, Hogwarts',
73-
address_line2 = 'Near Diagon Alley',
74-
city = 'Hogwarts',
75-
country = 'England';
60+
61+
Or run a one-shot check that [creates a record](/docs/reference/query-language/statements/create) and [selects it](/docs/reference/query-language/statements/select):
62+
63+
<Tabs synckey="sql-pipe">
64+
<TabItem label="Bash">
65+
```bash
66+
echo "CREATE registration SET full_name = 'John Doe', email = 'johndoe@gmail.com', address_line1 = 'Room number 1, Hogwarts', address_line2 = 'Near Diagon Alley', city = 'Hogwarts', country = 'England'; SELECT * FROM registration;" | surreal sql --conn wss://[ngrok-address] --user root --pass secret --ns main --db main --pretty --hide-welcome
67+
```
68+
</TabItem>
69+
<TabItem label="PowerShell">
70+
```powershell
71+
"CREATE registration SET full_name = 'John Doe', email = 'johndoe@gmail.com', address_line1 = 'Room number 1, Hogwarts', address_line2 = 'Near Diagon Alley', city = 'Hogwarts', country = 'England'; SELECT * FROM registration;" | surreal sql --conn wss://[ngrok-address] --user root --pass secret --ns main --db main --pretty --hide-welcome
7672
```
77-
And let's [query the data](/docs/reference/query-language/statements/select) from the record now.
78-
```surql
79-
SELECT * FROM registration
80-
```
73+
</TabItem>
74+
</Tabs>
8175

8276
## Conclusion
8377

src/content/index/concepts.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ An example of output for the `INFO FOR DATABASE` statement is as follows.
8888
SCHEMAFULL PERMISSIONS NONE'
8989
},
9090
users: {
91-
Boris: "DEFINE USER Boris ON DATABASE PASSHASH '$argon2id$v=19$m=19456,t=2,p=1$1ZMzsVGNRxAaZAhTZ3Kn0g$sO23Ukw1OVNCQb2T72wNnb5bS6lqhLllmfNzcqwH9i4' ROLES VIEWER DURATION FOR TOKEN 1h, FOR SESSION NONE",
92-
Drusilla: "DEFINE USER Drusilla ON DATABASE PASSHASH '$argon2id$v=19$m=19456,t=2,p=1$AFRMmk2Ny+ZoDdG9U7nOPQ$vsSr2TfQ9K5OUhTjygkWu/Y+8WX/Dns9wfK0rdQ8cnc' ROLES VIEWER DURATION FOR TOKEN 1h, FOR SESSION NONE"
91+
Boris: "DEFINE USER Boris ON DATABASE PASSHASH '[REDACTED]' ROLES VIEWER DURATION FOR TOKEN 1h, FOR SESSION NONE",
92+
Drusilla: "DEFINE USER Drusilla ON DATABASE PASSHASH '[REDACTED]' ROLES VIEWER DURATION FOR TOKEN 1h, FOR SESSION NONE"
9393
}
9494
}
9595
```

0 commit comments

Comments
 (0)