- Endpoint
- Authentication
- Scopes
- Tools
- Resources
- Prompts
- Results and refusals
- Rate limits
- What an agent never does
- What the record shows
- Testing and review
Endpoint
Tesserow exposes one hosted MCP server over Streamable HTTP. There is nothing to install, no SDK, and no per-client configuration on Tesserow's side; any MCP-capable client that can send a bearer token connects the same way.
| Environment | Endpoint | Use |
|---|---|---|
| Production | https://app.tesserow.com/mcp | Real accounts |
| Demo | https://demo.tesserow.com/mcp | Review and integration testing against synthetic accounts with a lived-in ledger |
Requests are JSON-RPC 2.0 over HTTP POST. Responses are JSON whatever the Accept header says. A request without a valid token receives 401 with a JSON body, never a redirect.
curl -s -X POST https://app.tesserow.com/mcp \
-H "Authorization: Bearer tsr_…" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Authentication
Tesserow uses bearer tokens that the person issues themselves. There are no agent identities and no service accounts: a token is one person's hand, with that person's permissions minus the human signatures listed under what an agent never does.
- Issuing
- Settings, Integrations, in the Tesserow app. The account must have two-factor authentication enrolled, and the session must confirm its password. The person names the token, ticks the scopes, and sets a lifetime from 1 to 365 days (default 90). The secret, prefixed
tsr_, is shown once and stored only as a hash. - Presenting
Authorization: Bearer tsr_…on every request.- Who it acts as
- A contributor (their own ledger), or a business workspace seat (owner, admin or member). A seat token carries the seat's role and sees exactly what that role sees; a member seat's agent never sees rates, private notes or email addresses. Staff accounts cannot issue tokens.
- Revoking
- The Integrations page lists every token with its call count and last use, and revokes it in one click; the next call fails with
401. Tokens are replaced, not renewed. A staff reset of the account's two-factor revokes every token on the account. - OAuth
- Not required. Platforms that need an authorization-code flow with PKCE can be supported; the token model beneath it would not change. Ask at hello@tesserow.com.
Scopes
Nine scopes, granted per token. A call outside the token's scopes returns a clear refusal, not a partial result. Contributor tokens may hold any scope; business seat tokens are limited to the four marked.
| Scope | Grants | Contributor | Business seat |
|---|---|---|---|
schedule:read | Read the schedule: blocks, capacity, weekly cap | yes | no |
schedule:write | Propose and withdraw blocks | yes | no |
time:read | Read time records and blocks to log | yes | yes (approval queue) |
time:write | Log and submit time, signing as the contributor | yes | no |
requests:read | Read work requests | yes | yes |
requests:write | Answer (contributor) or send (business) work requests | yes | yes |
billing:read | Read approved work not yet invoiced | yes | no |
billing:write | Draft invoices | yes | no |
standing:read | Read standing, bench and contract terms | yes | yes |
Tools
Seventeen tools across the two account kinds. tools/list returns only the ones the token's account kind and scopes allow: twelve for a contributor, five for a business seat. Read tesserow://me first; it carries the contract ids the write tools take.
Contributor tools
| Tool | Scope | Purpose |
|---|---|---|
schedule_week | schedule:read | This week on the planner: declared hours per day, committed blocks with client and contract, hours used against the weekly cap, and the residual. Pass week (a Monday, YYYY-MM-DD) for another week. |
schedule_propose | schedule:write | Place a block of hours under an active contract: contract_id, date, start_time, hours (quarter-hour steps); optional request_id to place it for an accepted work request. The ledger answers admitted, held or rejected with the reason. A rejection is still recorded. |
schedule_withdraw | schedule:write | Withdraw a committed or held block that has no time record against it. A block with hours logged cannot be withdrawn; the time record is the thing to revise. |
time_blocks_to_log | time:read | Committed blocks that have ended with no time record against them, oldest first. |
time_list | time:read | Time records, newest first: draft, submitted, approved, disputed. Filter by state. |
time_log | time:write | Draft a time record against a block: block_id, started_at, ended_at (local), optional note. Returns the draft and any anomalies flagged. Nothing is signed until time_submit. |
time_submit | time:write | Submit a draft, signing it as the contributor. This is the contributor's own signature and it is final; a submitted record can only be revised if the client disputes it. Approval stays with a human on the client side. |
requests_inbox | requests:read | Work requests waiting on the person, soonest to expire first, with estimated hours, window, payout estimate at the contract rate and time left to answer. |
requests_decide | requests:write | Accept or decline a work request: request_id, decision, optional reason. Accepting schedules nothing; place blocks with schedule_propose afterwards. |
standing_summary | standing:read | VeriHour standing for a window (default this week and the next three): declared, committed, verified, attested and residual hours, conflicts caught, and whether the record verifies. |
billing_uninvoiced | billing:read | Per client: approved time records not yet on a live invoice, with hours and the range they cover. |
billing_draft_invoice | billing:write | Generate a draft invoice for one client from approved, uninvoiced records: client_id, optional period and due_in_days. The draft is not sent; the person reviews and sends it in the app. |
Business seat tools
| Tool | Scope | Purpose |
|---|---|---|
bench_list | standing:read | Everyone on the workspace's bench: name, discipline, claimed or unclaimed seat, availability, and standing over the next four weeks. Rates and private notes only for owner and admin seats. |
contracts_list | standing:read | Active contracts: contributor, terms (rates, weekly budget, hard cap, dates, overage policy), this week's standing against the budget, and whether time is auto-approved. Rates only for owner and admin seats. |
time_queue | time:read | Submitted time records waiting for an owner or admin to countersign, oldest first, with anomaly flags. Read only: approval is a human signature and happens in the app. |
requests_list | requests:read | The workspace's work requests, newest first, with state, contributor, estimate and window. A member seat sees only its own. |
requests_create | requests:write | Compose and send a work request under an active contract: contract_id, description, estimated_hours, rate_class, window dates. Over the contract's approval threshold it is routed to approvers; past the hard cap, or when the contributor is away or not taking requests, it is refused. |
Resources
| URI | Returns |
|---|---|
tesserow://me | The account behind the token: kind, display name, timezone, workspace and role for a seat, the active contracts with their ids, the scopes granted, and when the token expires. Read this first. |
tesserow://contract/{public_id} | One contract: parties, rates where the token may see them, weekly budget, hard cap, approval threshold, dates, overage policy, and this week's standing against those terms. |
tesserow://verihour/{contributor} | A contributor's VeriHour standing for this week and the next three. Readable for the token's own contributor, or from a workspace seat, any contributor on its bench. |
Prompts
plan_my_week- Read this week's planner and the work-request inbox, then propose blocks for accepted work inside the declared capacity and caps, reporting what was placed and what the ledger refused.
log_yesterday- Find finished blocks with no hours logged, draft time records from the person's notes, and submit them once the person confirms each one.
The server's instructions to every agent are the same as ours to people: propose before you place, draft before you submit, and confirm with the person before any write they have not seen.
Results and refusals
Every tool returns structured content plus a one-sentence summary string saying what happened. A refusal by the ledger (a block that overlaps another, a proposal past a cap, a request outside a contract's dates, a record that cannot be withdrawn) is a normal result with the reason in it, not a protocol error, because the refusal is itself part of the record. Validation problems with the arguments come back as tool errors naming the field. Tool output is data about records; it never contains instructions to the agent.
| HTTP | Meaning |
|---|---|
200 | The JSON-RPC response, including tool refusals and tool errors |
401 | Missing, unknown, expired or revoked token (JSON body) |
429 | Rate limit reached; see below |
Rate limits
| Limit | Default |
|---|---|
| Per token | 60 calls per minute, 600 per hour |
| Per IP across tokens | 60 calls per minute |
| Unauthenticated, per IP | 20 per minute, 200 per hour |
Throttling runs before authentication. Read tools are cheap; there is no separate quota for them.
What an agent never does
These are design lines, not settings, and they hold whatever scopes a token carries.
- Approve or dispute another person's hours.
time_queueis read only; verified is a human countersignature. - Draft, send, confirm or end a contract.
- Send an invitation of any kind, or manage workspace members.
- Send an invoice or change its status.
billing_draft_invoicestops at a draft the person reviews. - Export the signed records. Agents read summaries; exports are for people and auditors.
- See more than the person. Scope gating and seat-role masking apply to agents exactly as they apply in the app.
What the record shows
Every write an agent makes leaves a row on the account's security trail: which tool, whether it was done or refused, which record it touched, and the token it came from. Never the arguments. Inside the workspace's signed audit record the same write is marked as made via that agent, so the audit trail both parties see reads, for example, "Rosa's assistant proposed 4.0 hrs · via agent" followed by "Rosa Delgado submitted 4.0 hrs" and "Acme Finance approved 4.0 hrs · verified". The record can always say: the agent proposed, the person signed.
Testing and review
Agent platforms reviewing the connector get a persona on the demo environment with a lived-in ledger: a working token, the endpoint, and app sign-in with two-factor, so reviewers can watch their agent's actions land on the person's planner and trail. Write to hello@tesserow.com. Security questions and reports go to security@tesserow.com. The connector's data handling is described in the Privacy Policy (Automated agents) and its rules of use in the Terms of Use (Automated agents and API access).
Bring your own agent. Keep your own signature.
Tesserow for agents is available to early-access accounts. Tell us which client you use and what you want it to handle.
Request early access