Sample code for 30+ languages & platforms
SQL Server Requires Chilkat v11.6.0+

Non-Streaming End-to-End MCP Tool Use with an AI Model

See more AI Examples

Demonstrates Ai.UseMcp in a complete, non-streaming Model Context Protocol (MCP) workflow. The example connects to an MCP server, registers the server's tools with an AI model via UseMcp, and asks a question the model can only answer well by calling one of those tools. When the model requests a tool, Chilkat automatically calls it on the MCP server, feeds the result back into the conversation, and continues — all inside a single (non-streaming) Ask.

Tip: Code to parse the returned JSON can be generated with Chilkat's online tool at https://tools.chilkat.io/jsonParse.

Background. Automatic tool use requires a conversation (created with NewConvo); it cannot be used with a stateless query. Each registered tool name is namespaced with a prefix (here deepwiki) so tools from different servers cannot collide. The Mcp object must stay connected and in scope for as long as its tools are in use during the conversation. This example uses DeepWiki, a free, public, no-authentication Streamable HTTP MCP server; swap in any MCP server URL, setting AuthToken before Connect if a bearer token is required.
Using multiple MCP servers. More than one MCP server can be used in the same conversation. Connect each server and call UseMcp once per server — one call per MCP server — giving each a distinct prefix (for example deepwiki, weather, github) so tools from different servers never collide.

Chilkat SQL Server Downloads

SQL Server
--
CREATE PROCEDURE ChilkatSample
AS
BEGIN
    DECLARE @hr int
    DECLARE @sTmp0 nvarchar(4000)
    DECLARE @sTmp1 nvarchar(4000)
    DECLARE @success int
    SELECT @success = 0

    --  Non-streaming, end-to-end MCP example.  It connects to an MCP server, hands the server's tools to
    --  an AI model via Ai.UseMcp, and asks a question that the model can only answer by calling one of
    --  those tools.  When the model requests a tool, Chilkat automatically calls it on the MCP server,
    --  feeds the result back into the conversation, and continues -- all inside a single (non-streaming)
    --  Ask.
    --  
    --  The MCP server used here is DeepWiki: a free, public, no-authentication Streamable HTTP server
    --  that answers questions about public GitHub repositories.  Swap in any MCP server URL; if it
    --  requires a bearer token, set mcp.AuthToken before Connect.

    --  1) Connect to the MCP server.
    DECLARE @mcp int
    EXEC @hr = sp_OACreate 'Chilkat.Mcp', @mcp OUT
    IF @hr <> 0
    BEGIN
        PRINT 'Failed to create ActiveX component'
        RETURN
    END

    --  mcp.AuthToken = "...";   // <-- only if the server requires a bearer token
    EXEC sp_OAMethod @mcp, 'Connect', @success OUT, 'https://mcp.deepwiki.com/mcp'
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @mcp, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @mcp
        RETURN
      END


    EXEC sp_OAGetProperty @mcp, 'ServerName', @sTmp0 OUT

    EXEC sp_OAGetProperty @mcp, 'ServerVersion', @sTmp1 OUT

    PRINT 'Connected to MCP server: ' + @sTmp0 + ' (version ' + @sTmp1 + ')'

    --  (Optional) Show the tools the server advertises.  This is the same set of tools Chilkat registers
    --  with the model in the UseMcp call below.
    DECLARE @toolsJson int
    EXEC @hr = sp_OACreate 'Chilkat.JsonObject', @toolsJson OUT

    EXEC sp_OASetProperty @toolsJson, 'EmitCompact', 0
    EXEC sp_OAMethod @mcp, 'ListTools', @success OUT, @toolsJson
    IF @success = 1
      BEGIN

        PRINT 'Available MCP tools:'
        EXEC sp_OAMethod @toolsJson, 'Emit', @sTmp0 OUT
        PRINT @sTmp0

        PRINT '----'
      END

    --  2) Set up the AI conversation and register the MCP tools.
    DECLARE @ai int
    EXEC @hr = sp_OACreate 'Chilkat.Ai', @ai OUT

    EXEC sp_OASetProperty @ai, 'Provider', 'anthropic'
    --  The API key should come from a secure source rather than being hard-coded.
    EXEC sp_OASetProperty @ai, 'ApiKey', 'AI_PROVIDER_API_KEY'
    EXEC sp_OASetProperty @ai, 'Model', 'claude-sonnet-5'
    EXEC sp_OASetProperty @ai, 'VerboseLogging', 1

    --  Automatic tool use (MCP or JavaScript) requires a conversation -- it cannot be used with a
    --  stateless query, so create one with NewConvo.
    EXEC sp_OAMethod @ai, 'NewConvo', @success OUT, 'test_conversation', 'You are a helpful assistant.  Use the available tools when they can help answer the question.', ''
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @ai, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @mcp
        EXEC @hr = sp_OADestroy @toolsJson
        EXEC @hr = sp_OADestroy @ai
        RETURN
      END

    --  Register the connected server's tools with the model.  Each tool name is namespaced with the
    --  "deepwiki" prefix so that tools from different servers (and JavaScript tools) can never collide --
    --  e.g. "deepwiki_ask_question".  The Mcp object must stay connected and in scope for as long as its
    --  tools are in use during the conversation.
    EXEC sp_OAMethod @ai, 'UseMcp', @success OUT, @mcp, 'deepwiki'
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @ai, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @mcp
        EXEC @hr = sp_OADestroy @toolsJson
        EXEC @hr = sp_OADestroy @ai
        RETURN
      END

    --  Multiple MCP servers can be used in the same conversation.  Connect each server and call
    --  UseMcp once per server, giving each a distinct prefix so their tool names cannot collide.

    --  A prompt the model can only answer well by calling one of the MCP tools.
    EXEC sp_OAMethod @ai, 'InputAddText', @success OUT, 'Use the available tools to look up the GitHub repository "modelcontextprotocol/modelcontextprotocol", then give me a brief, sourced summary of which transports the Model Context Protocol defines.'
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @ai, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @mcp
        EXEC @hr = sp_OADestroy @toolsJson
        EXEC @hr = sp_OADestroy @ai
        RETURN
      END

    --  3) Non-streaming Ask.  Any MCP tool the model requests is executed automatically inside this call
    --  (Chilkat -> Mcp.CallTool -> result back into the transcript -> continue), so Ask returns only once
    --  the model produces its final answer.
    EXEC sp_OAMethod @ai, 'Ask', @success OUT, 'text'
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @ai, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @mcp
        EXEC @hr = sp_OADestroy @toolsJson
        EXEC @hr = sp_OADestroy @ai
        RETURN
      END

    --  The final assistant answer (after any automatic tool calls).
    DECLARE @sbResponse int
    EXEC @hr = sp_OACreate 'Chilkat.StringBuilder', @sbResponse OUT

    EXEC sp_OAMethod @ai, 'GetOutputTextSb', @success OUT, @sbResponse
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @ai, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @mcp
        EXEC @hr = sp_OADestroy @toolsJson
        EXEC @hr = sp_OADestroy @ai
        EXEC @hr = sp_OADestroy @sbResponse
        RETURN
      END

    PRINT 'Assistant answer:'
    EXEC sp_OAMethod @sbResponse, 'GetAsString', @sTmp0 OUT
    PRINT @sTmp0

    PRINT '----'

    --  (Optional) Dump the full transcript, which now includes the tool call and the tool result that
    --  were added automatically.
    DECLARE @convoJson int
    EXEC @hr = sp_OACreate 'Chilkat.JsonObject', @convoJson OUT

    EXEC sp_OASetProperty @convoJson, 'EmitCompact', 0
    EXEC sp_OAMethod @ai, 'ExportConvo', @success OUT, 'test_conversation', @convoJson
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @ai, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @mcp
        EXEC @hr = sp_OADestroy @toolsJson
        EXEC @hr = sp_OADestroy @ai
        EXEC @hr = sp_OADestroy @sbResponse
        EXEC @hr = sp_OADestroy @convoJson
        RETURN
      END

    PRINT 'Full Conversation:'
    EXEC sp_OAMethod @convoJson, 'Emit', @sTmp0 OUT
    PRINT @sTmp0

    --  4) Close the MCP session (best effort; releases the server-side session).
    EXEC sp_OAMethod @mcp, 'Close', @success OUT
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @mcp, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @mcp
        EXEC @hr = sp_OADestroy @toolsJson
        EXEC @hr = sp_OADestroy @ai
        EXEC @hr = sp_OADestroy @sbResponse
        EXEC @hr = sp_OADestroy @convoJson
        RETURN
      END

    EXEC @hr = sp_OADestroy @mcp
    EXEC @hr = sp_OADestroy @toolsJson
    EXEC @hr = sp_OADestroy @ai
    EXEC @hr = sp_OADestroy @sbResponse
    EXEC @hr = sp_OADestroy @convoJson


END
GO