Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,11 @@ These are high-level frameworks that make it easier to build MCP servers or clie

* **[codemirror-mcp](https://github.com/marimo-team/codemirror-mcp)** - CodeMirror extension that implements the Model Context Protocol (MCP) for resource mentions and prompt commands

## Tooling

* **[mcp-autotest](https://github.com/strowk/mcp-autotest)** - Autotest MCP servers in a language-agnostic way by **[strowk](https://github.com/strowk)**
* check example tests for [SQLite MCP Server](https://github.com/modelcontextprotocol/servers/tree/main/src/sqlite/testdata)

## 📚 Resources

Additional resources on MCP.
Expand Down
2 changes: 2 additions & 0 deletions src/sqlite/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# ignore database file created during tests
sqlite_mcp_server.db
16 changes: 16 additions & 0 deletions src/sqlite/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,22 @@ Docker:
docker build -t mcp/sqlite .
```

## Autotesting

If you have installed `uv` and `npx` (Node.js) installed, you can run tests like this:

```bash
npx mcp-autotest run testdata uv run mcp-server-sqlite
```

Repeating this run, would give you error `Database error: table t1 already exists`, because tests assume that database is cleared before running.
So if you want to repeat run:

```bash
rm sqlite_mcp_server.db ; npx mcp-autotest run testdata uv run mcp-server-sqlite
```


## License

This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
40 changes: 40 additions & 0 deletions src/sqlite/testdata/01_lifecycle_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
case: Initialize

# Client requesting initialization
in_request_to_initialize:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params":
{
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": { "name": "ExampleClient", "version": "1.0.0" },
},
}

# Server responding to initialization
out:
{
"id": 1,
"jsonrpc": "2.0",
"result":
{
"capabilities":
{
"experimental": {},
"prompts": { "listChanged": false },
"resources": { "listChanged": false, "subscribe": false },
"tools": { "listChanged": false },
},
"protocolVersion": "2024-11-05",
"serverInfo": { "name": "sqlite", "version": "0.1.0" },
},
}

---

# Finish initialization
in_finished:
{ "jsonrpc": "2.0", "method": "notifications/initialized", "params": {} }
137 changes: 137 additions & 0 deletions src/sqlite/testdata/02_list_tools_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
case: Initialize

# Client requesting initialization
in_request_to_initialize:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params":
{
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": { "name": "ExampleClient", "version": "1.0.0" },
},
}

# Server responding to initialization, ignore this, since we are not testing it
out: {}

---

case: Finish initialization

# Finish initialization
in_finished:
{ "jsonrpc": "2.0", "method": "notifications/initialized", "params": {} }

---

case: List tools

# Client requesting list of tools
in: { "jsonrpc": "2.0", "method": "tools/list", "params": {}, "id": 2 }

# Server responding with list of tools
out:
{
"jsonrpc": "2.0",
"id": 2,
"result":
{
"tools":
[
{
"name": "read_query",
"description": "Execute a SELECT query on the SQLite database",
"inputSchema":
{
"type": "object",
"properties":
{
"query":
{
"type": "string",
"description": "SELECT SQL query to execute",
},
},
"required": ["query"],
},
},
{
"name": "write_query",
"description": "Execute an INSERT, UPDATE, or DELETE query on the SQLite database",
"inputSchema":
{
"type": "object",
"properties":
{
"query":
{
"type": "string",
"description": "SQL query to execute",
},
},
"required": ["query"],
},
},
{
"name": "create_table",
"description": "Create a new table in the SQLite database",
"inputSchema":
{
"type": "object",
"properties":
{
"query":
{
"type": "string",
"description": "CREATE TABLE SQL statement",
},
},
"required": ["query"],
},
},
{
"name": "list_tables",
"description": "List all tables in the SQLite database",
"inputSchema": { "type": "object", "properties": {} },
},
{
"name": "describe_table",
"description": "Get the schema information for a specific table",
"inputSchema":
{
"type": "object",
"properties":
{
"table_name":
{
"type": "string",
"description": "Name of the table to describe",
},
},
"required": ["table_name"],
},
},
{
"name": "append_insight",
"description": "Add a business insight to the memo",
"inputSchema":
{
"type": "object",
"properties":
{
"insight":
{
"type": "string",
"description": "Business insight discovered from data analysis",
},
},
"required": ["insight"],
},
},
],
},
}

46 changes: 46 additions & 0 deletions src/sqlite/testdata/03_call_list_tables_tool_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
case: Initialize

# Client requesting initialization
in_request_to_initialize:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params":
{
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": { "name": "ExampleClient", "version": "1.0.0" },
},
}

# Server responding to initialization, ignore this, since we are not testing it
out: {}

---

case: Finish initialization

# Finish initialization
in_finished:
{ "jsonrpc": "2.0", "method": "notifications/initialized", "params": {} }

---

case: Call list_table tool

in:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": { "name": "list_tables", "args": {} },
"id": 2,
}

out:
{
"jsonrpc": "2.0",
"id": 2,
"result":
{ "content": [{ "type": "text", "text": "[]" }], "isError": false },
}
96 changes: 96 additions & 0 deletions src/sqlite/testdata/04_call_create_table_tool_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
case: Initialize

# Client requesting initialization
in_request_to_initialize:
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params":
{
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": { "name": "ExampleClient", "version": "1.0.0" },
},
}

# Server responding to initialization, ignore this, since we are not testing it
out: {}

---
case: Finish initialization

# Finish initialization
in_finished:
{ "jsonrpc": "2.0", "method": "notifications/initialized", "params": {} }

---
case: Fail calling create_table tool

in: { "jsonrpc": "2.0", "method": "tools/call", "params": {
"name": "create_table",
"arguments": {},
}, "id": 2 } # query argument is missing

out:
{
"id": 2,
"jsonrpc": "2.0",
"result":
{
"content": [{ "text": "Error: Missing arguments", "type": "text" }],
"isError": false,
},
}

---

case: Success call create_table tool

in:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params":
{
"name": "create_table",
"arguments": { "query": "CREATE TABLE t1(x INT CHECK( x>3 ))" },
},
"id": 2,
}

out:
{
"id": 2,
"jsonrpc": "2.0",
"result":
{
"content": [{ "text": "Table created successfully", "type": "text" }],
"isError": false,
},
}

---

# Now confirm that created table is visible for list_tables tool

case: Call list_table tool to confirm table creation

in:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": { "name": "list_tables", "args": {} },
"id": 2,
}

out:
{
"id": 2,
"jsonrpc": "2.0",
"result":
{
"content": [{ "text": "[{'name': 't1'}]", "type": "text" }],
"isError": false,
},
}