An MCP server that provides tools to interact with Microsoft Teams data via JDBC connectivity, exposing tables, columns, and query execution capabilities.
Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
This is a data connector MCP server with 3 tools for querying Microsoft Teams data via SQL. Tool definitions are present with schemas and descriptions, but several quality gaps limit production readiness. Naming is clear and verb-based (get_*, run_*). Descriptions are adequate but generic, they explain WHAT the tools do but lack guidance on WHEN to use them or prerequisites. Parameter descriptions are minimal. Output schemas are not formally documented, responses are CSV strings without structured field definitions. Error handling is basic (RuntimeException with message). The server is STDIO-only, which is a hard architectural limitation for hosted MCP clients.
Tools (3)
teams_get_columnsread only50/100
Retrieves a list of fields, dimensions, or measures (as columns) for an object, entity or collection (table). Use the `teams_get_tables` tool to get a list of available tables. The output of the tool will be returned in CSV format, with the first line containing column headers.
teams_get_tablesread only50/100
Retrieves a list of objects, entities, collections, etc. (as tables) available in the data source. Use the `teams_get_columns` tool to list available columns on a table. Both `catalog` and `schema` are optional parameters. The output of the tool will be returned in CSV format, with the first line containing column headers.
Output schemas not documented. Tools return CSV strings, but LLMs have no formal specification of returned fields, data types, or structure. This forces the LLM to guess what columns are present and parse unstructured text, increasing error rates.
Parameter descriptions are generic or missing. 'catalog' is described as 'The catalog name', does it refer to a Teams workspace, organization, database catalog, or something else? 'schema' is similarly vague. Parameters lack examples, constraints, or guidance on when they are required vs optional.
teams_run_query description is too brief (51 chars: 'Execute a SQL SELECT statement.'). It lacks context on supported SQL dialects, which clauses are allowed, whether joins are safe, what happens on syntax errors, or when to use this vs the schema discovery tools. The description mentions SQL-92 dialect and valid clauses, but only in the parameter description, not the tool description itself.
Recommendations
Document the output schema for each tool as a JSON Schema. For teams_get_tables, specify: 'Returns CSV with columns: [TABLE_CAT (optional), TABLE_SCHEM (optional), TABLE_NAME (string), TABLE_TYPE (string), REMARKS (string)]'. For teams_get_columns: 'Returns CSV with columns: [TABLE_CAT (optional), TABLE_SCHEM (optional), TABLE_NAME (string), COLUMN_NAME (string), TYPE_NAME (string), REMARKS (string)]'. For teams_run_query: 'Returns CSV with columns determined by the SELECT statement; first row is headers; all data values are strings.' Structure this as formal JSON Schema in tool metadata, not just text.
Expand parameter descriptions. For 'catalog': 'The catalog name (optional; if omitted, uses default catalog). Example: "MyTeamsOrg". Typically a Teams organization or workspace identifier.' For 'schema': 'The schema name (optional; if omitted, uses default schema). Example: "dbo". Typically a logical grouping or database schema.' For 'table' in teams_get_columns: 'Required. The table name to inspect. Example: "Channels". Must be a valid table returned by teams_get_tables.'
Improve tool descriptions to guide LLM selection. teams_get_tables: 'Discover what tables are available in the Teams data source. Call this FIRST to see what data you can query. Returns a list of all tables with their types and remarks. Both catalog and schema are optional filters.' teams_get_columns: 'Inspect the structure of a specific table. Call this SECOND, after teams_get_tables, to see which columns you can filter and select. Returns column names, data types, and descriptions.' teams_run_query: 'Execute a SQL SELECT query to fetch data from Teams. Call this THIRD, after discovering tables and columns. Supports: FROM, INNER JOIN, LEFT JOIN, GROUP BY, ORDER BY, LIMIT/OFFSET. All queries must be SELECT only (no INSERT, UPDATE, DELETE). Identifiers must be quoted with double quotes (e.g., "Channels").'
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
No dependency hints. Descriptions should guide: 'Call teams_get_tables first to discover available tables, then teams_get_columns to see column names, then teams_run_query to fetch data.' The tooling chain is not documented.
Error handling is minimal. The only visible error response is RuntimeException thrown with a message. No guidance on retry strategies, no categorization of errors as retryable vs permanent, no recovery hints (e.g., 'If table not found, call teams_get_tables to verify the name').
No pagination or result limiting documented. If a table has 10,000 rows, teams_run_query will return all of them as CSV, which could exceed context windows and waste tokens. No LIMIT/OFFSET guidance in parameter descriptions.
Tool descriptions contain non-example implementation details ('CSV format, with the first line containing column headers') but lack high-level guidance on when to call each tool. No mention of which tool to call first or what the typical workflow is.
teams_get_tablesteams_get_columns
Add explicit error handling guidance: catch SQLException and return structured errors with recovery hints. E.g., 'Table "Channels" not found. Call teams_get_tables to see available tables.' or 'SQL syntax error: JOIN not supported on this table. Use INNER JOIN or LEFT JOIN instead.' or 'Query returned too many rows (10,000+). Add a LIMIT clause to reduce result size.'
Document pagination. Add to teams_run_query description: 'For large result sets, use LIMIT and OFFSET clauses. Example: SELECT * FROM Channels LIMIT 100 OFFSET 0 fetches the first 100 rows; change OFFSET to 100 for the next page. CSV output can be large, limit results to 100 - 500 rows per call.'
Add tool annotation hints. Mark teams_get_tables and teams_get_columns as readOnlyHint=true (safe to call repeatedly). Mark teams_run_query as readOnlyHint=true (SELECT only, no modifications). No tools are destructive, so destructiveHint is not needed.
Create a README or tool usage guide documenting the workflow: (1) Call teams_get_tables to discover table names. (2) Call teams_get_columns with the chosen table name. (3) Construct a SELECT query using the returned column names. (4) Call teams_run_query with the SQL. Example: teams_get_tables() → returns [Channels, Messages, Users] → teams_get_columns(table='Channels') → returns [TeamId, ChannelId, ChannelName, CreatedDate] → teams_run_query(sql='SELECT ChannelName, CreatedDate FROM Channels LIMIT 10').