Skip to main content
Glama

internal-ops-mcp

CI

MCP server that connects an agent to the internal support tools of Northline Goods, a fictional company. It exposes a local help center and a ticket queue stored in SQLite and seeded from fixtures/. The process does not use the network and does not need an API key.

NOTE

Northline Goods is fictional. This repository does not talk to a real help desk.

Maintainer: Mina Elzek · Built: January 2026

About

Server name

internal-ops

Entry point

python -m internal_ops_mcp

Transport

stdio

Store

SQLite. Default path data/ops.db. Override with OPS_DB_PATH.

Auth

Optional. When OPS_MCP_TOKEN is set, every tool call must pass that same value as access_token.

Python

3.11+

Seeding reads fixtures/docs/ and fixtures/tickets.json. Running it again does not duplicate rows.

Related MCP server: Zendesk MCP Server

Tools

Each tool returns a JSON string. A failure returns {"error": "..."} with a message the agent can act on. Stack traces are written to stderr, not returned to the caller.

Tool

Purpose

search_docs

Find help-center articles. Arguments: query, optional product (billing, accounts, shipping), optional limit (1–20, default 5). Each result has id, title, product, and snippet.

get_doc

Load one article by doc_id, including the full markdown body.

list_open_tickets

List tickets with status open. Optional priority (low, medium, high, critical) and limit. Each row has id, title, priority, status, and requester. Resolved and pending tickets are omitted.

get_ticket

Load one ticket by ticket_id, including description and last_note.

create_ticket

Insert a ticket with status open. Arguments: title, body, priority, requester_email. The email must look like name@domain.tld.

The resource ops://stats returns JSON with doc_count and open_ticket_count.

Every tool takes an optional access_token. If OPS_MCP_TOKEN is unset, local stdio calls are allowed without it. Set the variable before sharing the server. A missing or wrong token returns an error string and does not run the tool.

Getting started

Prerequisites

  • Python 3.11 or newer

  • An MCP client that can launch a stdio server

Install

python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements-dev.txt

On Windows PowerShell:

py -3 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements-dev.txt

requirements.txt is the runtime set (mcp 1.x and pydantic). requirements-dev.txt adds pytest.

Run

python -m internal_ops_mcp

The process speaks MCP over stdin and stdout. On startup it seeds the database. If OPS_MCP_TOKEN is missing it still starts, and it prints a stderr note telling you to set that variable before exposing the server.

Client configuration

Point the client at a checkout of this repository. Replace the paths below.

{
  "mcpServers": {
    "internal-ops": {
      "command": "python",
      "args": ["-m", "internal_ops_mcp"],
      "cwd": "/absolute/path/to/internal-ops-mcp"
    }
  }
}

Leave OPS_MCP_TOKEN unset for local use. To require a token, add it under env and pass that same value as access_token on every tool call. Do not commit a real token.

Tests

python -m pytest

Tests set OPS_DB_PATH to a temporary database. They do not read data/ops.db.

Project layout

internal_ops_mcp/    server, auth, and SQLite access
fixtures/docs/       help-center articles
fixtures/tickets.json
tests/               pytest

Contributing

See CONTRIBUTING.md. The Code of Conduct applies to this repository.

Security

See SECURITY.md.

License

MIT © 2026 Mina Elzek

Available Tools

5 tools
create_ticketB

Open a new ticket. The ticket is stored with status open.

NameRequiredDescriptionDefault
bodyYesWhat happened and what the agent already checked.
titleYesShort summary of the customer issue.
priorityYesTicket priority: low, medium, high, or critical.
access_tokenNoShared secret. Required only when OPS_MCP_TOKEN is set on the server. Omit it for local stdio when that variable is unset.
requester_emailYesEmail address of the person who asked for help.

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations supplied, the description carries the full burden of behavioral disclosure. The only fact offered — that the ticket is stored with status open — largely restates the verb 'Open' and says nothing about side effects such as whether the requester is notified, whether duplicates are rejected, or whether the call is idempotent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short, front-loaded sentences with no padding. The second sentence partially restates what 'Open a new ticket' already implies, so it is efficient but not entirely waste-free.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists and every parameter is documented in the schema, so return values and inputs are covered elsewhere. What is missing is context an agent would want for a mutation with no annotations: whether creating a ticket triggers notifications or requires a duplicate check.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including the conditional access_token requirement and the meaning of each field, so the schema already does the heavy lifting. The description adds no meaning beyond it, which is the baseline 3 case.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Open a new ticket'), which clearly marks this as the creation tool and separates it from list_open_tickets, get_ticket, search_docs, and get_doc. It does not explicitly name or contrast with any sibling, which keeps it just short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to create a ticket versus searching existing ones or reading a ticket first, and no mention of prerequisites such as duplicate checks or required requester context. The usage is only inferable from the verb itself.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_docA

Fetch one help-center article, including its full markdown body.

NameRequiredDescriptionDefault
doc_idYesArticle id returned by search_docs, such as refund-window.
access_tokenNoShared secret. Required only when OPS_MCP_TOKEN is set on the server. Omit it for local stdio when that variable is unset.

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and does disclose that the full markdown body is returned, useful for deciding whether fetching is worthwhile. It does not state that this is a read-only operation, that the id must come from search_docs (only the schema says that), or how missing articles behave.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence, front-loaded with the action and resource, with no redundant or filler wording. Nothing could be removed without losing information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-record read with a fully documented two-parameter schema and an output schema, the description covers what the tool returns. It could add a note on error behavior for unknown ids or a pointer to search_docs for id discovery, but the essential content is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are fully documented in the schema, including the doc_id origin and the conditional access_token. The description adds no parameter meaning beyond what the schema already provides, making 3 the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource ('Fetch one help-center article') and states the scope of the return ('full markdown body'), which clearly separates it from the sibling search_docs. It doesn't name search_docs explicitly, so it stops short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied: retrieve a single known article's full content, presumably after search_docs yields an id. There is no explicit when-to-use/when-not or named alternative, leaving the agent to infer the search-then-fetch pattern.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_ticketB

Fetch one ticket, including its description and latest note.

NameRequiredDescriptionDefault
ticket_idYesTicket id, such as TCK-1001.
access_tokenNoShared secret. Required only when OPS_MCP_TOKEN is set on the server. Omit it for local stdio when that variable is unset.

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. "Fetch" implies a read operation and the description discloses that the ticket description and latest note are included, but it does not state read-only semantics, authentication requirements, error behavior, or side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no wasted wording. It states the action, scope, and returned contents efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-ticket retrieval tool with a complete input schema and an output schema, the description is largely sufficient. It could be stronger by clarifying when to use this versus list_open_tickets or search_docs, but nothing critical for invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both ticket_id and access_token are already documented in the schema. The description adds no additional meaning about parameter formats or behavior beyond the schema, making baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ("Fetch") and resource ("one ticket") and states what is returned: description and latest note. It implicitly distinguishes from list_open_tickets and create_ticket by scope, but does not explicitly name sibling alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no when-to-use guidance or exclusions. It does not explain when to choose get_ticket over list_open_tickets, search_docs, or get_doc, leaving the agent to infer usage from the tool name and required ticket_id.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_open_ticketsA

List tickets that are still open. Resolved and pending tickets are omitted.

NameRequiredDescriptionDefault
limitNoMaximum number of open tickets to return, from 1 to 50.
priorityNoOptional priority filter: low, medium, high, or critical.
access_tokenNoShared secret. Required only when OPS_MCP_TOKEN is set on the server. Omit it for local stdio when that variable is unset.

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose the key behavioral trait: resolved and pending tickets are omitted from results. It says nothing about sort order, whether results are truncated by default, or the read-only/auth profile that the access_token parameter hints at.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with zero waste; the inclusion criterion is front-loaded and the exclusion clause immediately follows, which is exactly the order an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is a simple filtered list with an output schema present, full schema coverage on all three parameters, and the one non-obvious behavior (exclusion of resolved/pending) disclosed. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so limit, priority, and access_token are already fully explained including the 1-50 range and enum values. The description adds no filtering semantics beyond what the schema states, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and resource ('tickets') plus the scoping predicate ('still open'). An agent can distinguish it from get_ticket or create_ticket by the plural listing and the open-state filter, though siblings are never named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the caller learns it returns open tickets, but there is no guidance on when to prefer it over search_docs or get_ticket, and no mention of prerequisites or pagination strategy. Adequate but leaves selection to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_docsC

Search Northline help-center articles by keyword.

NameRequiredDescriptionDefault
limitNoMaximum number of articles to return, from 1 to 20.
queryYesWords to find in an article title or body.
productNoOptional product filter: billing, accounts, or shipping.
access_tokenNoShared secret. Required only when OPS_MCP_TOKEN is set on the server. Omit it for local stdio when that variable is unset.

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are supplied, so the description carries the full behavioral burden and discloses almost nothing: no note that it is a read-only operation, no mention of ranking behavior, no mention that a shared secret may be required. The authentication nuance for access_token lives only in the schema, not the description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler, appropriate for a four-parameter search tool. Its brevity is efficient, though it edges toward under-specification rather than tightness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the schema fully documents the parameters. However, for a tool with zero annotation coverage the description should still convey that this is a safe read and how it relates to get_doc, which it does not.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter including the product enum values and the token conditions is already documented in the schema. The description adds only the word 'keyword', which hints at title/body matching already spelled out in the query field description. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (search) and resource (Northline help-center articles) plus the matching mode (by keyword), which distinguishes it from get_doc, which fetches a single article. It stops short of explicitly naming that sibling or the ticket tools, so the differentiation is inferential rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to pick this over get_doc (keyword discovery vs. known-document retrieval) or over the ticket tools for support questions. The agent must infer the choice from the tool names alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.1.0
    • First observedcreate_ticket
    • First observedget_doc
    • First observedget_ticket
    • First observedlist_open_tickets
    • First observedsearch_docs

TDQS

A3.5/5.0

Scored across 5 tools

Disambiguation5/5

The tool set splits cleanly into two resource families (docs and tickets), and within each family the actions are distinct: search_docs searches while get_doc fetches a single article, and list_open_tickets lists while get_ticket and create_ticket operate on a single ticket. No two tools could reasonably be confused for one another.

Naming Consistency5/5

All five tools follow a strict snake_case verb_noun pattern (search_docs, get_doc, list_open_tickets, get_ticket, create_ticket), with verbs that accurately signal the operation. The only variance is the natural doc/docs singular-plural distinction, which is idiomatic rather than inconsistent.

Tool Count4/5

Five tools is on the lean side but every tool serves a distinct purpose and none is redundant. It is slightly thin for an 'internal-ops' surface that touches both documentation and ticketing, but well within a reasonable scope.

Completeness3/5

The ticket lifecycle is a dead end: tickets can be created and read, but there is no update, close, resolve, or comment/note operation, so an agent cannot act on the tickets it lists. The docs side is read-only, which is plausible for a help center but leaves no way to enumerate articles beyond keyword search.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers