MCPcopy Create free account
hub / github.com/modelcontextprotocol/go-sdk / Write

Method Write

mcp/streamable.go:1781–1929  ·  view source on GitHub ↗

Write implements the [Connection] interface.

(ctx context.Context, msg jsonrpc.Message)

Source from the content-addressed store, hash-verified

1779
1780// Write implements the [Connection] interface.
1781func (c *streamableClientConn) Write(ctx context.Context, msg jsonrpc.Message) error {
1782 if err := c.failure(); err != nil {
1783 return err
1784 }
1785
1786 var requestSummary string
1787 var forCall *jsonrpc.Request
1788 switch msg := msg.(type) {
1789 case *jsonrpc.Request:
1790 requestSummary = fmt.Sprintf("sending %q", msg.Method)
1791 if msg.IsCall() {
1792 forCall = msg
1793 }
1794 case *jsonrpc.Response:
1795 requestSummary = fmt.Sprintf("sending jsonrpc response #%d", msg.ID)
1796 default:
1797 panic("unreachable")
1798 }
1799
1800 data, err := jsonrpc.EncodeMessage(msg)
1801 if err != nil {
1802 return fmt.Errorf("%s: %v", requestSummary, err)
1803 }
1804
1805 doRequest := func() (*http.Request, *http.Response, error) {
1806 req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.url, bytes.NewReader(data))
1807 if err != nil {
1808 return nil, nil, err
1809 }
1810 req.Header.Set("Content-Type", "application/json")
1811 req.Header.Set("Accept", "application/json, text/event-stream")
1812 if err := c.setMCPHeaders(req); err != nil {
1813 // Failure to set headers means that the request was not sent.
1814 // Wrap with ErrRejected so the jsonrpc2 connection doesn't set writeErr
1815 // and permanently break the connection.
1816 return nil, nil, fmt.Errorf("%s: %w: %w", requestSummary, jsonrpc2.ErrRejected, err)
1817 }
1818 // Keep this after the setMCPHeaders call to ensure that the
1819 // protocol version header is set.
1820 setStandardHeaders(req.Header, msg)
1821 resp, err := c.client.Do(req)
1822 if err != nil {
1823 // Any error from client.Do means the request didn't reach the server.
1824 // Wrap with ErrRejected so the jsonrpc2 connection doesn't set writeErr
1825 // and permanently break the connection.
1826 err = fmt.Errorf("%s: %w: %w", requestSummary, jsonrpc2.ErrRejected, err)
1827 }
1828 return req, resp, err
1829 }
1830
1831 req, resp, err := doRequest()
1832 if err != nil {
1833 return err
1834 }
1835
1836 if (resp.StatusCode == http.StatusUnauthorized || resp.StatusCode == http.StatusForbidden) && c.oauthHandler != nil {
1837 if err := c.oauthHandler.Authorize(ctx, req, resp); err != nil {
1838 // If the caller's context was cancelled while we were running the

Callers

nothing calls this directly

Calls 14

failureMethod · 0.95
setMCPHeadersMethod · 0.95
failMethod · 0.95
checkResponseMethod · 0.95
handleJSONMethod · 0.95
handleSSEMethod · 0.95
EncodeMessageFunction · 0.92
setStandardHeadersFunction · 0.85
baseMediaTypeFunction · 0.85
IsCallMethod · 0.80
IsMethod · 0.80
AuthorizeMethod · 0.65

Tested by

no test coverage detected