New release v2.3.8

This commit is contained in:
2026-03-05 13:17:53 +01:00
parent 305abfa85d
commit 3f9b30bfa1
10 changed files with 393 additions and 28 deletions

View File

@@ -105,13 +105,28 @@ class AnytypeMCPService {
],
required: ["space_id", "name"]
),
makeTool(
name: "anytype_append_to_object",
description: """
Append new markdown content to the end of an existing Anytype object without touching the existing body. \
This is the PREFERRED way to add content to existing notes, pages, or tasks — \
it preserves all Anytype internal links (anytype://...) and mention blocks exactly. \
Use this instead of anytype_update_object whenever you are adding information rather than rewriting.
""",
properties: [
"space_id": prop("string", "The ID of the space containing the object"),
"object_id": prop("string", "The ID of the object to append to"),
"content": prop("string", "Markdown content to append at the end of the object body")
],
required: ["space_id", "object_id", "content"]
),
makeTool(
name: "anytype_update_object",
description: """
Replace the full markdown body or rename an Anytype object. \
IMPORTANT: For toggling a checkbox (to-do item), use anytype_toggle_checkbox instead — \
it is safer and does not risk modifying other content. \
Use anytype_update_object ONLY for large content changes (adding paragraphs, rewriting sections, etc.). \
WARNING: This replaces the ENTIRE body — prefer anytype_append_to_object for adding content \
to existing objects, as full replacement degrades rich Anytype internal links (anytype://...) to plain text. \
Use this ONLY when you truly need to rewrite or restructure existing content. \
CRITICAL RULES when using this tool: \
1) Always call anytype_get_object first to get the current EXACT markdown. \
2) Make ONLY the minimal requested change — nothing else. \
@@ -214,6 +229,14 @@ class AnytypeMCPService {
let type_ = args["type"] as? String ?? "note"
return try await createObject(spaceId: spaceId, name: name, body: body, type: type_)
case "anytype_append_to_object":
guard let spaceId = args["space_id"] as? String,
let objectId = args["object_id"] as? String,
let content = args["content"] as? String else {
return ["error": "Missing required parameters: space_id, object_id, content"]
}
return try await appendToObject(spaceId: spaceId, objectId: objectId, content: content)
case "anytype_update_object":
guard let spaceId = args["space_id"] as? String,
let objectId = args["object_id"] as? String else {
@@ -351,6 +374,29 @@ class AnytypeMCPService {
return ["success": true, "message": "Object created"]
}
private func appendToObject(spaceId: String, objectId: String, content: String) async throws -> [String: Any] {
// Fetch current body
let result = try await request(endpoint: "/v1/spaces/\(spaceId)/objects/\(objectId)", method: "GET", body: nil)
guard let object = result["object"] as? [String: Any] else {
return ["error": "Object not found"]
}
let existing: String
if let md = object["markdown"] as? String { existing = md }
else if let body = object["body"] as? String { existing = body }
else { existing = "" }
let separator = existing.isEmpty ? "" : "\n\n"
let newMarkdown = existing + separator + content
_ = try await request(
endpoint: "/v1/spaces/\(spaceId)/objects/\(objectId)",
method: "PATCH",
body: ["markdown": newMarkdown]
)
return ["success": true, "message": "Content appended successfully"]
}
private func updateObject(spaceId: String, objectId: String, name: String?, body: String?) async throws -> [String: Any] {
var requestBody: [String: Any] = [:]
if let name = name { requestBody["name"] = name }

View File

@@ -430,6 +430,31 @@ class SettingsService {
}
}
// MARK: - Favorite Models
var favoriteModelIds: Set<String> {
get {
guard let json = cache["favoriteModelIds"],
let data = json.data(using: .utf8),
let ids = try? JSONDecoder().decode([String].self, from: data) else { return [] }
return Set(ids)
}
set {
let sorted = newValue.sorted()
if let data = try? JSONEncoder().encode(sorted),
let json = String(data: data, encoding: .utf8) {
cache["favoriteModelIds"] = json
DatabaseService.shared.setSetting(key: "favoriteModelIds", value: json)
}
}
}
func toggleFavoriteModel(_ id: String) {
var favs = favoriteModelIds
if favs.contains(id) { favs.remove(id) } else { favs.insert(id) }
favoriteModelIds = favs
}
// MARK: - Anytype MCP Settings
var anytypeMcpEnabled: Bool {