feat(phase5): MCP server, CalDAV, mail-to-task, Gmail settings and an AI layer
The MCP server speaks JSON-RPC over Streamable HTTP with the six tools the brief names, authenticated by a personal API token — so a connector reaches exactly what its owner reaches and there is no second identity to reason about. A failed tool call returns a tool error, not a protocol error: a model can recover from the first and can do nothing with the second. CalDAV serves VTODO, two-way, so Apple Reminders and Thunderbird can read, create and complete tasks. Clients authenticate with Basic using an API token as the password, never the account password — a client stores what it is given, and what it is given should not be able to sign in to the app. Completed tasks stay in the collection: a client that stops seeing one treats it as deleted and drops its own record of having done it. The AI layer is one interface with adapters for Anthropic, OpenAI, Google and any OpenAI-compatible endpoint. That last one is why the abstraction exists: an integration that only spoke to a hosted API would be useless to somebody running their own models. Every feature degrades to "off" when nothing is configured, and the stored API key is never returned to the settings page. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
4058ff0533
commit
6b19ed062d
@@ -151,6 +151,12 @@ func bearerToken(r *http.Request) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// withUser puts a user on the context. Used by the CalDAV handlers, which
|
||||
// authenticate with Basic rather than through the session middleware.
|
||||
func withUser(ctx context.Context, user *store.User) context.Context {
|
||||
return context.WithValue(ctx, ctxUser, user)
|
||||
}
|
||||
|
||||
func userFrom(ctx context.Context) *store.User {
|
||||
u, _ := ctx.Value(ctxUser).(*store.User)
|
||||
return u
|
||||
|
||||
Reference in New Issue
Block a user