Commit graph go-sdk/mcp
Author SHA1 Message Date
Recoordinate
2732839dba
mcp: prune completed listen request IDs from the session (#1190)
### Problem

`ServerSession` tracks the request IDs of in-flight
`subscriptions/listen` streams so `Close` can cancel the parked handlers
and avoid the jsonrpc2 drain deadlock. The ID is appended when the
listen starts, but it is never removed when the listen handler returns.

Every completed listen stream (peer cancel, unsubscribe, stream break)
therefore leaves one stale entry in the session for its entire lifetime.
On a long-lived session where a client repeatedly subscribes and
unsubscribes, the slice grows without bound: one leaked entry per cycle.

`Close` calls `jsonrpc2.Connection.Cancel` on each recorded ID, and a
stale ID is a no-op there today, but the bookkeeping is meant to hold
only in-flight listens and currently never shrinks.

### Change

Drop the request ID from the session's bookkeeping when the listen
handler returns, matching the lifecycle of the in-flight handler that
owns it.

### Tests

Three tests reproduce the leak, failing on `main` and passing here:

- `TestListenPrunedAfterSingleCompletion`
- `TestListenIDsDoNotAccumulate`
- `TestListenIDsLeakViaPublicSubscribeUnsubscribe`

The third exercises the leak through the public
`Subscribe`/`Unsubscribe` API. `go test ./mcp/` passes.

---------

Co-authored-by: Guglielmo Colombo <guglielmoc@google.com>
2026-08-25 17:15:09 +02:00
Scott Leggett
c68ad9a4e6
mcp: tolerate 404 on subscriptions/listen in stateless mode (#1193)
When connecting to remote stateless servers (such as GitHub's MCP
server), optional streams like subscriptions/listen may be rejected by
middleware with a plain-text HTTP 404 before reaching a JSON-RPC
handler.

Previously, checkResponse misclassified these 404s as lost stateful
sessions (ErrSessionMissing) and tore down the transport connection
because the error didn't wrap jsonrpc2.ErrRejected.

This change aligns with the MCP 2026-07-28 Streamable HTTP
specification:

1. Conditionally check for an active session ID before returning
ErrSessionMissing, since a 404 on a stateless connection cannot mean a
session was lost.

2. Wrap subscriptions/listen failures with ErrRejected (matching
server/discover) so the jsonrpc2 layer doesn't permanently break the
transport when encountering non-compliant plain-text 404s.

---

I have manually tested this change against GitHub's hosted MCP server
and confirmed that it fixes
https://github.com/github/github-mcp-server/issues/3129
2026-08-25 14:27:37 +02:00
Guglielmo Colombo
b8c53fedd6
mcp: add docs for tier 1 assessment (#1195)
Closes open points in
[comment](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/3220#issuecomment-5373089321)
2026-08-24 12:00:59 +02:00
Guglielmo Colombo
6f0a645c20
mcp: add ServerSession.NotifyElicitationComplete (#1194)
Adds:

```go
func (ss *ServerSession) NotifyElicitationComplete(ctx context.Context, params *ElicitationCompleteParams) error
```

As according to
[spec](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/2025-11-25/schema.ts#L2493-L2501)
2026-08-24 10:14:28 +02:00
Lee
3d6450fccf
mcp: bound streamable Close DELETE so a silent peer cannot hang teardown (#1184)
Close issued a synchronous session-termination DELETE on the connection
context and cancelled that context only after `Do` returned. A reachable
but silent peer could stall `Close()` until the TCP timeout.

Give the DELETE its own short timeout.

RED on current main: `TestCloseHangsOnBlackHoledDelete` failed with
`Close() blocked on a black-holing DELETE`.

GREEN: `go test ./mcp/ -count=1 -timeout 120s -run
'TestStreamableClient|TestCloseHangs|TestCallCancellation_FastReturn'`

Fixes #1183

Made with [Cursor](https://cursor.com)

Co-authored-by: Guglielmo Colombo <guglielmoc@google.com>
2026-08-21 12:31:12 +02:00
PratikDhanave
ce0b198202
mcp: prevent MemoryEventStore.After panic on index past the end (#1132)
## Summary

`MemoryEventStore.After` guarded only the lower bound of the requested
index:

```go
start := index + 1
if dl.first > start { // too old → ErrEventsPurged
    return nil, fmt.Errorf(... ErrEventsPurged)
}
return slices.Clone(dl.data[start-dl.first:]), nil
```

There was no *upper*-bound guard, so an `index` greater than the highest
stored event made the final slice expression panic with `slice bounds
out of range`. The boundary `start-dl.first == len(dl.data)` (resume
from the last event seen) is a valid empty replay, so only
strictly-greater indices faulted.

This is reachable from untrusted input: `parseEventID` accepts any
non-negative index from the client-supplied `Last-Event-ID` header, and
`serveGET` passes it straight to `eventStore.After`. Direct callers of
the exported `EventStore.After` API crash outright.

Fixes #1131

## Change

Return an empty replay for an index at or beyond the latest stored event
— there is nothing after it — consistent with the already-valid `index
== last` case. `ErrEventsPurged` would be misleading here, since those
events were never sent rather than purged.

## Testing

Extended `TestMemoryEventStoreAfter` with indices past the end of a
stream (`3`, `100`, and one past a second stream), asserting an empty
replay with no error.

Verified the new cases **panic on the pre-fix code** (`panic: runtime
error: slice bounds out of range [3:2]`) and **pass with the fix**. `go
vet ./mcp/` and the full `go test ./mcp/` suite pass.

---------

Co-authored-by: Yaroslav Shevchuk <yarolegovich@gmail.com>
2026-08-21 10:53:36 +02:00
gwyszynski-sa
b0408f2821
mcp: prefer the negotiated protocol version over the request context (#1163)
setMCPHeaders resolved Mcp-Protocol-Version from the request context
before
c.initializedResult. #1107 established the opposite order and said so in
its
description; the code it replaced also consulted the context last. The
two
branches were transposed by the switch-to-if rewrite in #1115, whose
subject
was an unrelated nil-pointer check.

The context branch serves the pre-negotiation server/discover probe,
which
sets its own value in Client.Connect. Once a version has been negotiated
it is
the authoritative one for that connection, so initializedResult should
win.
_meta.protocolVersion from the outgoing message stays on top, so #1109
stays
fixed.

The existing table built its request with http.NewRequest, so
protocolVersionFromContext returned "" in every case and the two
orderings
were indistinguishable, which is why the transposition went unnoticed.
Adds a
ctxVersion dimension and three cases pinning the precedence.

Fixes #1162

Co-authored-by: Guglielmo Colombo <guglielmoc@google.com>
2026-08-18 07:42:58 +00:00
Guglielmo Colombo
1fcaf0c393
mcp: resolve deadlock on serverSession.Close() with subscriptionsListen call (#1166)
Fixes #1160
2026-08-17 12:21:13 +00:00
King Star
ba1496a9aa
mcp: keep request log levels scoped to each request (#1168)
Fixes a request-scoping bug in the new-protocol logging path.
`ServerSession.handle` decoded
`_meta[io.modelcontextprotocol/logLevel]`, but stored it in
`ServerSessionState.LogLevel`. Concurrent new-protocol requests on the
same session could therefore clear or inherit another request's log
threshold before the original handler emitted logs.

This keeps the new-protocol log level on the handler context instead.
`ServerSession.Log` and `LoggingHandler.Enabled` read that context value
first, while legacy `logging/setLevel` behavior still uses session
state.

Tests:

- `go test ./mcp -run
TestServerLogLevelDoesNotLeakBetweenNewProtocolRequests -count=1`
- `go test -race ./mcp -run
TestServerLogLevelDoesNotLeakBetweenNewProtocolRequests -count=1`
- `go test ./mcp -run TestEndToEnd -count=1`
- `go test ./mcp -run TestValidateRequestMeta -count=1`
- `go test ./mcp -run
TestStreamableStateless_NewProtocolSession_NoFakeInit -count=1`
- `go test ./... -skip
TestSSELocalhostProtection|TestStreamableLocalhostProtection`

A full `go test ./...` run in my local environment still fails the two
localhost protection cases for `0.0.0.0 via localhost rejects evil.com`;
those same two tests also fail when run directly and are unrelated to
this logging change.

Co-authored-by: Guglielmo Colombo <guglielmoc@google.com>
2026-08-17 14:00:41 +02:00
Recoordinate
0eb1600eef
mcp: avoid panicking when a resource handler returns nil (#1176)
### What

`readResource` dereferenced the handler's result before the `if res ==
nil`
check that was meant to guard it. A `ResourceHandler` returning `(nil,
nil)`
therefore panicked instead of returning an error:

- modern clients: `handleMultiRoundTripResult` calls `res.setResultType`
on the
  nil result, and
- older clients: `res.setDefaultCacheableValues()` runs on the nil
result.

Either way the `if res == nil` guard a few lines below was dead code.

### Why it matters

Request handlers run in their own goroutine and nothing recovers, so the
panic
does not just fail the one request. It terminates the whole server
process and
every concurrent session.

The sibling handlers already avoid this: `callTool` and `getPrompt` both
guard
their result with `if err == nil && res != nil` before touching it, so a
`(nil, nil)` return flows up and becomes a normal error response.

### Change

Move the nil check in `readResource` ahead of
`handleMultiRoundTripResult` and
`setDefaultCacheableValues`, so a nil result returns the existing
descriptive
error (`read handler returned nil information`) instead of panicking.
Added a
regression test that drives a resource handler returning `(nil, nil)`
through
the server and asserts a clean error.
2026-08-17 10:44:53 +02:00
Guglielmo Colombo
4282916668
mcp: avoid Client.Connect leaks (#1158)
Fixes #1154
2026-08-10 08:52:50 +00:00
Recoordinate
e9a85e285f
mcp: fix typo in protocol version comment (#1156)
`protcol` should be `protocol`.

The comment sits above the `Mcp-Protocol-Version` header lookup, and the
surrounding code uses `protocolVersion` and
`protocolVersionFromContext`, so this is the only place in the package
where the word is misspelled.
2026-08-10 09:10:06 +02:00
Guglielmo Colombo
039119057f
mcp: allow asynchronous cancel notification (#1151)
Fixes #1150
2026-08-07 10:43:17 +02:00
dev_Hakaze
958dfcc532
mcp: limit SSE discover supportedVersions to SSE-defined revisions (#1121)
## Summary

`NewSSEHandler` sessions were advertising `2026-07-28` in
`server/discover` `supportedVersions`. That revision only defines stdio
and Streamable HTTP, not the deprecated HTTP+SSE binding, so
Modern-first clients could negotiate a revision the transport cannot
honour.

## Changes

- Implement `ProtocolVersionSupporter` on `SSEServerTransport` so
`filterSupportedVersions` excludes `>= 2026-07-28` (matching the
streamable transport's version gate pattern).
- In `Server.discover`, only set session `InitializeParams` when the
requested version is actually supported by the transport. Without this,
a discover probe that returns only legacy versions still marked the
session initialized, and the client's fallback `initialize` failed with
`duplicate "initialize" received`.
- Tests: unit coverage for filtered SSE versions, plus an end-to-end
Modern client → SSE fallback-to-initialize path.

Fixes #1112

## Test plan

- [x] `go test ./...`
- [x] `go test ./mcp/ -run
'TestSSE|TestInMemory_E2E_Discover|TestStreamableStateful_AcceptsDiscover|TestStreamableHTTP_E2E_Discover|TestClientConnectDiscover'`

Assistance: human-reviewed AI assistance used for implementation.

---------

Co-authored-by: arimu1 <19286898+arimu1@users.noreply.github.com>
2026-08-05 15:36:22 +02:00
Guglielmo Colombo
6b1518cb0b
mcp: return json-rpc error on stateful server serving protocolVersion20260728 requests (#1143)
Fixes #1130
2026-08-05 12:16:39 +02:00
Guglielmo Colombo
c4a4ce4543
mcp: fix error propagation to prevent session closing (#1118)
Fixes #1117
2026-08-04 11:02:36 +02:00
dev_Hakaze
1acd66e9d7
mcp: export ClientSessionOptions.ProtocolVersion (#1127)
## Summary

`ClientSessionOptions.protocolVersion` was unexported and documented as
test-only, so external consumers of `Client.Connect` could not request a
specific protocol revision.

This exports the field as `ProtocolVersion` with the same semantics:

- empty → request the latest supported version (unchanged default)
- non-empty → send that version in initialize/discover
- existing negotiate-down path is unchanged

## Usage

```go
cs, err := client.Connect(ctx, transport, &mcp.ClientSessionOptions{
    ProtocolVersion: "2025-11-25",
})
```

## Testing

- `go test ./mcp/ -count=1` (pass)

Fixes #1113

Co-authored-by: arimu1 <19286898+arimu1@users.noreply.github.com>
Co-authored-by: Guglielmo Colombo <guglielmoc@google.com>
2026-08-03 15:29:52 +02:00
Guglielmo Colombo
0d0cdbc943
mcp: prevent leaks of ServerSession on StatefulServer (#1137)
Fixes #1136
2026-08-03 13:54:24 +02:00
n0liu
7743b71b1c
mcp: fix ListTools panic and null normalization on malformed tools (#1120)
Fixes #1119.

`ClientSession.ListTools` post-processes the server response through
`filterValidTools`, which has two problems on malformed input:

1. **Nil-pointer panic on `"tools":[null]`.** A `nil` `*Tool` element
reaches `validateParamHeaderAnnotations(tool)`, which dereferences
`tool.InputSchema`, crashing the client on untrusted server input.
2. **`"tools":null` is normalized into a non-nil empty slice.**
`make([]*Tool, 0, len(tools))` is always non-nil, so a nil `Tools` slice
from a malformed response is silently laundered into valid-looking data.

Reproduction:

```go
filterValidTools(nil, []*Tool{nil}) // panics: nil pointer dereference
filterValidTools(nil, nil)          // returns non-nil slice (len 0), want nil
```

Fix (`mcp/streamable_headers.go`):

- Skip (log and exclude) nil tool elements instead of dereferencing
them, so a malformed `"tools":[null]` can no longer crash the client.
This is consistent with the function’s existing contract of excluding
invalid tools.
- Return early with `nil` for a nil input slice so a `"tools":null`
response is preserved as nil rather than normalized into an empty slice.

Added `TestFilterValidToolsNilHandling` covering both defects plus the
mixed valid/nil case. `go test ./mcp/` passes; `gofmt` and `go vet` are
clean.

Note on scope: this keeps the change minimal and within
`filterValidTools`’s existing signature. If maintainers would rather
surface a hard protocol error for a malformed `"tools":null` /
`"tools":[null]` response at the `ListTools` level (rather than
tolerating and filtering it), I’m happy to follow up with that larger
change.
2026-07-30 10:06:14 +02:00
Yaroslav
bc72835f62
mcp: fix potential nil-pointer dereference on message send (#1115) 2026-07-27 17:20:53 +02:00
George McCarron
e761950d97
mcp: avoid double-copy of payload in writeEvent (#1106)
`writeEvent` built the SSE frame with `fmt.Fprintf(&b, "data: %s\n\n",
string(evt.Data))`, which copies the payload into a fresh string and
then again into the buffer, growing it via repeated `bytes.growSlice`
doublings. For large MCP responses (e.g. ~162KB `tools/list`) under a
burst of concurrent writes this ~3x amplifies allocations and peak heap.

Write the payload directly into a pre-grown buffer instead. Output
framing is byte-identical. Benchmarks (162KB payload): 517KB->172KB per
op, 9->4 allocs/op, ~3x faster.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Yaroslav <yarolegovich@gmail.com>
2026-07-24 10:07:06 +02:00
Jan Steinke
2781b8f7e3
mcp: derive Mcp-Protocol-Version header from the outgoing message (#1107)
`streamableClientConn.setMCPHeaders` sets `Mcp-Protocol-Version` only
from `c.initializedResult`, which is populated exclusively through the
unexported `clientConnection.sessionUpdated` hook. `Client.Connect`
reaches that hook via a type assertion on the `Connection` returned by
the `Transport`:

```go
  if hc, ok := cs.mcpConn.(clientConnection); ok {
      hc.sessionUpdated(cs.state)
  }
```

That assertion silently fails whenever the `Connection` is wrapped by
another type that exposes only the exported `Connection` interface.
`c.initializedResult` then stays `nil` for the life of the session, and
every `SEP-2575` (>= `2026-07-28`) request sent through that connection
is missing the header. Servers that validate the header per spec reject
the request with `400 Bad Request`, closing the connection.

Every SEP-2575 request already carries its own `_meta.protocolVersion`
field via `injectRequestMeta`. `setMCPHeaders` now reads the protocol
version from the outgoing message first, falling back to
`c.initializedResult` and then the request context.

This is currently breaking the GitHub MCP with the 1.7-pre releases of
this module.

Fixes #1109

Co-authored-by: eu.anthropic.claude-sonnet-5 via Crush <charmcrush@users.noreply.github.com>
2026-07-24 09:21:59 +02:00
Guglielmo Colombo
827f90ba0c
mcp: allow opt-in to cancel handler ctx on aborted POST (#1099)
Fixes #1093
2026-07-17 13:40:39 +02:00
Guglielmo Colombo
5cb8339210
mcp: update return meta in DiscoverResult (SEP-2575) (#1097)
This PR implements the latest changes introduced by
https://github.com/modelcontextprotocol/modelcontextprotocol/pull/3002
2026-07-16 16:10:12 +02:00
Guglielmo Colombo
8baa4ccebe
mcp: add return type to subscriptions/listen (#1088)
This PR adds the expected return type to `subscriptions/listen` rpc
2026-07-15 14:37:19 +02:00
Guglielmo Colombo
9576afc114
mcp: wrap unmarshalParams with jsonrpc error (#1087)
Fixes #976
2026-07-14 14:26:18 +00:00
Guglielmo Colombo
7fde7d3452
mcp: reject calls to methodDiscover for <20260728 requests (#1084)
This PR adds a gate for requests towards methodDiscover if it is coming
from a client that does not support the 20260728 protocol version
2026-07-14 12:13:40 +02:00
Guglielmo Colombo
c79a30ae0a
mcp: add param check for CompleteResult (#1080)
Fixes #1071
2026-07-13 12:14:21 +00:00
Yashas Gunderia
dd79ca3d44
mcp: include resultType on new-protocol responses (#1060)
## Summary

- Add `resultType: "complete"` to non-MRTR server result responses for
2026-07-28 requests.
- Cover `server/discover`, list methods, and completion responses, and
update expected conformance/example output.

## Why

Fixes #1032. The 2026-07-28 schema requires `resultType` on result
objects, but only the MRTR-capable results were setting it.

## Validation

- `go test ./mcp -run
'Test(ServerSessionHandle|CompleteResult|ClientConnectDiscover|InMemory_E2E_Discover)'
-count=1` — passed\n- `go test ./mcp -count=1` — passed\n- `go test
./...` — passed\n- `go vet ./...` — passed

---------

Co-authored-by: ychampion <ychampion@users.noreply.github.com>
Co-authored-by: Guglielmo Colombo <guglielmoc@google.com>
2026-07-13 11:51:19 +00:00
Guglielmo Colombo
40f034322f
mcp: infer elicit mode from ElicitParams (#1078)
Fixes #1072
2026-07-13 11:49:15 +02:00
Guglielmo Colombo
ce393acb95
mcp: do not ApplyDefault when res.Content==nil (#1069)
Fixes #1062
2026-07-10 11:26:29 +02:00
Guglielmo Colombo
deecf8a432
mcp: block server initiated requests (SEP-2322) (#1057)
This PR explicitly blocks server initiated requests in server.go
2026-07-08 15:17:41 +02:00
Guglielmo Colombo
7f67c851d1
mcp: enforce body size limit in Stremable connection (#1055)
This PR enforces a body size limit on Streamable connection to prevent
OOM attacks
2026-07-08 10:34:41 +02:00
Guglielmo Colombo
6de85ec3ed
mcp: do not enforce TTL on cached tool (#1053)
This PR removes the TTL enforcing on the cached tools, when used to
generate the http-parameters for CallTool, according to updated
[spec](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2972)

> Clients **MUST** construct `Mcp-Param-*` headers using the most
recently obtained `inputSchema` for the tool.
2026-07-07 13:43:10 +02:00
Guglielmo Colombo
d651e2d2e1
mcp: make NotificationSubscriptions a mandatory field (#1050)
Fixes #1037
2026-07-07 11:39:18 +02:00
Guglielmo Colombo
ec564f9ccb
mcp: cap negotiated protocolVersion in legacy initialize to protocolVersion20251125 (#1051)
Fixes #1033
2026-07-06 15:40:27 +00:00
Guglielmo Colombo
224a240875
mcp: do not exclude Notifications from carrying InitializeParams in Meta (#1049)
Fixes #1043
2026-07-06 17:10:26 +02:00
Yaroslav
ede1894174
fix: extra wrapper for input response map (#1045)
fixes #1036
2026-07-02 09:22:05 +02:00
Guglielmo Colombo
65ece59643
mcp: Allow registration of custom JSON-RPC methods (#956)
## Description

This PR introduces support for custom (non-standard) JSON-RPC methods in
the MCP Go SDK.
This feature enables servers to handle arbitrary JSON-RPC methods and
clients to invoke them, all while maintaining full type safety and
integrating seamlessly with the SDK's existing middleware and session
management.

- Server-Side Registration: Added AddReceivingCustomMethod to allow
servers to register handlers for custom methods. Incoming requests are
automatically unmarshaled into user-defined parameter structs.
- Client-Side Calling: Added AddSendingCustomMethod which returns a
strongly-typed caller function that clients can use to invoke custom
methods and receive strongly-typed results.
- Helper Structs: Provided ParamsBase and ResultBase for users to embed
in their custom structs. This allows them to easily satisfy the SDK's
internal Params and Result interfaces.

Fixes #954
2026-06-25 23:13:17 +02:00
Guglielmo Colombo
a817f61412
mcp: add Cacheable fields to DiscoverResult (#1022)
This PR add the Cacheable fields to the DiscoverResult, as it was added
later
(8e4c2322ca)
2026-06-24 14:08:43 +02:00
Guglielmo Colombo
7f4aa4a0ce
mcp: add 2026-07-28 to the supported protocol versions (#1020)
This PR adds the protocol version `2026-07-28` to the list of supported
protocol versions and fixes legacy tests hardcoding the legacy protocol
version for those use cases.
2026-06-24 12:02:56 +02:00
Guglielmo Colombo
b9e6fc5a66
mcp: add documentation for new protocol version (#1019)
Add documentation for new protocol version in the `internal/docs`
2026-06-23 17:07:38 +02:00
Guglielmo Colombo
01847b35b3
mcp: refactor notification of subscribed sessions (#1018)
This PR improves the notification of subscribed sessions removing
duplicated part
2026-06-23 09:50:33 +00:00
Guglielmo Colombo
b6649db4f9
mcp: Deprecate roots, sampling and logging (SEP-2577) (#1017)
Fixes #1013
2026-06-23 11:11:08 +02:00
Guglielmo Colombo
cd7d80c591
mcp: Implement subscriptions/listen rpc (SEP-2575) (#1007)
Fixes #966
2026-06-22 18:57:36 +02:00
Guglielmo Colombo
3486f6bcaf
mco: update JSON-RPC error codes to align with updated MCP specification (#1016)
This PR updates the error codes to align with the updated specifications
in
https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2907

ErrServerClosing and ErrClientClosing are reverted to their 1.6.0
version codes, as they do not overlap anymore with the newly introduced
error codes.
2026-06-22 10:27:31 +02:00
Guglielmo Colombo
17029489ff
mcp: bump protocol version from 2026-06-30 to 2026-07-28 (#1015)
The new official date for the protocol version has been moved to
'2026-07-28'. Update all the references in the code of the old version.
2026-06-22 09:53:04 +02:00
Guglielmo Colombo
b85574f685
mcp: Enable legacy initialize fallback on any error (#1014)
To guarantee a better compatibility with legacy server, enable the
fallback to the legacy initialize rpc in case of any error returned by
the server, in case of `server/discover` request.
2026-06-18 15:52:11 +02:00
Guglielmo Colombo
6333aa7c63
mcp: add ttl for list results (SEP-2549) (#1008)
Fixes #994
2026-06-18 15:20:21 +02:00
Guglielmo Colombo
71ffcb412a
mcp: add MCPGPDEBUG for opt-in Content-Type check (#1012)
Copy of existing
[PR](https://github.com/modelcontextprotocol/go-sdk/pull/972) patching
1.6.0 version
2026-06-17 11:41:35 +02:00