Documentation
¶
Index ¶
- Variables
- func Tier2GroupForTool(toolName string) (string, bool)
- func Tier2GroupNames() []string
- type ActivationResult
- type DateRange
- type DaySummary
- type DeactivationResult
- type EffectiveRate
- type EntryRateView
- type FindAndUpdateEntryData
- type IdentityData
- type LogTimeData
- type MoneyView
- type ProjectSummary
- type QuickReportData
- type RateScope
- type ResultEnvelope
- type Service
- func (s *Service) ActivateNamedTool(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ActivateToolGroup(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) AddEntry(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) AddUserToGroup(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ArchiveProjects(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) AssignProjectMemberships(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) AttendanceReport(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) CallDocumentedDeleteAPI(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) CallDocumentedReadAPI(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) CallDocumentedWriteAPI(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) CreateClient(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) CreateCustomField(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) CreateHoliday(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) CreateProject(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) CreateProjectFromTemplate(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) CreateProjectTemplate(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) CreateTag(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) CreateTask(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) CreateUserGroup(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) CreateUserGroupAdmin(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) CreateWebhook(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) CurrentUser(ctx context.Context) (ResultEnvelope, error)
- func (s *Service) DeactivateToolGroup(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) DeactivateUser(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) DeleteClient(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) DeleteCustomField(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) DeleteEntry(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) DeleteHoliday(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) DeleteProject(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) DeleteTag(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) DeleteTask(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) DeleteUserGroup(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) DeleteUserGroupAdmin(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) DeleteWebhook(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) DetailedReport(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) EmitProgress(ctx context.Context, progress, total float64, message string)
- func (s *Service) FindAndUpdateEntry(ctx context.Context, args map[string]any) (any, error)
- func (s *Service) GetClient(ctx context.Context, clientRef string) (ResultEnvelope, error)
- func (s *Service) GetCustomField(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) GetEntry(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) GetMemberProfile(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) GetProject(ctx context.Context, projectRef string) (ResultEnvelope, error)
- func (s *Service) GetProjectTemplate(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) GetTag(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) GetTask(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) GetUserGroup(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) GetWebhook(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) GetWorkspace(ctx context.Context) (ResultEnvelope, error)
- func (s *Service) ListClients(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ListCustomFields(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ListDocumentedAPIOperations(_ context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ListEntries(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ListHolidays(ctx context.Context) (ResultEnvelope, error)
- func (s *Service) ListProjectTemplates(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ListProjects(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ListResourceTemplates(_ context.Context) ([]mcp.ResourceTemplate, error)
- func (s *Service) ListResources(ctx context.Context) ([]mcp.Resource, error)
- func (s *Service) ListTags(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ListTasks(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ListTools(_ context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ListUserGroups(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ListUserGroupsAdmin(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ListUsers(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ListWebhookEvents(ctx context.Context, _ map[string]any) (ResultEnvelope, error)
- func (s *Service) ListWebhooks(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ListWorkspaces(ctx context.Context) (ResultEnvelope, error)
- func (s *Service) LogTime(ctx context.Context, args map[string]any) (any, error)
- func (s *Service) PolicyInfo(ctx context.Context) (ResultEnvelope, error)
- func (s *Service) QuickReport(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ReadResource(ctx context.Context, uri string) ([]mcp.ResourceContents, error)
- func (s *Service) Registry() []mcp.ToolDescriptor
- func (s *Service) RemoveUserFromGroup(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ResolveDebug(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ResolveName(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) ResolveWorkspaceID(ctx context.Context) (string, error)
- func (s *Service) SearchTools(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) SetCustomFieldValue(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) SetProjectMemberships(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) StartTimer(ctx context.Context, projectID, projectRef, description string) (ResultEnvelope, error)
- func (s *Service) StartTimerArgs(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) StopTimer(ctx context.Context, args map[string]any) (any, error)
- func (s *Service) SummaryReport(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) SwitchProject(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) TestWebhook(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) Tier2Handlers(groupName string) ([]mcp.ToolDescriptor, bool)
- func (s *Service) TimerStatus(ctx context.Context) (ResultEnvelope, error)
- func (s *Service) TimesheetFillGap(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) TimesheetReview(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) TodayEntries(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) UpdateClient(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) UpdateCustomField(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) UpdateEntry(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) UpdateMemberProfile(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) UpdateProject(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) UpdateProjectEstimate(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) UpdateProjectMemberships(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) UpdateProjectTemplate(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) UpdateProjectUserRate(ctx context.Context, args map[string]any, endpoint string) (ResultEnvelope, error)
- func (s *Service) UpdateTag(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) UpdateTask(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) UpdateTaskRate(ctx context.Context, args map[string]any, endpoint string) (ResultEnvelope, error)
- func (s *Service) UpdateUserGroup(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) UpdateUserGroupAdmin(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) UpdateUserRole(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) UpdateWebhook(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) WeeklySummary(ctx context.Context, args map[string]any) (ResultEnvelope, error)
- func (s *Service) WhoAmI(ctx context.Context) (ResultEnvelope, error)
- type SummaryData
- type SummaryTotals
- type Tier2Group
- type TimeEntryDraft
- type TimeEntryRef
- type TimeEntryUpdatePreview
- type TimesheetFillGapData
- type TimesheetIssue
- type TimesheetReviewData
- type ToolSuggestion
- type WeeklySummaryData
- type WorkspaceContext
Constants ¶
This section is empty.
Variables ¶
var Tier2Groups = map[string]Tier2Group{}
Tier2Groups is the global registry of Tier 2 tool groups.
Functions ¶
func Tier2GroupForTool ¶ added in v1.2.1
func Tier2GroupNames ¶ added in v1.2.1
func Tier2GroupNames() []string
Types ¶
type ActivationResult ¶
type ActivationResult struct {
Kind string `json:"kind"`
Name string `json:"name"`
Group string `json:"group,omitempty"`
// ToolCount is len(ActivatedTools); kept as a separate field for
// backwards compatibility with clients that read it directly.
ToolCount int `json:"toolCount"`
// ActivatedTools enumerates every tool name brought online by this
// activation. For Tier-2 tool-name activations, this is the full
// containing group — the LLM sees exactly what other capabilities
// it just gained alongside the requested one. Empty for Tier-1
// single-tool activation by design.
ActivatedTools []string `json:"activatedTools,omitempty"`
// TotalVisibleTools is the post-activation tools/list count after
// bootstrap and policy filtering. Zero means the activator could not
// compute the session total and activationPayload omits it.
TotalVisibleTools int `json:"totalVisibleTools,omitempty"`
// VisibleActivatedTools is ActivatedTools filtered through the same
// post-activation tools/list visibility gate. nil preserves legacy
// activation callbacks; non-nil means activationPayload should expose
// this filtered set as activated_tools.
VisibleActivatedTools []string `json:"visibleActivatedTools,omitempty"`
// ActivatedToolsHiddenByBootstrap names activated tools that remained
// hidden because the active bootstrap config did not expose them.
ActivatedToolsHiddenByBootstrap []string `json:"activatedToolsHiddenByBootstrap,omitempty"`
// ActivatedToolsBlockedByPolicy names activated tools that remained
// hidden because policy enforcement filtered them from tools/list.
ActivatedToolsBlockedByPolicy []string `json:"activatedToolsBlockedByPolicy,omitempty"`
}
ActivationResult is the payload returned by a Service activator (ActivateGroup / ActivateTool) describing which tools came online. The shape feeds activationPayload + activationMessage so the MCP response envelope carries a self-describing list of newly-visible tools rather than a bare "ok".
type DateRange ¶
DateRange is the inclusive [Start, End] window used by every summary / report payload to describe the period the rollup spans.
type DaySummary ¶
type DaySummary struct {
Date string `json:"date"`
Entries int `json:"entries"`
TotalSeconds int64 `json:"totalSeconds"`
TotalHours float64 `json:"totalHours"`
}
DaySummary is the per-day rollup row used by WeeklySummaryData. Date is RFC 3339 YYYY-MM-DD in the configured timezone.
type DeactivationResult ¶ added in v1.2.1
type DeactivationResult struct {
Kind string `json:"kind"`
Name string `json:"name"`
Group string `json:"group,omitempty"`
ToolCount int `json:"toolCount"`
DeactivatedTools []string `json:"deactivatedTools,omitempty"`
TotalVisibleTools int `json:"totalVisibleTools,omitempty"`
}
DeactivationResult mirrors ActivationResult for the deactivation path: the Service.DeactivateGroup callback returns one of these to describe which tools were removed from the visible tools/list.
type EffectiveRate ¶ added in v1.2.2
type EffectiveRate struct {
Hourly *clockify.Rate `json:"hourly,omitempty"`
Cost *clockify.Rate `json:"cost,omitempty"`
HourlyScope RateScope `json:"hourly_scope"`
CostScope RateScope `json:"cost_scope"`
}
EffectiveRate is the resolved hourly + cost rate that should be applied to a given (workspace, project, task, entry, user) combination. The Scope fields tell the caller which layer of the hierarchy supplied the rate so the model can explain its answer.
func ResolveEffectiveRate ¶ added in v1.2.2
func ResolveEffectiveRate( ws *clockify.Workspace, proj *clockify.Project, task *clockify.Task, entry *clockify.TimeEntry, userID string, ) EffectiveRate
ResolveEffectiveRate walks the Clockify rate hierarchy:
entry > task > project-member (matched on userID) > project > workspace-member (matched on userID) > workspace
Any of the inputs may be nil. The returned EffectiveRate.Scope is RateScopeNone when no layer supplied a rate. Hourly and Cost are resolved independently because a workspace can legitimately set a cost rate without a billable rate (and vice versa).
type EntryRateView ¶ added in v1.2.2
type EntryRateView struct {
EntryHourly *clockify.Rate `json:"entry_hourly,omitempty"`
EntryCost *clockify.Rate `json:"entry_cost,omitempty"`
EffectiveHourly *clockify.Rate `json:"effective_hourly,omitempty"`
EffectiveCost *clockify.Rate `json:"effective_cost,omitempty"`
HourlyScope RateScope `json:"hourly_scope"`
CostScope RateScope `json:"cost_scope"`
DurationSeconds int64 `json:"duration_seconds"`
BillableEarnings MoneyView `json:"billable_earnings,omitempty"`
Cost MoneyView `json:"cost,omitempty"`
}
EntryRateView is the LLM-facing block we attach to every time-entry row across tool outputs. It bundles the raw entry-level rates (so the caller can see what Clockify itself stored) with the resolved effective rate and the derived per-entry money.
func BuildEntryRateView ¶ added in v1.2.2
func BuildEntryRateView( ws *clockify.Workspace, proj *clockify.Project, task *clockify.Task, entry *clockify.TimeEntry, ) EntryRateView
BuildEntryRateView is the canonical adapter from a (workspace, project, task, entry, user) tuple to the EntryRateView envelope. Callers pass whatever context they have; nils are tolerated.
type FindAndUpdateEntryData ¶
type FindAndUpdateEntryData struct {
Entry clockify.TimeEntry `json:"entry"`
MatchedBy map[string]any `json:"matchedBy"`
UpdatedFields []string `json:"updatedFields"`
MatchedEntryID string `json:"matched_entry_id,omitempty"`
Current *TimeEntryUpdatePreview `json:"current,omitempty"`
Proposed map[string]any `json:"proposed_changes,omitempty"`
DryRun bool `json:"dry_run,omitempty"`
Note string `json:"note,omitempty"`
}
FindAndUpdateEntryData is the structured payload for clockify_find_and_update_entry. Entry is the matched time entry; MatchedBy explains which finder predicate identified it; UpdatedFields lists the fields that actually changed. When dry_run:true is set, Current + Proposed + DryRun carry the preview-only diff so a downstream confirmation step can stage the mutation before applying.
type IdentityData ¶
type IdentityData struct {
User clockify.User `json:"user"`
WorkspaceID string `json:"workspaceId"`
}
IdentityData pairs the upstream Clockify user with the resolved workspace so a single clockify_whoami response carries everything an agent needs to ground subsequent tool calls.
type LogTimeData ¶
type LogTimeData struct {
Entry clockify.TimeEntry `json:"entry"`
ResolvedProject string `json:"resolvedProject,omitempty"`
}
LogTimeData is the structured payload for clockify_log_time. Entry is the created TimeEntry; ResolvedProject names the project the agent supplied (by name or ID) so the caller can confirm name resolution succeeded.
type MoneyView ¶ added in v1.2.2
type MoneyView struct {
AmountCents int64 `json:"amount_cents"`
AmountDecimal string `json:"amount_decimal"`
Currency string `json:"currency,omitempty"`
Display string `json:"display,omitempty"`
}
MoneyView is the LLM-facing envelope for any monetary value the MCP surfaces. The model receives all four fields:
- amount_cents: int64 minor units (authoritative).
- amount_decimal: string, two dp, signed (audit / direct render).
- currency: ISO code from the source.
- display: pre-rendered symbol form (e.g. "€43.21 EUR").
Callers that have only a JSON-number from the reports host should use MoneyFromReportNumber; callers with an int-cents value (the primary API) should use MoneyFromCents.
func DerivedEarnings ¶ added in v1.2.2
func DerivedEarnings(eff EffectiveRate, durationSeconds int64) (billable, cost MoneyView)
DerivedEarnings multiplies the effective hourly + cost rates by the given duration (in seconds) and returns the per-entry billable earnings and cost as MoneyViews. Both come back zero when no rate is set for that side. Rounding is to the nearest cent.
Math: rate is cents-per-hour; duration is seconds; result is
cents = round(rateCents * durationSeconds / 3600)
We use float intermediates and math.Round for the final cent — matching `CentsFromReportNumber`'s half-away-from-zero behaviour so the MCP-derived number agrees with Clockify's own.
func MoneyFromCents ¶ added in v1.2.2
MoneyFromCents wraps an int64 cents value into a MoneyView.
func MoneyFromRate ¶ added in v1.2.2
MoneyFromRate is a nil-tolerant adapter for `*clockify.Rate`. A nil rate or an inherited sentinel returns the zero MoneyView so callers can decide whether to emit the field at all.
func MoneyFromReportNumber ¶ added in v1.2.2
MoneyFromReportNumber converts a JSON-number cents value coming from the reports.api host (always integer-cents-as-float in practice) to MoneyView. Banker's rounding to int64 cents.
type ProjectSummary ¶
type ProjectSummary struct {
ProjectID string `json:"projectId,omitempty"`
ProjectName string `json:"projectName"`
Entries int `json:"entries"`
TotalSeconds int64 `json:"totalSeconds"`
TotalHours float64 `json:"totalHours"`
}
ProjectSummary is the per-project rollup row used by SummaryData and WeeklySummaryData. ProjectID is omitempty so entries that did not resolve to a project (e.g. tracked with no project tag) still appear in the rollup keyed only by ProjectName.
type QuickReportData ¶
type QuickReportData struct {
Range DateRange `json:"range"`
Totals SummaryTotals `json:"totals"`
TopProject *ProjectSummary `json:"topProject,omitempty"`
RunningEntries []clockify.TimeEntry `json:"runningEntries,omitempty"`
EntriesSample []clockify.TimeEntry `json:"entriesSample,omitempty"`
ProjectsRepresented int `json:"projectsRepresented"`
SuggestedActions []ToolSuggestion `json:"suggestedActions"`
}
QuickReportData powers clockify_quick_report: a single-glance snapshot with totals, the top project, any running entries, and a short entry sample so an agent can answer "what did I just do?" without a full detailed report round-trip.
type RateScope ¶ added in v1.2.2
type RateScope string
RateScope identifies which layer of the Clockify rate hierarchy supplied the effective rate for a given time entry. Returned to the model so it can explain *why* a particular earning amount is what it is, rather than only the final number.
type ResultEnvelope ¶
type ResultEnvelope struct {
OK bool `json:"ok"`
Action string `json:"action"`
Data any `json:"data,omitempty"`
Meta map[string]any `json:"meta,omitempty"`
}
ResultEnvelope is the canonical shape every Tier 1 / Tier 2 tool handler returns. OK is the boolean success flag, Action mirrors the tool name for client-side dispatch, Data carries the typed payload (struct or map) and Meta is reserved for cross-cutting metadata (pagination cursors, fingerprint hashes, etc.). Wire-locked by the per-tool outputSchemas in output_schemas.go; mutate this struct and every schemaFor[T] surface has to be reviewed for drift.
type Service ¶
type Service struct {
Client *clockify.Client
WorkspaceID string
DefaultTimezone *time.Location // from CLOCKIFY_TIMEZONE; nil falls back to time.Now().Location() for flexible date/time inputs.
DedupeConfig *dedupe.Config // optional, set during wiring
PolicyDescribe func() map[string]any // set during wiring; returns policy description
Bootstrap *bootstrap.Config // set during wiring; describes current bootstrap visibility
ActivateGroup func(context.Context, string) (ActivationResult, error)
ActivateTool func(context.Context, string) (ActivationResult, error)
DeactivateGroup func(context.Context, string) (DeactivationResult, error)
GroupActivation func(string) (allowed bool, reason string)
// WebhookValidateDNS, when true, makes CreateWebhook/UpdateWebhook
// resolve the webhook host via the system resolver and reject any
// reply that contains a private/reserved IP. Config defaults this
// on for every profile so a hostname pointing at 169.254.169.254
// (cloud-metadata) or 10.0.0.x cannot turn the Clockify webhook
// delivery into an SSRF probe. Operators can explicitly opt out
// for trusted air-gapped tests.
WebhookValidateDNS bool
// WebhookHostResolver overrides the LookupIPAddr call for tests.
// nil = use net.DefaultResolver.
WebhookHostResolver func(context.Context, string) ([]netip.Addr, error)
// WebhookAllowedDomains is an optional escape-hatch list of webhook
// hostnames that bypass the WebhookValidateDNS private-IP check.
// Each entry is matched against the parsed URL's host (lowercased)
// either by exact equality (`webhook.example.com`) or by suffix
// when the entry begins with a dot (`.example.com` matches
// `webhook.example.com` and `api.example.com` but NOT
// `attacker.example.com.evil.com`). Empty list = no bypass; the
// DNS check applies to every host. Operators use this to admit
// known-trusted hostnames in split-horizon DNS environments where
// the hostname legitimately resolves to a private IP only on the
// control-plane network. See `docs/runbooks/webhook-dns-validation.md`
// §4b for the use case. Production wiring (env var + Config field)
// follows in a later commit; tests inject this field directly.
WebhookAllowedDomains []string
// Notifier delivers server→client notifications (progress, resource updates,
// etc.) emitted by tool handlers. nil = drop silently.
Notifier mcp.Notifier
// EmitResourceUpdate publishes notifications/resources/updated for a URI
// with an optional delta envelope. Wired from runtime.go to
// Server.NotifyResourceUpdated so the subscription gate lives in the
// protocol core rather than in every mutation handler. nil = drop silently
// (tests without a Server wired).
EmitResourceUpdate func(uri string, delta mcp.ResourceUpdateDelta)
// SubscriptionGate reports whether any client is currently subscribed
// to a URI. When wired (runtime.go sets it to
// Server.HasResourceSubscription), emitResourceUpdate short-circuits
// before the ReadResource round-trip so unsubscribed mutations don't
// pay for a redundant fetch. nil = gate disabled; every emit pays for
// the re-read (W3-era behaviour, preserved for tests).
SubscriptionGate func(uri string) bool
// ReportMaxEntries is the hard cap on the number of time entries a report
// tool will aggregate. 0 disables the cap. Wired from CLOCKIFY_REPORT_MAX_ENTRIES.
ReportMaxEntries int
// DeltaFormat selects the diff algorithm for resource notifications.
// "merge" (default) uses RFC 7396 merge patch; "jsonpatch" uses RFC 6902.
DeltaFormat string
// contains filtered or unexported fields
}
func (*Service) ActivateNamedTool ¶ added in v1.2.1
func (*Service) ActivateToolGroup ¶ added in v1.2.1
func (*Service) AddUserToGroup ¶
AddUserToGroup adds a user to a user group.
func (*Service) ArchiveProjects ¶
func (*Service) AssignProjectMemberships ¶ added in v1.2.2
func (*Service) AttendanceReport ¶ added in v1.2.2
func (*Service) CallDocumentedDeleteAPI ¶ added in v1.2.2
func (*Service) CallDocumentedReadAPI ¶ added in v1.2.2
func (*Service) CallDocumentedWriteAPI ¶ added in v1.2.2
func (*Service) CreateClient ¶
func (*Service) CreateCustomField ¶
func (*Service) CreateHoliday ¶
func (*Service) CreateProject ¶
func (*Service) CreateProjectFromTemplate ¶ added in v1.2.2
func (*Service) CreateProjectTemplate ¶
func (*Service) CreateTask ¶
func (*Service) CreateUserGroup ¶
CreateUserGroup creates a new user group.
func (*Service) CreateUserGroupAdmin ¶
func (*Service) CreateWebhook ¶
CreateWebhook creates a new webhook with URL validation.
func (*Service) CurrentUser ¶
func (s *Service) CurrentUser(ctx context.Context) (ResultEnvelope, error)
func (*Service) DeactivateToolGroup ¶ added in v1.2.1
func (*Service) DeactivateUser ¶
DeactivateUser deactivates a user. Supports dry-run (confirm pattern).
func (*Service) DeleteClient ¶ added in v1.2.2
DeleteClient archives the client if it is still active, then deletes it. Clockify rejects DELETE on active clients (the active rule is the same as for projects), and the PUT archive validator additionally requires the existing name in the body. The implementation mirrors the rawArchiveAndDeleteClient cleanup helper in tests/.
func (*Service) DeleteCustomField ¶
func (*Service) DeleteEntry ¶
DeleteEntry deletes a time entry by ID.
func (*Service) DeleteHoliday ¶
func (*Service) DeleteProject ¶ added in v1.2.2
DeleteProject archives the project if still active, then deletes it. Clockify rejects DELETE on active projects (the archive validator additionally requires the existing name in the body). Mirrors clients.DeleteClient's archive-first pattern; both resources share the same upstream constraint.
func (*Service) DeleteTag ¶ added in v1.2.2
DeleteTag deletes a tag by ID or exact name. Clockify's DELETE /workspaces/{ws}/tags/{id} works directly on active tags — no archive step is required (unlike clients). Supports dry_run.
func (*Service) DeleteTask ¶ added in v1.2.2
DeleteTask deletes a task by project + task reference (ID or name). Clockify requires tasks to be DONE before DELETE, so active tasks are first updated with the existing full-replacement shape plus status=DONE.
func (*Service) DeleteUserGroup ¶
DeleteUserGroup deletes a user group. Supports dry-run (minimal fallback).
func (*Service) DeleteUserGroupAdmin ¶
func (*Service) DeleteWebhook ¶
DeleteWebhook deletes a webhook. Supports dry-run (preview via GET).
func (*Service) DetailedReport ¶
func (*Service) EmitProgress ¶
EmitProgress publishes a notifications/progress if a progressToken was supplied with the current tools/call and the Service has a Notifier wired. No-op otherwise. total < 0 signals an indeterminate total.
func (*Service) FindAndUpdateEntry ¶
func (*Service) GetCustomField ¶
func (*Service) GetMemberProfile ¶ added in v1.2.5
func (s *Service) GetMemberProfile(ctx context.Context, args map[string]any) (ResultEnvelope, error)
GetMemberProfile returns a workspace-scoped member profile for a user.
func (*Service) GetProject ¶
func (*Service) GetProjectTemplate ¶
func (*Service) GetTask ¶ added in v1.2.2
GetTask fetches a single task by ID or exact name within a project. project (name or ID) and task (ID or name) are both required.
func (*Service) GetUserGroup ¶
func (*Service) GetWebhook ¶
GetWebhook retrieves a single webhook by ID.
func (*Service) GetWorkspace ¶
func (s *Service) GetWorkspace(ctx context.Context) (ResultEnvelope, error)
func (*Service) ListClients ¶
func (*Service) ListCustomFields ¶
func (*Service) ListDocumentedAPIOperations ¶ added in v1.2.2
func (*Service) ListEntries ¶
ListEntries returns recent time entries with optional filtering by date range, project, and pagination.
func (*Service) ListHolidays ¶
func (s *Service) ListHolidays(ctx context.Context) (ResultEnvelope, error)
func (*Service) ListProjectTemplates ¶
func (*Service) ListProjects ¶
func (*Service) ListResourceTemplates ¶
ListResourceTemplates returns the parametric URI templates clients can dereference by substituting concrete IDs.
func (*Service) ListResources ¶
ListResources returns a small, immediately-navigable set of concrete resources pinned to the Service's current workspace. Parametric resources (per-id entry, project, weekly report) live in ListResourceTemplates.
func (*Service) ListUserGroups ¶
ListUserGroups returns user groups for the workspace.
func (*Service) ListUserGroupsAdmin ¶
func (*Service) ListWebhookEvents ¶
ListWebhookEvents returns the static enum of webhook event types the Clockify webhooks API accepts. The upstream exposes no listing endpoint — see findings/webhooks.md (#15).
func (*Service) ListWebhooks ¶
ListWebhooks returns webhooks for the workspace.
func (*Service) ListWorkspaces ¶
func (s *Service) ListWorkspaces(ctx context.Context) (ResultEnvelope, error)
func (*Service) PolicyInfo ¶
func (s *Service) PolicyInfo(ctx context.Context) (ResultEnvelope, error)
func (*Service) QuickReport ¶
func (*Service) ReadResource ¶
ReadResource parses a clockify:// URI and fetches the underlying entity from Clockify, returning it as a single JSON-encoded ResourceContents entry. Unknown or malformed URIs return a -32602-equivalent error.
func (*Service) Registry ¶
func (s *Service) Registry() []mcp.ToolDescriptor
func (*Service) RemoveUserFromGroup ¶
func (s *Service) RemoveUserFromGroup(ctx context.Context, args map[string]any) (ResultEnvelope, error)
RemoveUserFromGroup removes a user from a user group. Supports dry-run (minimal fallback).
func (*Service) ResolveDebug ¶
func (*Service) ResolveName ¶ added in v1.2.1
func (*Service) ResolveWorkspaceID ¶
func (*Service) SearchTools ¶
func (*Service) SetCustomFieldValue ¶
func (*Service) SetProjectMemberships ¶
func (*Service) StartTimer ¶
func (*Service) StartTimerArgs ¶ added in v1.2.1
func (*Service) SummaryReport ¶
func (*Service) SwitchProject ¶
func (*Service) TestWebhook ¶
TestWebhook sends a test delivery to a webhook.
func (*Service) Tier2Handlers ¶
func (s *Service) Tier2Handlers(groupName string) ([]mcp.ToolDescriptor, bool)
Tier2Handlers returns the descriptors for a named Tier 2 group. Every returned descriptor has its Tool.OutputSchema populated with at least envelopeOpaque so MCP clients see a consistent envelope shape across all 96 lazy-loaded tools.
func (*Service) TimerStatus ¶
func (s *Service) TimerStatus(ctx context.Context) (ResultEnvelope, error)
func (*Service) TimesheetFillGap ¶ added in v1.2.1
func (*Service) TimesheetReview ¶ added in v1.2.1
func (*Service) TodayEntries ¶
TodayEntries returns time entries for the current day.
func (*Service) UpdateClient ¶ added in v1.2.2
UpdateClient performs a fetch-then-merge update of a client. Clockify's PUT /clients/{id} is a full replacement (omitted fields get nulled server-side), so we GET the existing client, layer caller-provided changes over the fetched object, and PUT the complete merged shape back. Caller-supplied empty strings are treated as "do not change" (use the dedicated `archived` boolean flag to flip archival state).
func (*Service) UpdateCustomField ¶
func (*Service) UpdateEntry ¶
UpdateEntry performs a fetch-then-update of a time entry, merging caller fields over the existing values.
func (*Service) UpdateMemberProfile ¶ added in v1.2.5
func (s *Service) UpdateMemberProfile(ctx context.Context, args map[string]any) (ResultEnvelope, error)
UpdateMemberProfile updates live-supported workspace member profile fields.
func (*Service) UpdateProject ¶ added in v1.2.2
UpdateProject performs a fetch-then-merge update of a project. Clockify's PUT /projects/{id} replaces the full record (omitted optional fields are nulled), so we GET the existing project, layer caller-provided changes over it, and PUT the merged shape back. Caller-supplied empty strings are treated as "do not change"; flip archival state through the dedicated `archived` boolean instead.
func (*Service) UpdateProjectEstimate ¶
func (*Service) UpdateProjectMemberships ¶ added in v1.2.2
func (*Service) UpdateProjectTemplate ¶ added in v1.2.2
func (*Service) UpdateProjectUserRate ¶ added in v1.2.2
func (*Service) UpdateTag ¶ added in v1.2.2
UpdateTag performs a fetch-then-merge update of a tag. Clockify's PUT /workspaces/{ws}/tags/{id} is a full replacement; we GET the existing tag, layer caller changes on top, then PUT the merged shape back. The archived boolean can be toggled explicitly.
func (*Service) UpdateTask ¶ added in v1.2.2
UpdateTask performs a fetch-then-merge update of a task. Clockify's PUT /projects/{pid}/tasks/{tid} is a full replacement; we GET the existing task, layer caller changes on top, then PUT the merged shape back. Empty-string caller args are treated as "no change".
func (*Service) UpdateTaskRate ¶ added in v1.2.2
func (*Service) UpdateUserGroup ¶
UpdateUserGroup updates a user group's name.
func (*Service) UpdateUserGroupAdmin ¶
func (*Service) UpdateUserRole ¶
UpdateUserRole updates a user's workspace role.
func (*Service) UpdateWebhook ¶
UpdateWebhook updates an existing webhook.
func (*Service) WeeklySummary ¶
type SummaryData ¶
type SummaryData struct {
Range DateRange `json:"range"`
Totals SummaryTotals `json:"totals"`
ByProject []ProjectSummary `json:"byProject"`
SuggestedActions []ToolSuggestion `json:"suggestedActions"`
Entries []clockify.TimeEntry `json:"entries,omitempty"`
}
SummaryData is the structured payload for clockify_summary_report and clockify_detailed_report: per-project rollups plus optional raw entries. The WeeklySummaryData variant adds a per-day axis on top.
type SummaryTotals ¶
type SummaryTotals struct {
Entries int `json:"entries"`
RunningEntries int `json:"runningEntries"`
TotalSeconds int64 `json:"totalSeconds"`
TotalHours float64 `json:"totalHours"`
}
SummaryTotals aggregates entry counts and tracked time across the containing DateRange. RunningEntries is the subset of Entries that are still in progress (no End yet); TotalSeconds is the canonical duration, TotalHours is the convenience float derived from it.
type Tier2Group ¶
type Tier2Group struct {
Name string
Description string
Keywords []string
ToolNames []string
Builder func(s *Service) []mcp.ToolDescriptor
}
Tier2Group defines a lazily-activated group of related tools.
type TimeEntryDraft ¶ added in v1.2.1
type TimeEntryRef ¶ added in v1.2.1
type TimeEntryUpdatePreview ¶ added in v1.2.1
type TimeEntryUpdatePreview struct {
Description string `json:"description"`
ProjectID string `json:"project_id,omitempty"`
Start string `json:"start,omitempty"`
End string `json:"end,omitempty"`
Billable bool `json:"billable"`
}
TimeEntryUpdatePreview is the projected "current" shape of a time entry shown alongside a proposed-change diff during a dry-run update.
type TimesheetFillGapData ¶ added in v1.2.1
type TimesheetFillGapData struct {
DryRun bool `json:"dryRun"`
Proposed TimeEntryDraft `json:"proposed"`
Entry clockify.TimeEntry `json:"entry,omitempty"`
Overlaps []TimeEntryRef `json:"overlaps,omitempty"`
Validated bool `json:"validated"`
}
type TimesheetIssue ¶ added in v1.2.1
type TimesheetReviewData ¶ added in v1.2.1
type TimesheetReviewData struct {
Range DateRange `json:"range"`
Totals SummaryTotals `json:"totals"`
ByDay []DaySummary `json:"byDay"`
ByProject []ProjectSummary `json:"byProject"`
Issues []TimesheetIssue `json:"issues"`
SuggestedActions []ToolSuggestion `json:"suggestedActions"`
Entries []clockify.TimeEntry `json:"entries,omitempty"`
}
type ToolSuggestion ¶ added in v1.2.1
type WeeklySummaryData ¶
type WeeklySummaryData struct {
Range DateRange `json:"range"`
Totals SummaryTotals `json:"totals"`
ByDay []DaySummary `json:"byDay"`
ByProject []ProjectSummary `json:"byProject"`
SuggestedActions []ToolSuggestion `json:"suggestedActions"`
Entries []clockify.TimeEntry `json:"entries,omitempty"`
UnassignedKey string `json:"unassignedKey,omitempty"`
}
WeeklySummaryData is the structured payload for clockify_weekly_ summary: a date range, total counts, per-day and per-project rollups, suggested follow-up actions for the agent, and (optionally) the raw entries so callers can drill into specific records without a second round-trip.
type WorkspaceContext ¶
type WorkspaceContext struct {
WorkspaceID string `json:"workspaceId"`
}
WorkspaceContext is the lightweight envelope returned by clockify_get_workspace when the caller only needs the resolved workspace identifier (full workspace details live behind clockify_list_workspaces).
Source Files
¶
- client_project_task_args.go
- client_project_task_schemas.go
- clients.go
- common.go
- context.go
- entries.go
- money.go
- output_schemas.go
- projects.go
- registry.go
- reports.go
- reports_api.go
- reports_api_schemas.go
- resolve_cache.go
- resource_cache.go
- resources.go
- risk_overrides.go
- schemagen.go
- tags.go
- tasks.go
- tier2_approvals.go
- tier2_catalog.go
- tier2_custom_fields.go
- tier2_expenses.go
- tier2_groups_holidays.go
- tier2_invoices.go
- tier2_probe_lab_api.go
- tier2_project_admin.go
- tier2_scheduling.go
- tier2_shared_reports.go
- tier2_time_off.go
- tier2_user_admin.go
- tier2_webhooks.go
- timer.go
- timesheet_workflows.go
- users.go
- workflows.go
- workspaces.go